Skip to content

Commit 72b28ca

Browse files
[3.13] pythongh-138432: Improved invalid path checking in zoneinfo.reset_tzpath() (pythonGH-138433) (pythonGH-138778)
* Improve error messages for path-like relative paths and path-like bytes paths. * TZPATH is now always a tuple of strings. (cherry picked from commit 859aecc) Co-authored-by: Stephen Morton <[email protected]>
1 parent afec6a5 commit 72b28ca

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

Lib/test/test_zoneinfo/test_zoneinfo.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from functools import cached_property
1919

2020
from test.support import MISSING_C_DOCSTRINGS, requires_gil_enabled
21+
from test.support.os_helper import FakePath
2122
from test.test_zoneinfo import _support as test_support
2223
from test.test_zoneinfo._support import OS_ENV_LOCK, TZPATH_TEST_LOCK, ZoneInfoTestBase
2324
from test.support.import_helper import import_module, CleanImport
@@ -1798,6 +1799,7 @@ def test_reset_tzpath_relative_paths(self):
17981799
("/usr/share/zoneinfo", "../relative/path",),
17991800
("path/to/somewhere", "../relative/path",),
18001801
("/usr/share/zoneinfo", "path/to/somewhere", "../relative/path",),
1802+
(FakePath("path/to/somewhere"),)
18011803
]
18021804
for input_paths in bad_values:
18031805
with self.subTest(input_paths=input_paths):
@@ -1809,6 +1811,9 @@ def test_tzpath_type_error(self):
18091811
"/etc/zoneinfo:/usr/share/zoneinfo",
18101812
b"/etc/zoneinfo:/usr/share/zoneinfo",
18111813
0,
1814+
(b"/bytes/path", "/valid/path"),
1815+
(FakePath(b"/bytes/path"),),
1816+
(0,),
18121817
]
18131818

18141819
for bad_value in bad_values:
@@ -1819,15 +1824,20 @@ def test_tzpath_type_error(self):
18191824
def test_tzpath_attribute(self):
18201825
tzpath_0 = [f"{DRIVE}/one", f"{DRIVE}/two"]
18211826
tzpath_1 = [f"{DRIVE}/three"]
1827+
tzpath_pathlike = (FakePath(f"{DRIVE}/usr/share/zoneinfo"),)
18221828

18231829
with self.tzpath_context(tzpath_0):
18241830
query_0 = self.module.TZPATH
18251831

18261832
with self.tzpath_context(tzpath_1):
18271833
query_1 = self.module.TZPATH
18281834

1835+
with self.tzpath_context(tzpath_pathlike):
1836+
query_pathlike = self.module.TZPATH
1837+
18291838
self.assertSequenceEqual(tzpath_0, query_0)
18301839
self.assertSequenceEqual(tzpath_1, query_1)
1840+
self.assertSequenceEqual(tuple([os.fspath(p) for p in tzpath_pathlike]), query_pathlike)
18311841

18321842

18331843
class CTzPathTest(TzPathTest):

Lib/zoneinfo/_tzpath.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ def _reset_tzpath(to=None, stacklevel=4):
1313
+ f"not {type(tzpaths)}: {tzpaths!r}"
1414
)
1515

16+
tzpaths = [os.fspath(p) for p in tzpaths]
17+
if not all(isinstance(p, str) for p in tzpaths):
18+
raise TypeError(
19+
"All elements of a tzpath sequence must be strings or "
20+
"os.PathLike objects which convert to strings."
21+
)
22+
1623
if not all(map(os.path.isabs, tzpaths)):
1724
raise ValueError(_get_invalid_paths_message(tzpaths))
1825
base_tzpath = tzpaths
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
:meth:`zoneinfo.reset_tzpath` will now convert any :class:`os.PathLike` objects
2+
it receives into strings before adding them to ``TZPATH``. It will raise
3+
``TypeError`` if anything other than a string is found after this conversion.
4+
If given an :class:`os.PathLike` object that represents a relative path, it
5+
will now raise ``ValueError`` instead of ``TypeError``, and present a more
6+
informative error message.

0 commit comments

Comments
 (0)