Skip to content

Commit 7015485

Browse files
authored
GH-126789: fix some sysconfig data on late site initializations (#127729)
1 parent 79b7cab commit 7015485

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

Lib/sysconfig/__init__.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,7 @@ def joinuser(*args):
173173
_PY_VERSION = sys.version.split()[0]
174174
_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}'
175175
_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}'
176-
_PREFIX = os.path.normpath(sys.prefix)
177176
_BASE_PREFIX = os.path.normpath(sys.base_prefix)
178-
_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
179177
_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
180178
# Mutex guarding initialization of _CONFIG_VARS.
181179
_CONFIG_VARS_LOCK = threading.RLock()
@@ -473,8 +471,8 @@ def _init_config_vars():
473471
global _CONFIG_VARS
474472
_CONFIG_VARS = {}
475473

476-
prefix = _PREFIX
477-
exec_prefix = _EXEC_PREFIX
474+
prefix = os.path.normpath(sys.prefix)
475+
exec_prefix = os.path.normpath(sys.exec_prefix)
478476
base_prefix = _BASE_PREFIX
479477
base_exec_prefix = _BASE_EXEC_PREFIX
480478

@@ -564,9 +562,19 @@ def get_config_vars(*args):
564562
With arguments, return a list of values that result from looking up
565563
each argument in the configuration variable dictionary.
566564
"""
565+
global _CONFIG_VARS_INITIALIZED
567566

568567
# Avoid claiming the lock once initialization is complete.
569-
if not _CONFIG_VARS_INITIALIZED:
568+
if _CONFIG_VARS_INITIALIZED:
569+
# GH-126789: If sys.prefix or sys.exec_prefix were updated, invalidate the cache.
570+
prefix = os.path.normpath(sys.prefix)
571+
exec_prefix = os.path.normpath(sys.exec_prefix)
572+
if _CONFIG_VARS['prefix'] != prefix or _CONFIG_VARS['exec_prefix'] != exec_prefix:
573+
with _CONFIG_VARS_LOCK:
574+
_CONFIG_VARS_INITIALIZED = False
575+
_init_config_vars()
576+
else:
577+
# Initialize the config_vars cache.
570578
with _CONFIG_VARS_LOCK:
571579
# Test again with the lock held to avoid races. Note that
572580
# we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED,

Lib/test/test_sysconfig.py

+25
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ def setUp(self):
5353
os.uname = self._get_uname
5454
# saving the environment
5555
self.name = os.name
56+
self.prefix = sys.prefix
57+
self.exec_prefix = sys.exec_prefix
5658
self.platform = sys.platform
5759
self.version = sys.version
5860
self._framework = sys._framework
@@ -77,6 +79,8 @@ def tearDown(self):
7779
else:
7880
del os.uname
7981
os.name = self.name
82+
sys.prefix = self.prefix
83+
sys.exec_prefix = self.exec_prefix
8084
sys.platform = self.platform
8185
sys.version = self.version
8286
sys._framework = self._framework
@@ -653,6 +657,27 @@ def test_sysconfigdata_json(self):
653657

654658
self.assertEqual(system_config_vars, json_config_vars)
655659

660+
def test_sysconfig_config_vars_no_prefix_cache(self):
661+
sys.prefix = 'prefix-AAA'
662+
sys.exec_prefix = 'exec-prefix-AAA'
663+
664+
config_vars = sysconfig.get_config_vars()
665+
666+
self.assertEqual(config_vars['prefix'], sys.prefix)
667+
self.assertEqual(config_vars['base'], sys.prefix)
668+
self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
669+
self.assertEqual(config_vars['platbase'], sys.exec_prefix)
670+
671+
sys.prefix = 'prefix-BBB'
672+
sys.exec_prefix = 'exec-prefix-BBB'
673+
674+
config_vars = sysconfig.get_config_vars()
675+
676+
self.assertEqual(config_vars['prefix'], sys.prefix)
677+
self.assertEqual(config_vars['base'], sys.prefix)
678+
self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
679+
self.assertEqual(config_vars['platbase'], sys.exec_prefix)
680+
656681

657682
class MakefileTests(unittest.TestCase):
658683

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fixed :func:`sysconfig.get_config_vars`, :func:`sysconfig.get_paths`, and
2+
siblings, returning outdated cached data if the value of :data:`sys.prefix`
3+
or :data:`sys.exec_prefix` changes. Overwriting :data:`sys.prefix` or
4+
:data:`sys.exec_prefix` still is discouraged, as that might break other
5+
parts of the code.

0 commit comments

Comments
 (0)