From 834b7c18d74da3b30fdca66cc7da6b9e1db3ce6c Mon Sep 17 00:00:00 2001 From: Yilei Yang Date: Wed, 1 Nov 2023 14:11:18 -0700 Subject: [PATCH] gh-106718: Treat PyConfig.stdlib_dir as highest-priority setting for stdlib_dir when calculating paths (GH-108730) --- Lib/test/test_getpath.py | 14 +++++++++++ ...-08-31-11-42-16.gh-issue-106718._-57DA.rst | 2 ++ Modules/getpath.py | 24 +++++++++++-------- 3 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-08-31-11-42-16.gh-issue-106718._-57DA.rst diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py index b9cbe1d92c4..2f7aa69efc1 100644 --- a/Lib/test/test_getpath.py +++ b/Lib/test/test_getpath.py @@ -818,6 +818,20 @@ class MockGetPathTests(unittest.TestCase): actual = getpath(ns, expected) self.assertEqual(expected, actual) + def test_explicitly_set_stdlib_dir(self): + """Test the explicitly set stdlib_dir in the config is respected.""" + ns = MockPosixNamespace( + PREFIX="/usr", + argv0="python", + ENV_PATH="/usr/bin", + ) + ns["config"]["stdlib_dir"] = "/custom_stdlib_dir" + expected = dict( + stdlib_dir="/custom_stdlib_dir", + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + # ****************************************************************************** diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-31-11-42-16.gh-issue-106718._-57DA.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-31-11-42-16.gh-issue-106718._-57DA.rst new file mode 100644 index 00000000000..4c564bba412 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-08-31-11-42-16.gh-issue-106718._-57DA.rst @@ -0,0 +1,2 @@ +When PyConfig.stdlib_dir is explicitly set, it's now respected and won't be +overridden by PyConfig.home. diff --git a/Modules/getpath.py b/Modules/getpath.py index 4391a6194c7..1410ffdbed8 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -229,9 +229,10 @@ use_environment = config.get('use_environment', 1) pythonpath = config.get('module_search_paths') pythonpath_was_set = config.get('module_search_paths_set') +stdlib_dir = config.get('stdlib_dir') +stdlib_dir_was_set_in_config = bool(stdlib_dir) real_executable_dir = None -stdlib_dir = None platstdlib_dir = None # ****************************************************************************** @@ -507,11 +508,12 @@ if ((not home_was_set and real_executable_dir and not py_setpath) build_stdlib_prefix = build_prefix else: build_stdlib_prefix = search_up(build_prefix, *BUILDSTDLIB_LANDMARKS) - # Always use the build prefix for stdlib - if build_stdlib_prefix: - stdlib_dir = joinpath(build_stdlib_prefix, 'Lib') - else: - stdlib_dir = joinpath(build_prefix, 'Lib') + # Use the build prefix for stdlib when not explicitly set + if not stdlib_dir_was_set_in_config: + if build_stdlib_prefix: + stdlib_dir = joinpath(build_stdlib_prefix, 'Lib') + else: + stdlib_dir = joinpath(build_prefix, 'Lib') # Only use the build prefix for prefix if it hasn't already been set if not prefix: prefix = build_stdlib_prefix @@ -543,8 +545,9 @@ else: prefix, had_delim, exec_prefix = home.partition(DELIM) if not had_delim: exec_prefix = prefix - # Reset the standard library directory if it was already set - stdlib_dir = None + # Reset the standard library directory if it was not explicitly set + if not stdlib_dir_was_set_in_config: + stdlib_dir = None # First try to detect prefix by looking alongside our runtime library, if known @@ -560,7 +563,8 @@ else: if STDLIB_SUBDIR and STDLIB_LANDMARKS and not prefix: if any(isfile(joinpath(library_dir, f)) for f in STDLIB_LANDMARKS): prefix = library_dir - stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) + if not stdlib_dir_was_set_in_config: + stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) # Detect prefix by looking for zip file @@ -571,7 +575,7 @@ else: prefix = executable_dir else: prefix = search_up(executable_dir, ZIP_LANDMARK) - if prefix: + if prefix and not stdlib_dir_was_set_in_config: stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) if not isdir(stdlib_dir): stdlib_dir = None