import pytz
except ModuleNotFoundError:
pytz = None
+
+try:
import zoneinfo
+except ModuleNotFoundError:
+ zoneinfo = None
def _get_tzinfo(tzenv: str):
else:
try:
return zoneinfo.ZoneInfo(tzenv)
+ except ValueError as ve:
+ # This is somewhat hacky, but since _validate_tzfile_path() doesn't
+ # raise a specific error type, we'll need to check the message to be
+ # one we know to be from that function.
+ # If so, we pretend it meant that the TZ didn't exist, for the benefit
+ # of `babel.localtime` catching the `LookupError` raised by
+ # `_get_tzinfo_or_raise()`.
+ # See https://github.com/python-babel/babel/issues/1092
+ if str(ve).startswith("ZoneInfo keys "):
+ return None
except zoneinfo.ZoneInfoNotFoundError:
pass
--- /dev/null
+import sys
+
+import pytest
+
+from babel.localtime import _helpers, get_localzone
+
+
+@pytest.mark.skipif(
+ sys.platform == "win32",
+ reason="Issue 1092 is not applicable on Windows",
+)
+def test_issue_1092_without_pytz(monkeypatch):
+ pytest.importorskip("zoneinfo", reason="zoneinfo is not available")
+ monkeypatch.setenv("TZ", "/UTC") # Malformed timezone name.
+ # In case pytz _is_ also installed, we want to pretend it's not, so patch it out...
+ monkeypatch.setattr(_helpers, "pytz", None)
+ with pytest.raises(LookupError):
+ get_localzone()
+
+
+@pytest.mark.skipif(
+ sys.platform == "win32",
+ reason="Issue 1092 is not applicable on Windows",
+)
+def test_issue_1092_with_pytz(monkeypatch):
+ pytest.importorskip("pytz", reason="pytz is not installed")
+ monkeypatch.setenv("TZ", "/UTC") # Malformed timezone name.
+ with pytest.raises(LookupError):
+ get_localzone()