Skip to content

Commit 8bba81f

Browse files
authored
bpo-35978: Correctly skips venv tests in venvs (GH-12220)
Also fixes venvs from the build directory on Windows.
1 parent 7ee88bf commit 8bba81f

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

Lib/test/test_venv.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@
2424
except ImportError:
2525
ctypes = None
2626

27-
skipInVenv = unittest.skipIf(sys.prefix != sys.base_prefix,
28-
'Test not appropriate in a venv')
27+
# Platforms that set sys._base_executable can create venvs from within
28+
# another venv, so no need to skip tests that require venv.create().
29+
requireVenvCreate = unittest.skipUnless(
30+
hasattr(sys, '_base_executable')
31+
or sys.prefix == sys.base_prefix,
32+
'cannot run venv.create from within a venv on this platform')
2933

3034
def check_output(cmd, encoding=None):
3135
p = subprocess.Popen(cmd,
@@ -126,7 +130,7 @@ def test_prompt(self):
126130
self.assertEqual(context.prompt, '(My prompt) ')
127131
self.assertIn("prompt = 'My prompt'\n", data)
128132

129-
@skipInVenv
133+
@requireVenvCreate
130134
def test_prefixes(self):
131135
"""
132136
Test that the prefix values are as expected.
@@ -262,7 +266,7 @@ def test_symlinking(self):
262266
# run the test, the pyvenv.cfg in the venv created in the test will
263267
# point to the venv being used to run the test, and we lose the link
264268
# to the source build - so Python can't initialise properly.
265-
@skipInVenv
269+
@requireVenvCreate
266270
def test_executable(self):
267271
"""
268272
Test that the sys.executable value is as expected.
@@ -306,6 +310,7 @@ def test_unicode_in_batch_file(self):
306310
)
307311
self.assertEqual(out.strip(), '0')
308312

313+
@requireVenvCreate
309314
def test_multiprocessing(self):
310315
"""
311316
Test that the multiprocessing is able to spawn.
@@ -319,7 +324,7 @@ def test_multiprocessing(self):
319324
'print(Pool(1).apply_async("Python".lower).get(3))'])
320325
self.assertEqual(out.strip(), "python".encode())
321326

322-
@skipInVenv
327+
@requireVenvCreate
323328
class EnsurePipTest(BaseTest):
324329
"""Test venv module installation of pip."""
325330
def assert_pip_not_installed(self):

Lib/venv/__init__.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,18 +178,23 @@ def symlink_or_copy(self, src, dst, relative_symlinks_ok=False):
178178
# On Windows, we rewrite symlinks to our base python.exe into
179179
# copies of venvlauncher.exe
180180
basename, ext = os.path.splitext(os.path.basename(src))
181-
if basename.endswith('_d'):
182-
ext = '_d' + ext
183-
basename = basename[:-2]
184-
if sysconfig.is_python_build(True):
181+
srcfn = os.path.join(os.path.dirname(__file__),
182+
"scripts",
183+
"nt",
184+
basename + ext)
185+
# Builds or venv's from builds need to remap source file
186+
# locations, as we do not put them into Lib/venv/scripts
187+
if sysconfig.is_python_build(True) or not os.path.isfile(srcfn):
188+
if basename.endswith('_d'):
189+
ext = '_d' + ext
190+
basename = basename[:-2]
185191
if basename == 'python':
186192
basename = 'venvlauncher'
187193
elif basename == 'pythonw':
188194
basename = 'venvwlauncher'
189-
scripts = os.path.dirname(src)
195+
src = os.path.join(os.path.dirname(src), basename + ext)
190196
else:
191-
scripts = os.path.join(os.path.dirname(__file__), "scripts", "nt")
192-
src = os.path.join(scripts, basename + ext)
197+
src = srcfn
193198

194199
shutil.copyfile(src, dst)
195200

0 commit comments

Comments
 (0)