https://github.com/python/cpython/commit/d7334e2c2012defaf7aae920d6a56689464509d1
commit: d7334e2c2012defaf7aae920d6a56689464509d1
branch: main
author: Nikita Sobolev <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-02-06T15:08:56+02:00
summary:
gh-106233: Fix stacklevel in zoneinfo.InvalidTZPathWarning (GH-106234)
files:
A Misc/NEWS.d/next/Library/2023-06-29-14-26-56.gh-issue-106233.Aqw2HI.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 18eab5b33540c9..8414721555731e 100644
--- a/Lib/test/test_zoneinfo/test_zoneinfo.py
+++ b/Lib/test/test_zoneinfo/test_zoneinfo.py
@@ -20,7 +20,7 @@
from test.support import MISSING_C_DOCSTRINGS
from test.test_zoneinfo import _support as test_support
from test.test_zoneinfo._support import OS_ENV_LOCK, TZPATH_TEST_LOCK,
ZoneInfoTestBase
-from test.support.import_helper import import_module
+from test.support.import_helper import import_module, CleanImport
lzma = import_module('lzma')
py_zoneinfo, c_zoneinfo = test_support.get_modules()
@@ -1720,13 +1720,26 @@ def test_env_variable_relative_paths(self):
with self.subTest("warning", path_var=path_var):
# Note: Per PEP 615 the warning is implementation-defined
# behavior, other implementations need not warn.
- with self.assertWarns(self.module.InvalidTZPathWarning):
+ with self.assertWarns(self.module.InvalidTZPathWarning) as
w:
self.module.reset_tzpath()
+ self.assertEqual(w.warnings[0].filename, __file__)
tzpath = self.module.TZPATH
with self.subTest("filtered", path_var=path_var):
self.assertSequenceEqual(tzpath, expected_paths)
+ def test_env_variable_relative_paths_warning_location(self):
+ path_var = "path/to/somewhere"
+
+ with self.python_tzpath_context(path_var):
+ with CleanImport("zoneinfo", "zoneinfo._tzpath"):
+ with self.assertWarns(RuntimeWarning) as w:
+ import zoneinfo
+ InvalidTZPathWarning = zoneinfo.InvalidTZPathWarning
+ self.assertIsInstance(w.warnings[0].message, InvalidTZPathWarning)
+ # It should represent the current file:
+ self.assertEqual(w.warnings[0].filename, __file__)
+
def test_reset_tzpath_kwarg(self):
self.module.reset_tzpath(to=[f"{DRIVE}/a/b/c"])
diff --git a/Lib/zoneinfo/_tzpath.py b/Lib/zoneinfo/_tzpath.py
index 4985dce2dc36d0..5db17bea045d8c 100644
--- a/Lib/zoneinfo/_tzpath.py
+++ b/Lib/zoneinfo/_tzpath.py
@@ -2,7 +2,7 @@
import sysconfig
-def reset_tzpath(to=None):
+def _reset_tzpath(to=None, stacklevel=4):
global TZPATH
tzpaths = to
@@ -18,17 +18,22 @@ def reset_tzpath(to=None):
base_tzpath = tzpaths
else:
env_var = os.environ.get("PYTHONTZPATH", None)
- if env_var is not None:
- base_tzpath = _parse_python_tzpath(env_var)
- else:
- base_tzpath = _parse_python_tzpath(
- sysconfig.get_config_var("TZPATH")
- )
+ if env_var is None:
+ env_var = sysconfig.get_config_var("TZPATH")
+ base_tzpath = _parse_python_tzpath(env_var, stacklevel)
TZPATH = tuple(base_tzpath)
-def _parse_python_tzpath(env_var):
+def reset_tzpath(to=None):
+ """Reset global TZPATH."""
+ # We need `_reset_tzpath` helper function because it produces a warning,
+ # it is used as both a module-level call and a public API.
+ # This is how we equalize the stacklevel for both calls.
+ _reset_tzpath(to)
+
+
+def _parse_python_tzpath(env_var, stacklevel):
if not env_var:
return ()
@@ -45,6 +50,7 @@ def _parse_python_tzpath(env_var):
"Invalid paths specified in PYTHONTZPATH environment variable. "
+ msg,
InvalidTZPathWarning,
+ stacklevel=stacklevel,
)
return new_tzpath
@@ -172,4 +178,4 @@ class InvalidTZPathWarning(RuntimeWarning):
TZPATH = ()
-reset_tzpath()
+_reset_tzpath(stacklevel=5)
diff --git
a/Misc/NEWS.d/next/Library/2023-06-29-14-26-56.gh-issue-106233.Aqw2HI.rst
b/Misc/NEWS.d/next/Library/2023-06-29-14-26-56.gh-issue-106233.Aqw2HI.rst
new file mode 100644
index 00000000000000..345c8b20815c95
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-29-14-26-56.gh-issue-106233.Aqw2HI.rst
@@ -0,0 +1,2 @@
+Fix stacklevel in ``InvalidTZPathWarning`` during :mod:`zoneinfo` module
+import.
_______________________________________________
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]