gh-99370: fix test_zippath_from_non_installed_posix (GH-99483)

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.
This commit is contained in:
Kai Zhang 2022-11-15 09:01:01 +08:00 committed by GitHub
parent dc3e4350a5
commit 1df0752b4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -547,58 +547,67 @@ class BasicTest(BaseTest):
rmtree(self.env_dir) rmtree(self.env_dir)
# First try to create a non-installed python. It's not a real full # First try to create a non-installed python. It's not a real full
# functional non-installed python, but enough for this test. # functional non-installed python, but enough for this test.
platlibdir = sys.platlibdir
non_installed_dir = os.path.realpath(tempfile.mkdtemp()) non_installed_dir = os.path.realpath(tempfile.mkdtemp())
try: self.addCleanup(rmtree, non_installed_dir)
bindir = os.path.join(non_installed_dir, self.bindir) bindir = os.path.join(non_installed_dir, self.bindir)
os.mkdir(bindir) os.mkdir(bindir)
shutil.copy2(sys.executable, 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) os.makedirs(libdir)
landmark = os.path.join(libdir, "os.py") landmark = os.path.join(libdir, "os.py")
stdlib_zip = "python%d%d.zip" % sys.version_info[:2] stdlib_zip = "python%d%d.zip" % sys.version_info[:2]
zip_landmark = os.path.join(non_installed_dir, zip_landmark = os.path.join(non_installed_dir,
self.lib[0], platlibdir,
stdlib_zip) stdlib_zip)
additional_pythonpath_for_non_installed = [] additional_pythonpath_for_non_installed = []
# Copy stdlib files to the non-installed python so venv can # Copy stdlib files to the non-installed python so venv can
# correctly calculate the prefix. # correctly calculate the prefix.
for eachpath in sys.path: for eachpath in sys.path:
if eachpath.endswith(".zip"): if eachpath.endswith(".zip"):
if os.path.isfile(eachpath): if os.path.isfile(eachpath):
shutil.copyfile( shutil.copyfile(
eachpath, 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")): elif os.path.isfile(os.path.join(eachpath, "os.py")):
for name in os.listdir(eachpath): for name in os.listdir(eachpath):
if name == "site-packages": if name == "site-packages":
continue continue
fn = os.path.join(eachpath, name) fn = os.path.join(eachpath, name)
if os.path.isfile(fn): if os.path.isfile(fn):
shutil.copy(fn, libdir) shutil.copy(fn, libdir)
elif os.path.isdir(fn): elif os.path.isdir(fn):
shutil.copytree(fn, os.path.join(libdir, name)) shutil.copytree(fn, os.path.join(libdir, name))
else: else:
additional_pythonpath_for_non_installed.append( additional_pythonpath_for_non_installed.append(
eachpath) eachpath)
cmd = [os.path.join(non_installed_dir, self.bindir, self.exe), cmd = [os.path.join(non_installed_dir, self.bindir, self.exe),
"-m", "-m",
"venv", "venv",
"--without-pip", "--without-pip",
self.env_dir] self.env_dir]
# Our fake non-installed python is not fully functional because # Our fake non-installed python is not fully functional because
# it cannot find the extensions. Set PYTHONPATH so it can run the # it cannot find the extensions. Set PYTHONPATH so it can run the
# venv module correctly. # venv module correctly.
pythonpath = os.pathsep.join( pythonpath = os.pathsep.join(
additional_pythonpath_for_non_installed) additional_pythonpath_for_non_installed)
subprocess.check_call(cmd, env={"PYTHONPATH": pythonpath}) # For python built with shared enabled. We need to set
envpy = os.path.join(self.env_dir, self.bindir, self.exe) # LD_LIBRARY_PATH so the non-installed python can find and link
# Now check the venv created from the non-installed python has # libpython.so
# correct zip path in pythonpath. ld_library_path = os.path.abspath(os.path.dirname(sys.executable))
cmd = [envpy, '-S', '-c', 'import sys; print(sys.path)'] if sys.platform == 'darwin':
out, err = check_output(cmd) ld_library_path_env = "DYLD_LIBRARY_PATH"
self.assertTrue(zip_landmark.encode() in out) else:
finally: ld_library_path_env = "LD_LIBRARY_PATH"
rmtree(non_installed_dir) 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 @requireVenvCreate
class EnsurePipTest(BaseTest): class EnsurePipTest(BaseTest):