fix(i18n): translate parser diagnostics and validation errors, disable abbreviations

This commit is contained in:
criss717 2026-08-30 18:16:30 +02:00
parent 5feda55c74
commit caa88ca186
4 changed files with 57 additions and 4 deletions

View file

@ -32,6 +32,12 @@ _ARGPARSE_MESSAGE_KEYS: dict[str, str] = {
"%(prog)s: error: %(message)s\n": "cli.argparse_error",
"unrecognized arguments: %s": "cli.argparse_unrecognized",
"the following arguments are required: %s": "cli.argparse_required",
"invalid choice: %(value)r (choose from %(choices)s)": "cli.argparse_invalid_choice",
"argument %(argument_name)s: %(message)s": "cli.argparse_argument_error",
"expected one argument": "cli.argparse_expected_one",
"expected at most one argument": "cli.argparse_expected_at_most",
"expected at least one argument": "cli.argparse_expected_at_least",
"unexpected option string: %s": "cli.argparse_unexpected_option",
}
@ -89,11 +95,11 @@ def _positive_budget(value: str) -> float:
try:
budget = float(value)
except ValueError as exc:
raise argparse.ArgumentTypeError(f"invalid float value: {value!r}") from exc
raise argparse.ArgumentTypeError(t("cli.invalid_float", value=value)) from exc
import math
if not math.isfinite(budget) or budget <= 0:
raise argparse.ArgumentTypeError("must be a finite number greater than 0")
raise argparse.ArgumentTypeError(t("cli.finite_number"))
return budget
@ -101,9 +107,9 @@ def _positive_int(value: str) -> int:
try:
parsed = int(value)
except ValueError as exc:
raise argparse.ArgumentTypeError(f"invalid int value: {value!r}") from exc
raise argparse.ArgumentTypeError(t("cli.invalid_int", value=value)) from exc
if parsed <= 0:
raise argparse.ArgumentTypeError("must be an integer greater than 0")
raise argparse.ArgumentTypeError(t("cli.positive_integer"))
return parsed
@ -114,6 +120,7 @@ def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=t("cli.description"),
formatter_class=argparse.RawDescriptionHelpFormatter,
allow_abbrev=False,
epilog=f"""
{t("cli.examples_header")}
# {t("cli.example_web_app")}

View file

@ -22,6 +22,16 @@
"cli.argparse_error": "%(prog)s: error: %(message)s\n",
"cli.argparse_unrecognized": "unrecognized arguments: %s",
"cli.argparse_required": "the following arguments are required: %s",
"cli.argparse_invalid_choice": "invalid choice: %(value)r (choose from %(choices)s)",
"cli.argparse_argument_error": "argument %(argument_name)s: %(message)s",
"cli.argparse_expected_one": "expected one argument",
"cli.argparse_expected_at_most": "expected at most one argument",
"cli.argparse_expected_at_least": "expected at least one argument",
"cli.argparse_unexpected_option": "unexpected option string: %s",
"cli.invalid_float": "invalid float value: {value!r}",
"cli.finite_number": "must be a finite number greater than 0",
"cli.invalid_int": "invalid int value: {value!r}",
"cli.positive_integer": "must be an integer greater than 0",
"cli.example_web_app": "Web application penetration test",
"cli.example_github": "GitHub repository analysis",
"cli.example_local_code": "Local code analysis",

View file

@ -22,6 +22,16 @@
"cli.argparse_error": "%(prog)s: error: %(message)s\n",
"cli.argparse_unrecognized": "argumentos no reconocidos: %s",
"cli.argparse_required": "se requieren los siguientes argumentos: %s",
"cli.argparse_invalid_choice": "opción inválida: %(value)r (elija entre %(choices)s)",
"cli.argparse_argument_error": "argumento %(argument_name)s: %(message)s",
"cli.argparse_expected_one": "se espera un argumento",
"cli.argparse_expected_at_most": "se espera como máximo un argumento",
"cli.argparse_expected_at_least": "se espera al menos un argumento",
"cli.argparse_unexpected_option": "opción inesperada: %s",
"cli.invalid_float": "valor float inválido: {value!r}",
"cli.finite_number": "debe ser un número finito mayor que 0",
"cli.invalid_int": "valor entero inválido: {value!r}",
"cli.positive_integer": "debe ser un entero mayor que 0",
"cli.example_web_app": "Prueba de penetración de aplicación web",
"cli.example_github": "Análisis de repositorio de GitHub",
"cli.example_local_code": "Análisis de código local",

View file

@ -346,6 +346,32 @@ class TestArgparseBuiltins:
assert cli_args._translate_argparse("unknown string") == "unknown string"
assert argparse._("usage: ") == "uso: "
def test_invalid_choice_translates(self):
set_language("es")
assert "inválida" in t("cli.argparse_invalid_choice")
assert "elija entre" in t("cli.argparse_invalid_choice")
def test_argument_error_translates(self):
set_language("es")
assert t("cli.argparse_argument_error") == "argumento %(argument_name)s: %(message)s"
def test_expected_arguments_translate(self):
set_language("es")
assert t("cli.argparse_expected_one") == "se espera un argumento"
assert "como máximo" in t("cli.argparse_expected_at_most")
assert "al menos" in t("cli.argparse_expected_at_least")
def test_unexpected_option_translates(self):
set_language("es")
assert t("cli.argparse_unexpected_option") == "opción inesperada: %s"
def test_validation_errors_translate(self):
set_language("es")
assert t("cli.invalid_float", value="abc") == "valor float inválido: 'abc'"
assert t("cli.invalid_int", value="abc") == "valor entero inválido: 'abc'"
assert t("cli.finite_number") == "debe ser un número finito mayor que 0"
assert t("cli.positive_integer") == "debe ser un entero mayor que 0"
class TestSettingsLanguageField:
def test_settings_has_language_field(self):