Skip to content

Commit 6c342df

Browse files
committed
Idempotent .pth execution in site.addsitedir
1 parent 62a6e89 commit 6c342df

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

Lib/site.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,14 @@ def addsitedir(sitedir, known_paths=None):
242242
if not sitedircase in known_paths:
243243
sys.path.append(sitedir) # Add path component
244244
known_paths.add(sitedircase)
245-
try:
246-
names = os.listdir(sitedir)
247-
except OSError:
248-
return
249-
names = [name for name in names
250-
if name.endswith(".pth") and not name.startswith(".")]
251-
for name in sorted(names):
252-
addpackage(sitedir, name, known_paths)
245+
try:
246+
names = os.listdir(sitedir)
247+
except OSError:
248+
return
249+
names = [name for name in names
250+
if name.endswith(".pth") and not name.startswith(".")]
251+
for name in sorted(names):
252+
addpackage(sitedir, name, known_paths)
253253
if reset:
254254
known_paths = None
255255
return known_paths

Lib/test/test_site.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def pth_file_tests(self, pth_file):
116116
"%s not in sys.modules" % pth_file.imported)
117117
self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
118118
self.assertFalse(os.path.exists(pth_file.bad_dir_path))
119+
self.assertFalse(os.path.exists(pth_file.idempotent_fail_path))
119120

120121
def test_addpackage(self):
121122
# Make sure addpackage() imports if the line starts with 'import',
@@ -199,6 +200,19 @@ def test_addsitedir(self):
199200
finally:
200201
pth_file.cleanup()
201202

203+
def test_addsitedir_idempotent(self):
204+
pth_file = PthFile()
205+
pth_file.cleanup(prep=True)
206+
207+
try:
208+
pth_file.create()
209+
dirs = set()
210+
dirs = site.addsitedir(pth_file.base_dir, dirs)
211+
dirs = site.addsitedir(pth_file.base_dir, dirs)
212+
self.pth_file_tests(pth_file)
213+
finally:
214+
pth_file.cleanup(prep=True)
215+
202216
def test_addsitedir_dotfile(self):
203217
pth_file = PthFile('.dotfile')
204218
pth_file.cleanup(prep=True)
@@ -414,6 +428,7 @@ def __init__(self, filename_base=TESTFN, imported="time",
414428
self.bad_dirname = bad_dirname
415429
self.good_dir_path = os.path.join(self.base_dir, self.good_dirname)
416430
self.bad_dir_path = os.path.join(self.base_dir, self.bad_dirname)
431+
self.idempotent_fail_path = os.path.join(self.base_dir, 'idempotent')
417432

418433
def create(self):
419434
"""Create a .pth file with a comment, blank lines, an ``import
@@ -430,6 +445,13 @@ def create(self):
430445
try:
431446
print("#import @bad module name", file=FILE)
432447
print("\n", file=FILE)
448+
449+
PROG = f'''\
450+
if {self.imported!r} in sys.modules:
451+
open({self.idempotent_fail_path!r}, 'a+').close()
452+
'''
453+
print(f"import sys; exec({PROG!r})", file=FILE)
454+
433455
print("import %s" % self.imported, file=FILE)
434456
print(self.good_dirname, file=FILE)
435457
print(self.bad_dirname, file=FILE)
@@ -454,6 +476,8 @@ def cleanup(self, prep=False):
454476
os.rmdir(self.good_dir_path)
455477
if os.path.exists(self.bad_dir_path):
456478
os.rmdir(self.bad_dir_path)
479+
if os.path.exists(self.idempotent_fail_path):
480+
os.remove(self.idempotent_fail_path)
457481

458482
class ImportSideEffectTests(unittest.TestCase):
459483
"""Test side-effects from importing 'site'."""
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Idempotent ``.pth`` file exection in :meth:`site.addsitedir`.

0 commit comments

Comments
 (0)