[Python-checkins] gh-98790: When DLLs directory is missing on Windows, assume executable_dir contains PYD files instead (GH-98936)

zooba webhook-mailer at python.org
Wed Nov 2 14:38:46 EDT 2022


https://github.com/python/cpython/commit/3d889dc0a0efa6fcbd984ece365c9ac08d2cd4a9
commit: 3d889dc0a0efa6fcbd984ece365c9ac08d2cd4a9
branch: main
author: Steve Dower <steve.dower at python.org>
committer: zooba <steve.dower at microsoft.com>
date: 2022年11月02日T18:38:40Z
summary:
gh-98790: When DLLs directory is missing on Windows, assume executable_dir contains PYD files instead (GH-98936)
files:
A Misc/NEWS.d/next/Windows/2022-11-01-00-37-13.gh-issue-98790.fpaPAx.rst
M Lib/test/test_embed.py
M Lib/test/test_getpath.py
M Modules/getpath.py
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index f5cda1519b65..8c92f495d167 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -1492,17 +1492,11 @@ def test_init_pyvenv_cfg(self):
 if not MS_WINDOWS:
 paths[-1] = lib_dynload
 else:
- # Include DLLs directory as well
- paths.insert(1, '.\\DLLs')
- for index, path in enumerate(paths):
- if index == 0:
- # Because we copy the DLLs into tmpdir as well, the zip file
- # entry in sys.path will be there. For a regular venv, it will
- # usually be in the home directory.
- paths[index] = os.path.join(tmpdir, os.path.basename(path))
- else:
- paths[index] = os.path.join(pyvenv_home, os.path.basename(path))
- paths[-1] = pyvenv_home
+ paths = [
+ os.path.join(tmpdir, os.path.basename(paths[0])),
+ pyvenv_home,
+ os.path.join(pyvenv_home, "Lib"),
+ ]
 
 executable = self.test_exe
 base_executable = os.path.join(pyvenv_home, os.path.basename(executable))
@@ -1519,12 +1513,12 @@ def test_init_pyvenv_cfg(self):
 config['base_prefix'] = pyvenv_home
 config['prefix'] = pyvenv_home
 config['stdlib_dir'] = os.path.join(pyvenv_home, 'Lib')
- config['use_frozen_modules'] = not support.Py_DEBUG
+ config['use_frozen_modules'] = int(not support.Py_DEBUG)
 else:
 # cannot reliably assume stdlib_dir here because it
 # depends too much on our build. But it ought to be found
 config['stdlib_dir'] = self.IGNORE_CONFIG
- config['use_frozen_modules'] = not support.Py_DEBUG
+ config['use_frozen_modules'] = int(not support.Py_DEBUG)
 
 env = self.copy_paths_by_env(config)
 self.check_all_configs("test_init_compat_config", config,
diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py
index 1e46cb5780c9..12d52442c554 100644
--- a/Lib/test/test_getpath.py
+++ b/Lib/test/test_getpath.py
@@ -238,6 +238,29 @@ def test_buildtree_pythonhome_win32(self):
 actual = getpath(ns, expected)
 self.assertEqual(expected, actual)
 
+ def test_no_dlls_win32(self):
+ "Test a layout on Windows with no DLLs directory."
+ ns = MockNTNamespace(
+ argv0=r"C:\Python\python.exe",
+ real_executable=r"C:\Python\python.exe",
+ )
+ ns.add_known_xfile(r"C:\Python\python.exe")
+ ns.add_known_file(r"C:\Python\Lib\os.py")
+ expected = dict(
+ executable=r"C:\Python\python.exe",
+ base_executable=r"C:\Python\python.exe",
+ prefix=r"C:\Python",
+ exec_prefix=r"C:\Python",
+ module_search_paths_set=1,
+ module_search_paths=[
+ r"C:\Python\python98.zip",
+ r"C:\Python\Lib",
+ r"C:\Python",
+ ],
+ )
+ actual = getpath(ns, expected)
+ self.assertEqual(expected, actual)
+
 def test_normal_posix(self):
 "Test a 'standard' install layout on *nix"
 ns = MockPosixNamespace(
diff --git a/Misc/NEWS.d/next/Windows/2022-11-01-00-37-13.gh-issue-98790.fpaPAx.rst b/Misc/NEWS.d/next/Windows/2022-11-01-00-37-13.gh-issue-98790.fpaPAx.rst
new file mode 100644
index 000000000000..e8c5ac452858
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2022-11-01-00-37-13.gh-issue-98790.fpaPAx.rst
@@ -0,0 +1,2 @@
+Assumes that a missing ``DLLs`` directory means that standard extension
+modules are in the executable's directory.
diff --git a/Modules/getpath.py b/Modules/getpath.py
index e3558bc49e38..90a6473f1e6c 100644
--- a/Modules/getpath.py
+++ b/Modules/getpath.py
@@ -579,15 +579,28 @@ def search_up(prefix, *landmarks, test=isfile):
 # Detect exec_prefix by searching from executable for the platstdlib_dir
 if PLATSTDLIB_LANDMARK and not exec_prefix:
 if executable_dir:
- exec_prefix = search_up(executable_dir, PLATSTDLIB_LANDMARK, test=isdir)
- if not exec_prefix:
- if EXEC_PREFIX:
- exec_prefix = EXEC_PREFIX
- if not isdir(joinpath(exec_prefix, PLATSTDLIB_LANDMARK)):
- warn('Could not find platform dependent libraries <exec_prefix>')
+ if os_name == 'nt':
+ # QUIRK: For compatibility and security, do not search for DLLs
+ # directory. The fallback below will cover it
+ exec_prefix = executable_dir
+ else:
+ exec_prefix = search_up(executable_dir, PLATSTDLIB_LANDMARK, test=isdir)
+ if not exec_prefix and EXEC_PREFIX:
+ exec_prefix = EXEC_PREFIX
+ if not exec_prefix or not isdir(joinpath(exec_prefix, PLATSTDLIB_LANDMARK)):
+ if os_name == 'nt':
+ # QUIRK: If DLLs is missing on Windows, don't warn, just assume
+ # that it's all the same as prefix.
+ # gh-98790: We set platstdlib_dir here to avoid adding "DLLs" into
+ # sys.path when it doesn't exist, which would give site-packages
+ # precedence over executable_dir, which is *probably* where our PYDs
+ # live. Ideally, whoever changes our layout will tell us what the
+ # layout is, but in the past this worked, so it should keep working.
+ platstdlib_dir = exec_prefix = prefix
 else:
 warn('Could not find platform dependent libraries <exec_prefix>')
 
+
 # Fallback: assume exec_prefix == prefix
 if not exec_prefix:
 exec_prefix = prefix
@@ -689,7 +702,8 @@ def search_up(prefix, *landmarks, test=isfile):
 pythonpath.append(platstdlib_dir)
 if stdlib_dir:
 pythonpath.append(stdlib_dir)
- pythonpath.append(executable_dir)
+ if executable_dir not in pythonpath:
+ pythonpath.append(executable_dir)
 else:
 if stdlib_dir:
 pythonpath.append(stdlib_dir)


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /