Skip to content

Commit b296541

Browse files
tungolmiss-islington
authored andcommitted
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. (cherry picked from commit 859aecc) Co-authored-by: Stephen Morton <[email protected]>
1 parent 3643a26 commit b296541

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

Lib/test/test_zoneinfo/test_zoneinfo.py

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

2020
from test.support import MISSING_C_DOCSTRINGS
21-
from test.support.os_helper import EnvironmentVarGuard
21+
from test.support.os_helper import EnvironmentVarGuard, FakePath
2222
from test.test_zoneinfo import _support as test_support
2323
from test.test_zoneinfo._support import TZPATH_TEST_LOCK, ZoneInfoTestBase
2424
from test.support.import_helper import import_module, CleanImport
@@ -1783,6 +1783,7 @@ def test_reset_tzpath_relative_paths(self):
17831783
("/usr/share/zoneinfo", "../relative/path",),
17841784
("path/to/somewhere", "../relative/path",),
17851785
("/usr/share/zoneinfo", "path/to/somewhere", "../relative/path",),
1786+
(FakePath("path/to/somewhere"),)
17861787
]
17871788
for input_paths in bad_values:
17881789
with self.subTest(input_paths=input_paths):
@@ -1794,6 +1795,9 @@ def test_tzpath_type_error(self):
17941795
"/etc/zoneinfo:/usr/share/zoneinfo",
17951796
b"/etc/zoneinfo:/usr/share/zoneinfo",
17961797
0,
1798+
(b"/bytes/path", "/valid/path"),
1799+
(FakePath(b"/bytes/path"),),
1800+
(0,),
17971801
]
17981802

17991803
for bad_value in bad_values:
@@ -1804,15 +1808,20 @@ def test_tzpath_type_error(self):
18041808
def test_tzpath_attribute(self):
18051809
tzpath_0 = [f"{DRIVE}/one", f"{DRIVE}/two"]
18061810
tzpath_1 = [f"{DRIVE}/three"]
1811+
tzpath_pathlike = (FakePath(f"{DRIVE}/usr/share/zoneinfo"),)
18071812

18081813
with self.tzpath_context(tzpath_0):
18091814
query_0 = self.module.TZPATH
18101815

18111816
with self.tzpath_context(tzpath_1):
18121817
query_1 = self.module.TZPATH
18131818

1819+
with self.tzpath_context(tzpath_pathlike):
1820+
query_pathlike = self.module.TZPATH
1821+
18141822
self.assertSequenceEqual(tzpath_0, query_0)
18151823
self.assertSequenceEqual(tzpath_1, query_1)
1824+
self.assertSequenceEqual(tuple([os.fspath(p) for p in tzpath_pathlike]), query_pathlike)
18161825

18171826

18181827
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)