Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make python's argparse generate Non-English text?

The argparse module "automatically generates help and usage messages". I can give Non-English names to the arguments and provide Non-English help texts; but the help output then becomes a mixture of at least two languages, because terms like usage, positional arguments, optional arguments and show this help message and exit are automatically generated in English.

How can I replace this English output with translations?

Preferably, I would like to provide the translations within the script, so that the script generates the same output wherever it is started.

Edit: Based on the answer by Jon-Eric, here an example with his solution:

import gettext

def Übersetzung(Text):
    Text = Text.replace("usage", "Verwendung")
    Text = Text.replace("show this help message and exit",
                        "zeige diese Hilfe an und tue nichts weiteres")
    Text = Text.replace("error:", "Fehler:")
    Text = Text.replace("the following arguments are required:",
                        "Die folgenden Argumente müssen angegeben werden:")
    return Text
gettext.gettext = Übersetzung

import argparse

Parser = argparse.ArgumentParser()
Parser.add_argument("Eingabe")
Argumente = Parser.parse_args()

print(Argumente.Eingabe)

saved as Beispiel.py gives with python3 Beispiel.py -h the following help output:

Verwendung: Beispiel.py [-h] Eingabe

positional arguments:
  Eingabe

optional arguments:
  -h, --help  zeige diese Hilfe an und tue nichts weiteres
like image 269
Wolfram Avatar asked Apr 09 '14 01:04

Wolfram


People also ask

How do you add an optional argument in Argparse?

Optional Arguments To add an optional argument, simply omit the required parameter in add_argument() . args = parser. parse_args()if args.

What is Store_true in Python?

The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present. The source for this behavior is succinct and clear: http://hg.python.org/cpython/file/2.7/Lib/argparse.py#l861.

What is ArgumentParser in Python?

The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv .

How do I make Argparse argument optional in Python?

Python argparse optional argument The example adds one argument having two options: a short -o and a long --ouput . These are optional arguments. The module is imported. An argument is added with add_argument .


2 Answers

argparse uses the gettext API inspired by GNU gettext. You can use this API to integrate your translation of argparse in a relatively clean manner.

To do so, call the following code before argparse outputs any text (but possibly after import argparse):

import gettext

# Use values that suit your project instead of 'argparse' and 'path/to/locale'
gettext.bindtextdomain('argparse', 'path/to/locale')
gettext.textdomain('argparse')

In order for this solution to work, your translation of argparse must be located at path/to/locale/ll/LC_MESSAGES/argparse.mo where ll is the code of the current language (for example de; can be configured for example by setting the environment variable LANGUAGE).

How do you generate the .mo file?

  1. pygettext --default-domain=argparse /usr/local/lib/python3.5/argparse.py
    • Use the actual location of argparse.py
    • Creates the file argparse.pot
  2. cp argparse.pot argparse-ll.po
    • Use an actual language code instead of ll
  3. Fill in the missing translation strings in argparse-ll.po
  4. msgfmt argparse-ll.po -o locale/ll/LC_MESSAGES/argparse.mo

See gettext documentation for details about creating .mo file.

I have published these instructions in more detail in README.md of my Czech translation of argparse.

like image 63
Filip Bártek Avatar answered Oct 21 '22 14:10

Filip Bártek


Here is a Python module to translate all messages emitted by argparse. It is intended for a quick and dirty translation to only one other language (French in my case, but feel free to adjust that for your own language). For a more industrial multilingual approach, look at the excellent Filip Bartek solution.

"""
This module is like argparse but in french. 
Import it and use it like you would use argparse.

DIRECTIVES:
First copy-paste this code in a separate new file named french_argparse.py
Put this new file beside your main.py file in the same top project folder.
Then in the main.py file, import it like this:

>>> import french_argparse as argparse
"""

import gettext

#################################################################################################################
# The following translations are in French, but feel free to replace them with your own
# Many messages are even not translated, because they seems to be more intended for the programmer than the user.
# Phrases were extracted from the code at (https://github.com/python/cpython/blob/master/Lib/argparse.py)
# On October 2019
#################################################################################################################

__TRANSLATIONS = {
    'ambiguous option: %(option)s could match %(matches)s': 'option ambiguë: %(option)s parmi %(matches)s',
    'argument "-" with mode %r': 'argument "-" en mode %r',
    'cannot merge actions - two groups are named %r': 'cannot merge actions - two groups are named %r',
    "can't open '%(filename)s': %(error)s": "can't open '%(filename)s': %(error)s",
    'dest= is required for options like %r': 'dest= is required for options like %r',
    'expected at least one argument': 'au moins un argument est attendu',
    'expected at most one argument': 'au plus un argument est attendu',
    'expected one argument': 'un argument est nécessaire',
    'ignored explicit argument %r': 'ignored explicit argument %r',
    'invalid choice: %(value)r (choose from %(choices)s)': 'choix invalide: %(value)r (parmi %(choices)s)',
    'invalid conflict_resolution value: %r': 'invalid conflict_resolution value: %r',
    'invalid option string %(option)r: must start with a character %(prefix_chars)r':
        'invalid option string %(option)r: must start with a character %(prefix_chars)r',
    'invalid %(type)s value: %(value)r': 'valeur invalide de type %(type)s: %(value)r',
    'mutually exclusive arguments must be optional': 'mutually exclusive arguments must be optional',
    'not allowed with argument %s': "pas permis avec l'argument %s",
    'one of the arguments %s is required': 'au moins un argument requis parmi %s',
    'optional arguments': 'arguments optionnels',
    'positional arguments': 'arguments positionnels',
    "'required' is an invalid argument for positionals": "'required' is an invalid argument for positionals",
    'show this help message and exit': 'afficher ce message et quitter',
    'unrecognized arguments: %s': 'argument non reconnu: %s',
    'unknown parser %(parser_name)r (choices: %(choices)s)': 'unknown parser %(parser_name)r (choices: %(choices)s)',
    'usage: ': 'usage: ',
    '%(prog)s: error: %(message)s\n': '%(prog)s: erreur: %(message)s\n',
    '%r is not callable': '%r is not callable',
}


gettext.gettext = lambda text: __TRANSLATIONS[text] or text

##############################################################################
# Now import all argparse functionalities inside this module.
#
#   NB Many linters don't like the following line of code so we have disabled
#   warnings for pylint, flake8 and PyCharm
##############################################################################

# pylint: disable=all
# noinspection PyUnresolvedReferences
from argparse import *                  # noqa

like image 21
Frederic Avatar answered Oct 21 '22 14:10

Frederic