Skip to content

GH-126789: fix some sysconfig data on late site initializations #127729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions Lib/sysconfig/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,7 @@ def joinuser(*args):
_PY_VERSION = sys.version.split()[0]
_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}'
_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}'
_PREFIX = os.path.normpath(sys.prefix)
_BASE_PREFIX = os.path.normpath(sys.base_prefix)
_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
# Mutex guarding initialization of _CONFIG_VARS.
_CONFIG_VARS_LOCK = threading.RLock()
Expand Down Expand Up @@ -473,8 +471,8 @@ def _init_config_vars():
global _CONFIG_VARS
_CONFIG_VARS = {}

prefix = _PREFIX
exec_prefix = _EXEC_PREFIX
prefix = os.path.normpath(sys.prefix)
exec_prefix = os.path.normpath(sys.exec_prefix)
base_prefix = _BASE_PREFIX
base_exec_prefix = _BASE_EXEC_PREFIX

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

# Avoid claiming the lock once initialization is complete.
if not _CONFIG_VARS_INITIALIZED:
if _CONFIG_VARS_INITIALIZED:
# GH-126789: If sys.prefix or sys.exec_prefix were updated, invalidate the cache.
prefix = os.path.normpath(sys.prefix)
exec_prefix = os.path.normpath(sys.exec_prefix)
if _CONFIG_VARS['prefix'] != prefix or _CONFIG_VARS['exec_prefix'] != exec_prefix:
with _CONFIG_VARS_LOCK:
_CONFIG_VARS_INITIALIZED = False
_init_config_vars()
else:
# Initialize the config_vars cache.
with _CONFIG_VARS_LOCK:
# Test again with the lock held to avoid races. Note that
# we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED,
Expand Down
25 changes: 25 additions & 0 deletions Lib/test/test_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ def setUp(self):
os.uname = self._get_uname
# saving the environment
self.name = os.name
self.prefix = sys.prefix
self.exec_prefix = sys.exec_prefix
self.platform = sys.platform
self.version = sys.version
self._framework = sys._framework
Expand All @@ -77,6 +79,8 @@ def tearDown(self):
else:
del os.uname
os.name = self.name
sys.prefix = self.prefix
sys.exec_prefix = self.exec_prefix
sys.platform = self.platform
sys.version = self.version
sys._framework = self._framework
Expand Down Expand Up @@ -653,6 +657,27 @@ def test_sysconfigdata_json(self):

self.assertEqual(system_config_vars, json_config_vars)

def test_sysconfig_config_vars_no_prefix_cache(self):
sys.prefix = 'prefix-AAA'
sys.exec_prefix = 'exec-prefix-AAA'

config_vars = sysconfig.get_config_vars()

self.assertEqual(config_vars['prefix'], sys.prefix)
self.assertEqual(config_vars['base'], sys.prefix)
self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
self.assertEqual(config_vars['platbase'], sys.exec_prefix)

sys.prefix = 'prefix-BBB'
sys.exec_prefix = 'exec-prefix-BBB'

config_vars = sysconfig.get_config_vars()

self.assertEqual(config_vars['prefix'], sys.prefix)
self.assertEqual(config_vars['base'], sys.prefix)
self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
self.assertEqual(config_vars['platbase'], sys.exec_prefix)


class MakefileTests(unittest.TestCase):

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