diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py index b9cbe1d92c436f..2f7aa69efc184a 100644 --- a/Lib/test/test_getpath.py +++ b/Lib/test/test_getpath.py @@ -818,6 +818,20 @@ def test_symlink_buildpath_macos(self): 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 00000000000000..4c564bba4122c9 --- /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 4391a6194c7e58..1410ffdbed8c70 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -229,9 +229,10 @@ def search_up(prefix, *landmarks, test=isfile): 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 @@ def search_up(prefix, *landmarks, test=isfile): 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 @@ def search_up(prefix, *landmarks, test=isfile): 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 @@ def search_up(prefix, *landmarks, test=isfile): 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 @@ def search_up(prefix, *landmarks, test=isfile): 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