Skip to content

Commit

Permalink
gh-106718: Treat PyConfig.stdlib_dir as highest-priority setting for …
Browse files Browse the repository at this point in the history
…stdlib_dir when calculating paths (GH-108730)
  • Loading branch information
yilei committed Nov 1, 2023
1 parent 821a7ac commit 834b7c1
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
14 changes: 14 additions & 0 deletions Lib/test/test_getpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


# ******************************************************************************

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
When PyConfig.stdlib_dir is explicitly set, it's now respected and won't be
overridden by PyConfig.home.
24 changes: 14 additions & 10 deletions Modules/getpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

# ******************************************************************************
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 834b7c1

Please sign in to comment.