From 917e9d9e47db376d00659dc29520eccab468da25 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sat, 5 Oct 2024 00:51:42 -0400 Subject: [PATCH] fix: setuptools-less installs couldn't translate, add test (#373) * Adding translate test * fix: fix tests Signed-off-by: Henry Schreiner * tests: skip if locale not available Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner --- .github/workflows/ci.yml | 4 +++ plumbum/cli/i18n.py | 15 ++++++---- tests/test_translate.py | 61 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 tests/test_translate.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fff293f2..ce1c043e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,10 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true + - name: Add locale for locale test + if: runner.os == 'Linux' && matrix.python-version != '3.10' + run: sudo locale-gen fr_FR.UTF-8 + - name: Setup uv (cached) uses: hynek/setup-cached-uv@v2 diff --git a/plumbum/cli/i18n.py b/plumbum/cli/i18n.py index 1921fe5b..57294f5f 100644 --- a/plumbum/cli/i18n.py +++ b/plumbum/cli/i18n.py @@ -1,6 +1,9 @@ from __future__ import annotations import locale +import os + +DIR = os.path.abspath(os.path.dirname(__file__)) # High performance method for English (no translation needed) loc = locale.getlocale()[0] @@ -23,7 +26,6 @@ def get_translation_for( else: import gettext - import os # If not installed with setuptools, this might not be available try: @@ -31,25 +33,26 @@ def get_translation_for( except ImportError: pkg_resources = None # type: ignore[assignment] - local_dir = os.path.basename(__file__) - def get_translation_for(package_name: str) -> gettext.NullTranslations: # type: ignore[misc] """Find and return gettext translation for package (Try to find folder manually if setuptools does not exist) """ + assert loc is not None if "." in package_name: package_name = ".".join(package_name.split(".")[:-1]) localedir = None if pkg_resources is None: - mydir = os.path.join(local_dir, "i18n") + mydir = os.path.join(DIR, "i18n") else: mydir = pkg_resources.resource_filename(package_name, "i18n") for localedir in mydir, None: - localefile = gettext.find(package_name, localedir) + localefile = gettext.find(package_name, localedir, languages=[loc]) if localefile: break - return gettext.translation(package_name, localedir=localedir, fallback=True) + return gettext.translation( + package_name, localedir=localedir, languages=[loc], fallback=True + ) diff --git a/tests/test_translate.py b/tests/test_translate.py new file mode 100644 index 00000000..305cba3a --- /dev/null +++ b/tests/test_translate.py @@ -0,0 +1,61 @@ +# Setting French as system language +from __future__ import annotations + +import importlib +import locale + +import pytest + +import plumbum.cli +import plumbum.cli.i18n + + +def reload_cli(): + importlib.reload(plumbum.cli.i18n) + importlib.reload(plumbum.cli.switches) + importlib.reload(plumbum.cli.application) + importlib.reload(plumbum.cli) + + +@pytest.fixture() +def french(): + try: + locale.setlocale(locale.LC_ALL, "fr_FR.utf-8") + reload_cli() + yield + except locale.Error: + pytest.skip( + "No fr_FR locale found, run 'sudo locale-gen fr_FR.UTF-8' to run this test" + ) + finally: + locale.setlocale(locale.LC_ALL, "") + reload_cli() + + +@pytest.mark.usefixtures("french") +def test_nolang_switches(): + class Simple(plumbum.cli.Application): + foo = plumbum.cli.SwitchAttr("--foo") + + def main(self): + pass + + _, rc = Simple.run(["foo", "-h"], exit=False) + assert rc == 0 + _, rc = Simple.run(["foo", "--version"], exit=False) + assert rc == 0 + + +@pytest.mark.usefixtures("french") +def test_help_lang(capsys): + class Simple(plumbum.cli.Application): + foo = plumbum.cli.SwitchAttr("--foo") + + def main(self): + pass + + _, rc = Simple.run(["foo", "-h"], exit=False) + assert rc == 0 + stdout, stderr = capsys.readouterr() + assert "Utilisation" in stdout + assert "Imprime ce message d'aide et sort" in stdout