https://github.com/python/cpython/commit/bf6623aaeb3516606f89851b0ba8b5756f18e9cf
commit: bf6623aaeb3516606f89851b0ba8b5756f18e9cf
branch: main
author: Neko Asakura <[email protected]>
committer: vsajip <[email protected]>
date: 2026-11-09T11:46:43Z
summary:
gh-160782: reject symlinked subdirectories in the venv directory (GH-160973)
files:
A Misc/NEWS.d/next/Library/2026-10-30-10-36-30.gh-issue-160782.n6JCUU.rst
M Lib/test/test_venv.py
M Lib/venv/__init__.py
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index 678615ea172aefa..43c2a552ee90b7f 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -663,6 +663,24 @@ def test_unoverwritable_fails(self):
self.assertRaises((ValueError, OSError), venv.create, self.env_dir)
self.clear_directory(self.env_dir)
+ @unittest.skipUnless(can_symlink(), 'Needs symlinks')
+ def test_symlinked_directory_error(self):
+ """
+ Test that venv creation fails when a directory inside the target
+ directory is a symlink.
+ """
+ outside = tempfile.mkdtemp()
+ self.addCleanup(rmtree, outside)
+ for n in range(1, len(self.lib) + 1):
+ subdirs = self.lib[:n]
+ with self.subTest(subdirs=subdirs):
+ rmtree(self.env_dir)
+ os.makedirs(os.path.join(self.env_dir, *subdirs[:-1]))
+ os.symlink(outside, os.path.join(self.env_dir, *subdirs),
+ target_is_directory=True)
+ self.assertRaises(ValueError, venv.create, self.env_dir)
+ self.assertEqual(os.listdir(outside), [])
+
def test_upgrade(self):
"""
Test upgrading an existing environment directory.
diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py
index 620168be16862ec..60fe070b1f9f4b1 100644
--- a/Lib/venv/__init__.py
+++ b/Lib/venv/__init__.py
@@ -141,6 +141,12 @@ def ensure_directories(self, env_dir):
"""
def create_if_needed(d):
+ path = env_dir
+ for part in os.path.relpath(d, env_dir).split(os.sep)[:-1]:
+ path = os.path.join(path, part)
+ if os.path.islink(path) or os.path.isjunction(path):
+ raise ValueError(f'Refusing to create a venv in {env_dir} '
+ f'because {path} is a link.')
if not os.path.exists(d):
os.makedirs(d)
elif os.path.islink(d) or os.path.isfile(d):
diff --git
a/Misc/NEWS.d/next/Library/2026-10-30-10-36-30.gh-issue-160782.n6JCUU.rst
b/Misc/NEWS.d/next/Library/2026-10-30-10-36-30.gh-issue-160782.n6JCUU.rst
new file mode 100644
index 000000000000000..d4da24bdca0b5e8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-10-30-10-36-30.gh-issue-160782.n6JCUU.rst
@@ -0,0 +1,2 @@
+:mod:`venv`: a symbolic link or junction in place of a directory inside the
+environment now raises :exc:`ValueError` instead of being followed.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]