]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-150162: Fix sysconfig cross-compile impermanence (#150164)
authorhetmankp <728670+hetmankp@users.noreply.github.com>
Mon, 22 Jun 2026 15:59:03 +0000 (01:59 +1000)
committerGitHub <noreply@github.com>
Mon, 22 Jun 2026 15:59:03 +0000 (15:59 +0000)
Fixes issue #150162 by improving the code introduced by 70154855cf69
(GH-127729) while retaining the original documented intent. The
aforementioned code has a side effect when used in a virtual environment
context, on posix platforms, with the cross-compiling environment
variable _PYTHON_PROJECT_BASE present. In this case, every single
sysconfig.get_config_vars() and sysconfig.get_config_var() call, forces
the _CONFIG_VARS dictionary to be reinitialised from scratch. This is
inefficient, but also means no changes to the dictionary returned by
sysconfig.get_config_vars() persist, which can be useful in certain
situations.

This commit tracks changes to sys.prefix and sys.exec_prefix more
directly rather than relying on a misalignment with the corresponding
sysconfig variables.

Lib/sysconfig/__init__.py

index 719b306b02b6e385f3a707cd3f8fb1e165fe0944..fe55f48647e9a86850e403c77e58fc62936afc46 100644 (file)
@@ -182,6 +182,8 @@ _CONFIG_VARS_LOCK = threading.RLock()
 _CONFIG_VARS = None
 # True iff _CONFIG_VARS has been fully initialized.
 _CONFIG_VARS_INITIALIZED = False
+_config_vars_cached_prefix = None
+_config_vars_cached_exec_prefix = None
 _USER_BASE = None
 
 
@@ -600,16 +602,20 @@ def get_config_vars(*args):
     each argument in the configuration variable dictionary.
     """
     global _CONFIG_VARS_INITIALIZED
+    global _config_vars_cached_prefix
+    global _config_vars_cached_exec_prefix
 
     # Avoid claiming the lock once initialization is complete.
+    prefix = os.path.normpath(sys.prefix)
+    exec_prefix = os.path.normpath(sys.exec_prefix)
     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:
+        if _config_vars_cached_prefix != prefix or _config_vars_cached_exec_prefix != exec_prefix:
             with _CONFIG_VARS_LOCK:
                 _CONFIG_VARS_INITIALIZED = False
                 _init_config_vars()
+                _config_vars_cached_prefix = prefix
+                _config_vars_cached_exec_prefix = exec_prefix
     else:
         # Initialize the config_vars cache.
         with _CONFIG_VARS_LOCK:
@@ -619,6 +625,8 @@ def get_config_vars(*args):
             # don't re-enter init_config_vars().
             if _CONFIG_VARS is None:
                 _init_config_vars()
+            _config_vars_cached_prefix = prefix
+            _config_vars_cached_exec_prefix = exec_prefix
 
     if args:
         vals = []