else:
pos = link_dst.find('/zoneinfo/')
if pos >= 0:
- zone_name = link_dst[pos + 10:]
+ # On occasion, the `/etc/localtime` symlink has a double slash, e.g.
+ # "/usr/share/zoneinfo//UTC", which would make `zoneinfo.ZoneInfo`
+ # complain (no absolute paths allowed), and we'd end up returning
+ # `None` (as a fix for #1092).
+ # Instead, let's just "fix" the double slash symlink by stripping
+ # leading slashes before passing the assumed zone name forward.
+ zone_name = link_dst[pos + 10:].lstrip("/")
tzinfo = _get_tzinfo(zone_name)
if tzinfo is not None:
return tzinfo
+import os
import sys
+from unittest.mock import Mock
import pytest
monkeypatch.setenv("TZ", "/UTC") # Malformed timezone name.
with pytest.raises(LookupError):
get_localzone()
+
+
+@pytest.mark.skipif(
+ sys.platform == "win32",
+ reason="Issue 990 is not applicable on Windows",
+)
+def test_issue_990(monkeypatch):
+ monkeypatch.setenv("TZ", "")
+ fake_readlink = Mock(return_value="/usr/share/zoneinfo////UTC") # Double slash, oops!
+ monkeypatch.setattr(os, "readlink", fake_readlink)
+ from babel.localtime._unix import _get_localzone
+ assert _get_localzone() is not None
+ fake_readlink.assert_called_with("/etc/localtime")