@@ -537,6 +537,69 @@ def test_pathsep_error(self):
537
537
self .assertRaises (ValueError , venv .create , bad_itempath )
538
538
self .assertRaises (ValueError , venv .create , pathlib .Path (bad_itempath ))
539
539
540
+ @requireVenvCreate
541
+ def test_zippath_from_non_installed (self ):
542
+ """
543
+ Test that when create venv from non-installed python, the zip path
544
+ value is as expected.
545
+ """
546
+ rmtree (self .env_dir )
547
+ # First try to create a non-installed python by using venv. It's not a
548
+ # real full functional non-installed python, but enough for this test.
549
+ non_installed_dir = os .path .realpath (tempfile .mkdtemp ())
550
+ builder = venv .EnvBuilder (symlinks = False )
551
+ builder .create (non_installed_dir )
552
+ try :
553
+ # Remove pyvenv.cfg to fake a non-installed python.
554
+ os .unlink (os .path .join (non_installed_dir , "pyvenv.cfg" ))
555
+ libdir = os .path .join (non_installed_dir , * self .lib )
556
+ landmark = os .path .join (libdir , "os.py" )
557
+ stdlib_zip = "python%d%d.zip" % sys .version_info [:2 ]
558
+ zip_landmark = os .path .join (non_installed_dir ,
559
+ self .lib [0 ],
560
+ stdlib_zip )
561
+ additional_pythonpath_for_non_installed = []
562
+ # Copy stdlib files to the non-installed python so venv can
563
+ # correctly calculate the prefix.
564
+ if not (os .path .isfile (landmark ) or os .path .isfile (zip_landmark )):
565
+ for eachpath in sys .path :
566
+ if eachpath .endswith (".zip" ):
567
+ if os .path .isfile (eachpath ):
568
+ shutil .copyfile (
569
+ eachpath ,
570
+ os .path .join (non_installed_dir , self .lib [0 ]))
571
+ elif os .path .isfile (os .path .join (eachpath , "os.py" )):
572
+ for name in os .listdir (eachpath ):
573
+ if name == "site-packages" :
574
+ continue
575
+ fn = os .path .join (eachpath , name )
576
+ if os .path .isfile (fn ):
577
+ shutil .copy (fn , libdir )
578
+ elif os .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 , '-c' , 'import sys; print(sys.path)' ]
598
+ out , err = check_output (cmd )
599
+ self .assertTrue (zip_landmark .encode () in out )
600
+ finally :
601
+ rmtree (non_installed_dir )
602
+
540
603
@requireVenvCreate
541
604
class EnsurePipTest (BaseTest ):
542
605
"""Test venv module installation of pip."""
0 commit comments