]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-35978: Correctly skips venv tests in venvs (GH-12220)
authorSteve Dower <steve.dower@microsoft.com>
Thu, 21 Mar 2019 17:04:21 +0000 (10:04 -0700)
committerGitHub <noreply@github.com>
Thu, 21 Mar 2019 17:04:21 +0000 (10:04 -0700)
Also fixes venvs from the build directory on Windows.

Lib/test/test_venv.py
Lib/venv/__init__.py

index 0b2c7a0258df1614f2373d31707baed8ed0a2caf..6822d567e42b58883b68cbeca7629ed46217b2ef 100644 (file)
@@ -24,8 +24,12 @@ try:
 except ImportError:
     ctypes = None
 
-skipInVenv = unittest.skipIf(sys.prefix != sys.base_prefix,
-                             'Test not appropriate in a venv')
+# Platforms that set sys._base_executable can create venvs from within
+# another venv, so no need to skip tests that require venv.create().
+requireVenvCreate = unittest.skipUnless(
+    hasattr(sys, '_base_executable')
+    or sys.prefix == sys.base_prefix,
+    'cannot run venv.create from within a venv on this platform')
 
 def check_output(cmd, encoding=None):
     p = subprocess.Popen(cmd,
@@ -126,7 +130,7 @@ class BasicTest(BaseTest):
         self.assertEqual(context.prompt, '(My prompt) ')
         self.assertIn("prompt = 'My prompt'\n", data)
 
-    @skipInVenv
+    @requireVenvCreate
     def test_prefixes(self):
         """
         Test that the prefix values are as expected.
@@ -262,7 +266,7 @@ class BasicTest(BaseTest):
     # run the test, the pyvenv.cfg in the venv created in the test will
     # point to the venv being used to run the test, and we lose the link
     # to the source build - so Python can't initialise properly.
-    @skipInVenv
+    @requireVenvCreate
     def test_executable(self):
         """
         Test that the sys.executable value is as expected.
@@ -306,6 +310,7 @@ class BasicTest(BaseTest):
         )
         self.assertEqual(out.strip(), '0')
 
+    @requireVenvCreate
     def test_multiprocessing(self):
         """
         Test that the multiprocessing is able to spawn.
@@ -319,7 +324,7 @@ class BasicTest(BaseTest):
             'print(Pool(1).apply_async("Python".lower).get(3))'])
         self.assertEqual(out.strip(), "python".encode())
 
-@skipInVenv
+@requireVenvCreate
 class EnsurePipTest(BaseTest):
     """Test venv module installation of pip."""
     def assert_pip_not_installed(self):
index a309b861c5f4d81cb7db386408d31e1e0cc20ff4..5e6d375e95a71c59793b6f03dfe0eb169ba53164 100644 (file)
@@ -178,18 +178,23 @@ class EnvBuilder:
                 # On Windows, we rewrite symlinks to our base python.exe into
                 # copies of venvlauncher.exe
                 basename, ext = os.path.splitext(os.path.basename(src))
-                if basename.endswith('_d'):
-                    ext = '_d' + ext
-                    basename = basename[:-2]
-                if sysconfig.is_python_build(True):
+                srcfn = os.path.join(os.path.dirname(__file__),
+                                     "scripts",
+                                     "nt",
+                                     basename + ext)
+                # Builds or venv's from builds need to remap source file
+                # locations, as we do not put them into Lib/venv/scripts
+                if sysconfig.is_python_build(True) or not os.path.isfile(srcfn):
+                    if basename.endswith('_d'):
+                        ext = '_d' + ext
+                        basename = basename[:-2]
                     if basename == 'python':
                         basename = 'venvlauncher'
                     elif basename == 'pythonw':
                         basename = 'venvwlauncher'
-                    scripts = os.path.dirname(src)
+                    src = os.path.join(os.path.dirname(src), basename + ext)
                 else:
-                    scripts = os.path.join(os.path.dirname(__file__), "scripts", "nt")
-                src = os.path.join(scripts, basename + ext)
+                    src = srcfn
 
             shutil.copyfile(src, dst)