gh-106233: Fix stacklevel in zoneinfo.InvalidTZPathWarning (GH-106234)

This commit is contained in:
Nikita Sobolev 2024-02-06 16:08:56 +03:00 committed by GitHub
parent 1a10437a14
commit d7334e2c20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 11 deletions

View File

@ -20,7 +20,7 @@ from functools import cached_property
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 @@ class TzPathTest(TzPathUserMixin, ZoneInfoTestBase):
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"])

View File

@ -2,7 +2,7 @@ import os
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)

View File

@ -0,0 +1,2 @@
Fix stacklevel in ``InvalidTZPathWarning`` during :mod:`zoneinfo` module
import.