Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/pendulum/tz/local_timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@ def _get_unix_timezone(_root: str = "/") -> Timezone:
tzpath = Path(_root) / filename
if tzpath.is_file():
with tzpath.open("rb") as f:
return Timezone.from_file(f)
tz = Timezone.from_file(f)
if tz.key is not None:
return tz

warnings.warn(
"Unable not find any timezone configuration, defaulting to UTC.", stacklevel=1
Expand All @@ -231,7 +233,7 @@ def _tz_from_env(tzenv: str) -> Timezone:
# TZ specifies a file
if os.path.isfile(tzenv):
with open(tzenv, "rb") as f:
return Timezone.from_file(f)
return Timezone.from_file(f, key=tzenv)

# TZ specifies a zoneinfo zone.
try:
Expand Down
24 changes: 24 additions & 0 deletions tests/tz/test_local_timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,27 @@ def test_unix_etc_timezone_dir():
tz = _get_unix_timezone(_root=root_path)

assert tz.name == "Europe/Paris"


@pytest.mark.skipif(
sys.platform == "win32", reason="Test only available for UNIX systems"
)
def test_unix_localtime_regular_file_defaults_to_utc():
# /etc/localtime as a bare copy of a zoneinfo file (no IANA key), as
# found in minimal containers / Slurm jobs, used to yield a Timezone
# with key=None, which crashed the Rust helpers (#989). It must now
# fall through to the UTC default with a named key.
import shutil
import tempfile

local_path = os.path.join(os.path.split(__file__)[0], "..")
root_path = tempfile.mkdtemp()
os.makedirs(os.path.join(root_path, "etc"), exist_ok=True)
shutil.copy(
os.path.join(local_path, "fixtures", "tz", "Paris"),
os.path.join(root_path, "etc", "localtime"),
)
tz = _get_unix_timezone(_root=root_path)

assert tz.key is not None
assert tz.name == "UTC"
5 changes: 4 additions & 1 deletion tests/tz/test_timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,10 @@ def _paris_tzif_bytes() -> bytes:


def test_from_file_without_a_key_can_be_pickled():
# get_local_timezone()'s last-resort fallback builds a Timezone this same way, with no key.
# Timezone.from_file without a key yields a keyless Timezone (key is
# None); this is still supported for pickling / utcoffset (#989). The
# local-timezone resolver no longer returns such a value, defaulting
# to UTC instead (see test_unix_localtime_regular_file_defaults_to_utc).
from io import BytesIO

import pendulum.tz.timezone as timezone_module
Expand Down