diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index ec3b638f007..67a071963d8 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -353,7 +353,8 @@ def _init_posix(vars): else: _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) build_time_vars = _temp.build_time_vars - vars.update(build_time_vars) + # GH-126920: Make sure we don't overwrite any of the keys already set + vars.update(build_time_vars | vars) def _init_non_posix(vars): """Initialize the module as appropriate for NT""" diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 4f9541b6a0b..c7acfe728bb 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -656,6 +656,38 @@ def test_paths_depend_on_site_initialization(self): self.assertNotEqual(site_paths, no_site_paths) + @unittest.skipIf(sys.platform == 'wasi', 'venv is unsupported on WASI') + def test_makefile_overwrites_config_vars(self): + script = textwrap.dedent(""" + import sys, sysconfig + + data = { + 'prefix': sys.prefix, + 'exec_prefix': sys.exec_prefix, + 'base_prefix': sys.base_prefix, + 'base_exec_prefix': sys.base_exec_prefix, + 'config_vars': sysconfig.get_config_vars(), + } + + import json + print(json.dumps(data, indent=2)) + """) + + # We need to run the test inside a virtual environment so that + # sys.prefix/sys.exec_prefix have a different value from the + # prefix/exec_prefix Makefile variables. + with self.venv() as venv: + data = json.loads(venv.run('-c', script).stdout) + + # We expect sysconfig.get_config_vars to correctly reflect sys.prefix/sys.exec_prefix + self.assertEqual(data['prefix'], data['config_vars']['prefix']) + self.assertEqual(data['exec_prefix'], data['config_vars']['exec_prefix']) + # As a sanity check, just make sure sys.prefix/sys.exec_prefix really + # are different from the Makefile values. + # sys.base_prefix/sys.base_exec_prefix should reflect the value of the + # prefix/exec_prefix Makefile variables, so we use them in the comparison. + self.assertNotEqual(data['prefix'], data['base_prefix']) + self.assertNotEqual(data['exec_prefix'], data['base_exec_prefix']) class MakefileTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2024-11-17-01-14-59.gh-issue-126920.s8-f_L.rst b/Misc/NEWS.d/next/Library/2024-11-17-01-14-59.gh-issue-126920.s8-f_L.rst new file mode 100644 index 00000000000..6966aec380f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-17-01-14-59.gh-issue-126920.s8-f_L.rst @@ -0,0 +1,5 @@ +Fix the ``prefix`` and ``exec_prefix`` keys from +:py:func:`sysconfig.get_config_vars` incorrectly having the same value as +:py:const:`sys.base_prefix` and :py:const:`sys.base_exec_prefix`, +respectively, inside virtual environments. They now accurately reflect +:py:const:`sys.prefix` and :py:const:`sys.exec_prefix`.