Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3110166

Browse files
committed
calculate zip path from prefix when in a venv
Before python3.11, when in a venv the zip path is calculatedfrom prefix. In python3.11 the behavior is accidentally changedto calculating from default prefix. This change will break venvcreated from a non-installed python with a stdlib zip file. Thiscommit restore the behavior back to before python3.11.
1 parent97c493d commit3110166

File tree

3 files changed

+97
-2
lines changed

3 files changed

+97
-2
lines changed

‎Lib/test/test_getpath.py‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,39 @@ def test_venv_changed_name_posix(self):
382382
actual=getpath(ns,expected)
383383
self.assertEqual(expected,actual)
384384

385+
deftest_venv_non_installed_zip_path_posix(self):
386+
"Test a venv created from non-installed python has correct zip path."""
387+
ns=MockPosixNamespace(
388+
argv0="/venv/bin/python",
389+
PREFIX="/usr",
390+
ENV_PATH="/venv/bin:/usr/bin",
391+
)
392+
ns.add_known_xfile("/path/to/non-installed/bin/python")
393+
ns.add_known_xfile("/venv/bin/python")
394+
ns.add_known_link("/venv/bin/python",
395+
"/path/to/non-installed/bin/python")
396+
ns.add_known_file("/path/to/non-installed/lib/python9.8/os.py")
397+
ns.add_known_dir("/path/to/non-installed/lib/python9.8/lib-dynload")
398+
ns.add_known_file("/venv/pyvenv.cfg", [
399+
r"home = /path/to/non-installed"
400+
])
401+
expected=dict(
402+
executable="/venv/bin/python",
403+
prefix="/path/to/non-installed",
404+
exec_prefix="/path/to/non-installed",
405+
base_executable="/path/to/non-installed/bin/python",
406+
base_prefix="/path/to/non-installed",
407+
base_exec_prefix="/path/to/non-installed",
408+
module_search_paths_set=1,
409+
module_search_paths=[
410+
"/path/to/non-installed/lib/python98.zip",
411+
"/path/to/non-installed/lib/python9.8",
412+
"/path/to/non-installed/lib/python9.8/lib-dynload",
413+
],
414+
)
415+
actual=getpath(ns,expected)
416+
self.assertEqual(expected,actual)
417+
385418
deftest_venv_changed_name_copy_posix(self):
386419
"Test a venv --copies layout on *nix that lacks a distributed 'python'"
387420
ns=MockPosixNamespace(

‎Lib/test/test_venv.py‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,69 @@ def test_pathsep_error(self):
537537
self.assertRaises(ValueError,venv.create,bad_itempath)
538538
self.assertRaises(ValueError,venv.create,pathlib.Path(bad_itempath))
539539

540+
@unittest.skipIf(os.name=='nt','not relevant on Windows')
541+
@requireVenvCreate
542+
deftest_zippath_from_non_installed_posix(self):
543+
"""
544+
Test that when create venv from non-installed python, the zip path
545+
value is as expected.
546+
"""
547+
rmtree(self.env_dir)
548+
# First try to create a non-installed python. It's not a real full
549+
# functional non-installed python, but enough for this test.
550+
non_installed_dir=os.path.realpath(tempfile.mkdtemp())
551+
try:
552+
bindir=os.path.join(non_installed_dir,self.bindir)
553+
os.mkdir(bindir)
554+
shutil.copy2(sys.executable,bindir)
555+
libdir=os.path.join(non_installed_dir,*self.lib)
556+
os.makedirs(libdir)
557+
landmark=os.path.join(libdir,"os.py")
558+
stdlib_zip="python%d%d.zip"%sys.version_info[:2]
559+
zip_landmark=os.path.join(non_installed_dir,
560+
self.lib[0],
561+
stdlib_zip)
562+
additional_pythonpath_for_non_installed= []
563+
# Copy stdlib files to the non-installed python so venv can
564+
# correctly calculate the prefix.
565+
foreachpathinsys.path:
566+
ifeachpath.endswith(".zip"):
567+
ifos.path.isfile(eachpath):
568+
shutil.copyfile(
569+
eachpath,
570+
os.path.join(non_installed_dir,self.lib[0]))
571+
elifos.path.isfile(os.path.join(eachpath,"os.py")):
572+
fornameinos.listdir(eachpath):
573+
ifname=="site-packages":
574+
continue
575+
fn=os.path.join(eachpath,name)
576+
ifos.path.isfile(fn):
577+
shutil.copy(fn,libdir)
578+
elifos.path.isdir(fn):
579+
shutil.copytree(fn,os.path.join(libdir,name))
580+
else:
581+
additional_pythonpath_for_non_installed.append(
582+
eachpath)
583+
cmd= [os.path.join(non_installed_dir,self.bindir,self.exe),
584+
"-m",
585+
"venv",
586+
"--without-pip",
587+
self.env_dir]
588+
# Our fake non-installed python is not fully functional because
589+
# it cannot find the extensions. Set PYTHONPATH so it can run the
590+
# venv module correctly.
591+
pythonpath=os.pathsep.join(
592+
additional_pythonpath_for_non_installed)
593+
subprocess.check_call(cmd,env={"PYTHONPATH":pythonpath})
594+
envpy=os.path.join(self.env_dir,self.bindir,self.exe)
595+
# Now check the venv created from the non-installed python has
596+
# correct zip path in pythonpath.
597+
cmd= [envpy,'-S','-c','import sys; print(sys.path)']
598+
out,err=check_output(cmd)
599+
self.assertTrue(zip_landmark.encode()inout)
600+
finally:
601+
rmtree(non_installed_dir)
602+
540603
@requireVenvCreate
541604
classEnsurePipTest(BaseTest):
542605
"""Test venv module installation of pip."""

‎Modules/getpath.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,9 +679,8 @@ def search_up(prefix, *landmarks, test=isfile):
679679
else:
680680
library_dir=executable_dir
681681
pythonpath.append(joinpath(library_dir,ZIP_LANDMARK))
682-
elifbuild_prefixorvenv_prefix:
682+
elifbuild_prefix:
683683
# QUIRK: POSIX uses the default prefix when in the build directory
684-
# or a venv
685684
pythonpath.append(joinpath(PREFIX,ZIP_LANDMARK))
686685
else:
687686
pythonpath.append(joinpath(prefix,ZIP_LANDMARK))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp