From 70828999ccebfec167444a4812c137210bc7c49e Mon Sep 17 00:00:00 2001 From: Kai Zhang Date: Mon, 14 Nov 2022 16:03:07 +0000 Subject: [PATCH 1/3] Fix test_zippath_from_non_installed_posix When build with shared enabled, we need to set `LD_LIBRARY_PATH` for the non-installed python environment in test_zippath_from_non_installed_posix so that the python binary and find and link the libpython.so. --- Lib/test/test_venv.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 3e306d39febf9d..95be6a0c6d7ad7 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -590,7 +590,17 @@ def test_zippath_from_non_installed_posix(self): # venv module correctly. pythonpath = os.pathsep.join( additional_pythonpath_for_non_installed) - subprocess.check_call(cmd, env={"PYTHONPATH": pythonpath}) + # For python built with shared enabled. We need to set + # LD_LIBRARY_PATH so the non-installed python can find and link + # libpython.so + ld_library_path = os.path.abspath(os.path.dirname(sys.executable)) + if sys.platform == 'darwin': + ld_library_path_env = "DYLD_LIBRARY_PATH" + else: + ld_library_path_env = "LD_LIBRARY_PATH" + subprocess.check_call(cmd, + env={"PYTHONPATH": pythonpath, + ld_library_path_env: ld_library_path}) envpy = os.path.join(self.env_dir, self.bindir, self.exe) # Now check the venv created from the non-installed python has # correct zip path in pythonpath. From 3266ff9eb57bab67c337a8c4651224ba8fd200d6 Mon Sep 17 00:00:00 2001 From: Kai Zhang Date: Mon, 14 Nov 2022 17:52:01 +0000 Subject: [PATCH 2/3] Use sys.platlibdir to create lib directory Python can be built with platlibdir configured to "lib64". Use sys.platlibdir instead of "lib" in test_zippath_from_non_installed_posix. --- Lib/test/test_venv.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 95be6a0c6d7ad7..7483c53d26d937 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -547,17 +547,18 @@ def test_zippath_from_non_installed_posix(self): rmtree(self.env_dir) # First try to create a non-installed python. It's not a real full # functional non-installed python, but enough for this test. + platlibdir = sys.platlibdir non_installed_dir = os.path.realpath(tempfile.mkdtemp()) try: bindir = os.path.join(non_installed_dir, self.bindir) os.mkdir(bindir) shutil.copy2(sys.executable, bindir) - libdir = os.path.join(non_installed_dir, *self.lib) + libdir = os.path.join(non_installed_dir, platlibdir, self.lib[1]) os.makedirs(libdir) landmark = os.path.join(libdir, "os.py") stdlib_zip = "python%d%d.zip" % sys.version_info[:2] zip_landmark = os.path.join(non_installed_dir, - self.lib[0], + platlibdir, stdlib_zip) additional_pythonpath_for_non_installed = [] # Copy stdlib files to the non-installed python so venv can @@ -567,7 +568,7 @@ def test_zippath_from_non_installed_posix(self): if os.path.isfile(eachpath): shutil.copyfile( eachpath, - os.path.join(non_installed_dir, self.lib[0])) + os.path.join(non_installed_dir, platlibdir)) elif os.path.isfile(os.path.join(eachpath, "os.py")): for name in os.listdir(eachpath): if name == "site-packages": From de73f73ef7aa4d546b412e32b937dab4324590d5 Mon Sep 17 00:00:00 2001 From: Kai Zhang Date: Mon, 14 Nov 2022 17:56:38 +0000 Subject: [PATCH 3/3] Replace enormous try block with self.addCleanup --- Lib/test/test_venv.py | 118 +++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 7483c53d26d937..c685a6554cfc70 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -549,67 +549,65 @@ def test_zippath_from_non_installed_posix(self): # functional non-installed python, but enough for this test. platlibdir = sys.platlibdir non_installed_dir = os.path.realpath(tempfile.mkdtemp()) - try: - bindir = os.path.join(non_installed_dir, self.bindir) - os.mkdir(bindir) - shutil.copy2(sys.executable, bindir) - libdir = os.path.join(non_installed_dir, platlibdir, self.lib[1]) - os.makedirs(libdir) - landmark = os.path.join(libdir, "os.py") - stdlib_zip = "python%d%d.zip" % sys.version_info[:2] - zip_landmark = os.path.join(non_installed_dir, - platlibdir, - stdlib_zip) - additional_pythonpath_for_non_installed = [] - # Copy stdlib files to the non-installed python so venv can - # correctly calculate the prefix. - for eachpath in sys.path: - if eachpath.endswith(".zip"): - if os.path.isfile(eachpath): - shutil.copyfile( - eachpath, - os.path.join(non_installed_dir, platlibdir)) - elif os.path.isfile(os.path.join(eachpath, "os.py")): - for name in os.listdir(eachpath): - if name == "site-packages": - continue - fn = os.path.join(eachpath, name) - if os.path.isfile(fn): - shutil.copy(fn, libdir) - elif os.path.isdir(fn): - shutil.copytree(fn, os.path.join(libdir, name)) - else: - additional_pythonpath_for_non_installed.append( - eachpath) - cmd = [os.path.join(non_installed_dir, self.bindir, self.exe), - "-m", - "venv", - "--without-pip", - self.env_dir] - # Our fake non-installed python is not fully functional because - # it cannot find the extensions. Set PYTHONPATH so it can run the - # venv module correctly. - pythonpath = os.pathsep.join( - additional_pythonpath_for_non_installed) - # For python built with shared enabled. We need to set - # LD_LIBRARY_PATH so the non-installed python can find and link - # libpython.so - ld_library_path = os.path.abspath(os.path.dirname(sys.executable)) - if sys.platform == 'darwin': - ld_library_path_env = "DYLD_LIBRARY_PATH" + self.addCleanup(rmtree, non_installed_dir) + bindir = os.path.join(non_installed_dir, self.bindir) + os.mkdir(bindir) + shutil.copy2(sys.executable, bindir) + libdir = os.path.join(non_installed_dir, platlibdir, self.lib[1]) + os.makedirs(libdir) + landmark = os.path.join(libdir, "os.py") + stdlib_zip = "python%d%d.zip" % sys.version_info[:2] + zip_landmark = os.path.join(non_installed_dir, + platlibdir, + stdlib_zip) + additional_pythonpath_for_non_installed = [] + # Copy stdlib files to the non-installed python so venv can + # correctly calculate the prefix. + for eachpath in sys.path: + if eachpath.endswith(".zip"): + if os.path.isfile(eachpath): + shutil.copyfile( + eachpath, + os.path.join(non_installed_dir, platlibdir)) + elif os.path.isfile(os.path.join(eachpath, "os.py")): + for name in os.listdir(eachpath): + if name == "site-packages": + continue + fn = os.path.join(eachpath, name) + if os.path.isfile(fn): + shutil.copy(fn, libdir) + elif os.path.isdir(fn): + shutil.copytree(fn, os.path.join(libdir, name)) else: - ld_library_path_env = "LD_LIBRARY_PATH" - subprocess.check_call(cmd, - env={"PYTHONPATH": pythonpath, - ld_library_path_env: ld_library_path}) - envpy = os.path.join(self.env_dir, self.bindir, self.exe) - # Now check the venv created from the non-installed python has - # correct zip path in pythonpath. - cmd = [envpy, '-S', '-c', 'import sys; print(sys.path)'] - out, err = check_output(cmd) - self.assertTrue(zip_landmark.encode() in out) - finally: - rmtree(non_installed_dir) + additional_pythonpath_for_non_installed.append( + eachpath) + cmd = [os.path.join(non_installed_dir, self.bindir, self.exe), + "-m", + "venv", + "--without-pip", + self.env_dir] + # Our fake non-installed python is not fully functional because + # it cannot find the extensions. Set PYTHONPATH so it can run the + # venv module correctly. + pythonpath = os.pathsep.join( + additional_pythonpath_for_non_installed) + # For python built with shared enabled. We need to set + # LD_LIBRARY_PATH so the non-installed python can find and link + # libpython.so + ld_library_path = os.path.abspath(os.path.dirname(sys.executable)) + if sys.platform == 'darwin': + ld_library_path_env = "DYLD_LIBRARY_PATH" + else: + ld_library_path_env = "LD_LIBRARY_PATH" + subprocess.check_call(cmd, + env={"PYTHONPATH": pythonpath, + ld_library_path_env: ld_library_path}) + envpy = os.path.join(self.env_dir, self.bindir, self.exe) + # Now check the venv created from the non-installed python has + # correct zip path in pythonpath. + cmd = [envpy, '-S', '-c', 'import sys; print(sys.path)'] + out, err = check_output(cmd) + self.assertTrue(zip_landmark.encode() in out) @requireVenvCreate class EnsurePipTest(BaseTest):