From db6322cb8ac1a8edede92e1aa1e3c688742a7923 Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Thu, 2 Feb 2017 19:05:19 +0000 Subject: [PATCH] Fixes #24875: pip can now be installed in a venv with --system-site-packages. --- Lib/test/test_venv.py | 25 ++++++++++++++++--------- Lib/venv/__init__.py | 9 +++++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 3999d1f9c40..c1e656613bf 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -328,13 +328,7 @@ class EnsurePipTest(BaseTest): with open(os.devnull, "rb") as f: self.assertEqual(f.read(), b"") - # Requesting pip fails without SSL (http://bugs.python.org/issue19744) - @unittest.skipIf(ssl is None, ensurepip._MISSING_SSL_MESSAGE) - @unittest.skipUnless(threading, 'some dependencies of pip import threading' - ' module unconditionally') - # Issue #26610: pip/pep425tags.py requires ctypes - @unittest.skipUnless(ctypes, 'pip requires ctypes') - def test_with_pip(self): + def do_test_with_pip(self, system_site_packages): rmtree(self.env_dir) with EnvironmentVarGuard() as envvars: # pip's cross-version compatibility may trigger deprecation @@ -368,6 +362,7 @@ class EnsurePipTest(BaseTest): # config in place to ensure we ignore it try: self.run_with_capture(venv.create, self.env_dir, + system_site_packages=system_site_packages, with_pip=True) except subprocess.CalledProcessError as exc: # The output this produces can be a little hard to read, @@ -417,9 +412,21 @@ class EnsurePipTest(BaseTest): out = out.decode("latin-1") # Force to text, prevent decoding errors self.assertIn("Successfully uninstalled pip", out) self.assertIn("Successfully uninstalled setuptools", out) - # Check pip is now gone from the virtual environment - self.assert_pip_not_installed() + # Check pip is now gone from the virtual environment. This only + # applies in the system_site_packages=False case, because in the + # other case, pip may still be available in the system site-packages + if not system_site_packages: + self.assert_pip_not_installed() + # Requesting pip fails without SSL (http://bugs.python.org/issue19744) + @unittest.skipIf(ssl is None, ensurepip._MISSING_SSL_MESSAGE) + @unittest.skipUnless(threading, 'some dependencies of pip import threading' + ' module unconditionally') + # Issue #26610: pip/pep425tags.py requires ctypes + @unittest.skipUnless(ctypes, 'pip requires ctypes') + def test_with_pip(self): + self.do_test_with_pip(False) + self.do_test_with_pip(True) if __name__ == "__main__": unittest.main() diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 74245abbb2a..fa0326251e7 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -77,6 +77,10 @@ class EnvBuilder: """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) + # See issue 24875. We need system_site_packages to be False + # until after pip is installed. + true_system_site_packages = self.system_site_packages + self.system_site_packages = False self.create_configuration(context) self.setup_python(context) if self.with_pip: @@ -84,6 +88,11 @@ class EnvBuilder: if not self.upgrade: self.setup_scripts(context) self.post_setup(context) + if true_system_site_packages: + # We had set it to False before, now + # restore it and rewrite the configuration + self.system_site_packages = True + self.create_configuration(context) def clear_directory(self, path): for fn in os.listdir(path):