Fall back to non-localized message on Windows

Windows does not implement LC_MESSAGES, and since PEP 668 is mainly
designed for Linux distributions, we simply take the easier way out
until someone wants an equivalent on Windows.
This commit is contained in:
Tzu-ping Chung 2023-01-03 07:44:22 +08:00
parent 6750d847a7
commit 8fe6563050
2 changed files with 71 additions and 3 deletions

View File

@ -703,7 +703,17 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
@staticmethod
def _iter_externally_managed_error_keys() -> Iterator[str]:
lang, _ = locale.getlocale(locale.LC_MESSAGES)
# LC_MESSAGES is in POSIX, but not the C standard. The most common
# platform that does not implement this category is Windows, where
# using other categories for console message localization is equally
# unreliable, so we fall back to the locale-less vendor message. This
# can always be re-evaluated when a vendor proposes a new alternative.
try:
category = locale.LC_MESSAGES
except AttributeError:
lang: Optional[str] = None
else:
lang, _ = locale.getlocale(category)
if lang is not None:
yield f"Error-{lang}"
for sep in ("-", "_"):

View File

@ -492,9 +492,9 @@ class TestExternallyManagedEnvironment:
orig_getlocal = locale.getlocale
def fake_getlocale(category: int) -> Tuple[Optional[str], Optional[str]]:
"""Fake getlocale() that always report zh_Hant."""
"""Fake getlocale() that always reports zh_Hant for LC_MESSASGES."""
result = orig_getlocal(category)
if category == locale.LC_MESSAGES:
if category == getattr(locale, "LC_MESSAGES", None):
return "zh_Hant", result[1]
return result
@ -541,6 +541,10 @@ class TestExternallyManagedEnvironment:
assert not caplog.records
assert str(exc.context) == self.default_text
@pytest.mark.skipif(
sys.platform == "win32",
reason="Localization disabled on Windows",
)
@pytest.mark.parametrize(
"config, expected",
[
@ -594,3 +598,57 @@ class TestExternallyManagedEnvironment:
exc = ExternallyManagedEnvironment.from_config(marker)
assert not caplog.records
assert str(exc.context) == expected
@pytest.mark.skipif(
sys.platform != "win32",
reason="Non-Windows should implement localization",
)
@pytest.mark.parametrize(
"config",
[
pytest.param(
"""\
[externally-managed]
Error = 最後
Error-en = English
Error-zh = 中文
Error-zh_Hant = 繁體
Error-zh_Hans = 简体
""",
id="full",
),
pytest.param(
"""\
[externally-managed]
Error = 最後
Error-en = English
Error-zh = 中文
Error-zh_Hans = 简体
""",
id="no-variant",
),
pytest.param(
"""\
[externally-managed]
Error = 最後
Error-en = English
""",
id="fallback",
),
],
)
def test_config_canonical_no_localization(
self,
caplog: pytest.LogCaptureFixture,
marker: pathlib.Path,
config: str,
) -> None:
marker.write_text(
textwrap.dedent(config),
encoding="utf8",
)
with caplog.at_level(logging.WARNING, "pip._internal.exceptions"):
exc = ExternallyManagedEnvironment.from_config(marker)
assert not caplog.records
assert str(exc.context) == "最後"