Skip to content

Commit ba9d6db

Browse files
committed
gh-143768: rebuild broken interpreter symlinks
1 parent a6bc60d commit ba9d6db

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

Lib/test/test_venv.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,24 @@ def test_failed_symlink(self):
597597
filepath_regex = r"'[A-Z]:\\\\(?:[^\\\\]+\\\\)*[^\\\\]+'"
598598
self.assertRegex(err, rf"Unable to symlink {filepath_regex} to {filepath_regex}")
599599

600+
@requireVenvCreate
601+
@unittest.skipUnless(can_symlink(), 'Needs symlinks')
602+
def test_broken_symlink_in_existing_venv(self):
603+
"""
604+
Test creating a venv when a stale venv with broken symlinks exists.
605+
"""
606+
bindir = os.path.join(self.env_dir, self.bindir)
607+
os.makedirs(bindir)
608+
python = os.path.join(bindir, 'python3')
609+
os.symlink('/path/to/deleted/conda/env/bin/python3', python)
610+
self.assertTrue(os.path.islink(python))
611+
self.assertFalse(os.path.exists(python))
612+
613+
builder = venv.EnvBuilder(with_pip=False, symlinks=True)
614+
self.run_with_capture(builder.create, self.env_dir)
615+
self.assertTrue(os.path.islink(python))
616+
self.assertTrue(os.path.exists(python))
617+
600618
@requireVenvCreate
601619
def test_multiprocessing(self):
602620
"""

Lib/venv/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ def symlink_or_copy(self, src, dst, relative_symlinks_ok=False):
267267
switch to a different set of files instead.)
268268
"""
269269
assert os.name != 'nt'
270+
if os.path.islink(dst) and not os.path.exists(dst):
271+
os.unlink(dst)
270272
force_copy = not self.symlinks
271273
if not force_copy:
272274
try:

0 commit comments

Comments
 (0)