https://github.com/python/cpython/commit/859aecc33b82f45e5b7ae30138d28f2a2f33a575
commit: 859aecc33b82f45e5b7ae30138d28f2a2f33a575
branch: main
author: Stephen Morton <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-09-11T10:08:53+03:00
summary:
gh-138432: Improved invalid path checking in zoneinfo.reset_tzpath() (GH-138433)
* Improve error messages for path-like relative paths and path-like bytes paths.
* TZPATH is now always a tuple of strings.
files:
A Misc/NEWS.d/next/Library/2025-09-03-15-20-10.gh-issue-138432.RMc7UX.rst
M Lib/test/test_zoneinfo/test_zoneinfo.py
M Lib/zoneinfo/_tzpath.py
diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py
b/Lib/test/test_zoneinfo/test_zoneinfo.py
index addc905af5ede9..2f9a5dfc1a89a0 100644
--- a/Lib/test/test_zoneinfo/test_zoneinfo.py
+++ b/Lib/test/test_zoneinfo/test_zoneinfo.py
@@ -18,7 +18,7 @@
from functools import cached_property
from test.support import MISSING_C_DOCSTRINGS
-from test.support.os_helper import EnvironmentVarGuard
+from test.support.os_helper import EnvironmentVarGuard, FakePath
from test.test_zoneinfo import _support as test_support
from test.test_zoneinfo._support import TZPATH_TEST_LOCK, ZoneInfoTestBase
from test.support.import_helper import import_module, CleanImport
@@ -1784,6 +1784,7 @@ def test_reset_tzpath_relative_paths(self):
("/usr/share/zoneinfo", "../relative/path",),
("path/to/somewhere", "../relative/path",),
("/usr/share/zoneinfo", "path/to/somewhere", "../relative/path",),
+ (FakePath("path/to/somewhere"),)
]
for input_paths in bad_values:
with self.subTest(input_paths=input_paths):
@@ -1795,6 +1796,9 @@ def test_tzpath_type_error(self):
"/etc/zoneinfo:/usr/share/zoneinfo",
b"/etc/zoneinfo:/usr/share/zoneinfo",
0,
+ (b"/bytes/path", "/valid/path"),
+ (FakePath(b"/bytes/path"),),
+ (0,),
]
for bad_value in bad_values:
@@ -1805,6 +1809,7 @@ def test_tzpath_type_error(self):
def test_tzpath_attribute(self):
tzpath_0 = [f"{DRIVE}/one", f"{DRIVE}/two"]
tzpath_1 = [f"{DRIVE}/three"]
+ tzpath_pathlike = (FakePath(f"{DRIVE}/usr/share/zoneinfo"),)
with self.tzpath_context(tzpath_0):
query_0 = self.module.TZPATH
@@ -1812,8 +1817,12 @@ def test_tzpath_attribute(self):
with self.tzpath_context(tzpath_1):
query_1 = self.module.TZPATH
+ with self.tzpath_context(tzpath_pathlike):
+ query_pathlike = self.module.TZPATH
+
self.assertSequenceEqual(tzpath_0, query_0)
self.assertSequenceEqual(tzpath_1, query_1)
+ self.assertSequenceEqual(tuple([os.fspath(p) for p in
tzpath_pathlike]), query_pathlike)
class CTzPathTest(TzPathTest):
diff --git a/Lib/zoneinfo/_tzpath.py b/Lib/zoneinfo/_tzpath.py
index 78fa6f00a8590a..177d32c35eff29 100644
--- a/Lib/zoneinfo/_tzpath.py
+++ b/Lib/zoneinfo/_tzpath.py
@@ -13,6 +13,13 @@ def _reset_tzpath(to=None, stacklevel=4):
+ f"not {type(tzpaths)}: {tzpaths!r}"
)
+ tzpaths = [os.fspath(p) for p in tzpaths]
+ if not all(isinstance(p, str) for p in tzpaths):
+ raise TypeError(
+ "All elements of a tzpath sequence must be strings or "
+ "os.PathLike objects which convert to strings."
+ )
+
if not all(map(os.path.isabs, tzpaths)):
raise ValueError(_get_invalid_paths_message(tzpaths))
base_tzpath = tzpaths
diff --git
a/Misc/NEWS.d/next/Library/2025-09-03-15-20-10.gh-issue-138432.RMc7UX.rst
b/Misc/NEWS.d/next/Library/2025-09-03-15-20-10.gh-issue-138432.RMc7UX.rst
new file mode 100644
index 00000000000000..b48b978a6d5c75
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-09-03-15-20-10.gh-issue-138432.RMc7UX.rst
@@ -0,0 +1,6 @@
+:meth:`zoneinfo.reset_tzpath` will now convert any :class:`os.PathLike` objects
+it receives into strings before adding them to ``TZPATH``. It will raise
+``TypeError`` if anything other than a string is found after this conversion.
+If given an :class:`os.PathLike` object that represents a relative path, it
+will now raise ``ValueError`` instead of ``TypeError``, and present a more
+informative error message.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]