Skip to content

Commit 04b67f7

Browse files
committed
One small round of cleanup.
1 parent c6cfcb0 commit 04b67f7

4 files changed

Lines changed: 17 additions & 15 deletions

File tree

Lib/site.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def _init_pathinfo():
164164
# addsitedir() calls which use the default defer_processing_start_files=False
165165
# are self-contained: they create a per-call _StartupState, populate it from
166166
# the site directory's .pth/.start files, run process() on it, and then throw
167-
# the state it away. This is implicit batching and in that case the
167+
# the state away. This is implicit batching and in that case the
168168
# _startup_state global variable stays None.
169169
#
170170
# main() needs different semantics: it accumulates state across multiple
@@ -369,10 +369,10 @@ def _extend_syspath(self):
369369
)
370370

371371
def _exec_imports(self):
372-
# For each `import` line we've seen in a .pth file, exec() it in order
373-
# unless the .pth has a matching .start file in this same batch, in
374-
# which case PEP 829 says the import lines are suppressed in favor of
375-
# the .start's entry points.
372+
# For each `import` line we've seen in a .pth file, exec() it in
373+
# order, unless the .pth has a matching .start file in this same
374+
# batch. In that case, PEP 829 says the import lines are
375+
# suppressed in favor of the .start's entry points.
376376
for filename, imports in self._importexecs.items():
377377
# Given "/path/to/foo.pth", check whether "/path/to/foo.start" was
378378
# registered in this same batch.
@@ -446,7 +446,7 @@ def process_startup_files():
446446
*before* state.process() runs. This way, if an exec'd import line
447447
or .start entry point itself calls site.addsitedir(), that call
448448
creates its own per-call _StartupState rather than mutating the dicts
449-
being iterated here — see gh-149504.
449+
being iterated here. See gh-149504.
450450
"""
451451
global _startup_state
452452
if _startup_state is None:
@@ -508,7 +508,7 @@ def addsitedir(sitedir, known_paths=None, *, defer_processing_start_files=False)
508508
# 1. A batch is already active (_startup_state is set, e.g. because
509509
# main() previously called us with
510510
# defer_processing_start_files=True). Participate in this batch by
511-
# sharing the same. Don't flush the state since the batch's
511+
# sharing the same state. Don't flush the state since the batch's
512512
# eventual process_startup_files() will do that.
513513
#
514514
# 2. There is no active batch but the caller passed

Lib/test/test_site.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,9 +1606,9 @@ def increment():
16061606

16071607
# gh-149504
16081608
def test_reentrant_addsitedir_pth(self):
1609-
# An import line in a .pth file that calls site.addsitedir() must
1610-
# not crash or re-execute outer entries while the outer
1611-
# _exec_imports() is iterating _pending_importexecs.
1609+
# An import line in a .pth file that calls site.addsitedir()
1610+
# must not crash or re-execute outer entries while the outer
1611+
# call is still processing its pending startup state.
16121612
overlay = self.enterContext(os_helper.temp_dir())
16131613
overlay_pth = os.path.join(overlay, 'overlay.pth')
16141614
pkgdir = self.enterContext(os_helper.temp_dir())
@@ -1622,9 +1622,8 @@ def test_reentrant_addsitedir_pth(self):
16221622
# gh-149504
16231623
def test_reentrant_addsitedir_start(self):
16241624
# As above, but the re-entry happens from a .start entry point
1625-
# instead of a .pth import line. _execute_start_entrypoints()
1626-
# iterates _pending_entrypoints with the same pattern and is
1627-
# vulnerable to the same dictionary-changed-during-iteration bug.
1625+
# instead of a .pth import line. The entry point execution
1626+
# phase is vulnerable to the same class of bug.
16281627
overlay = self.enterContext(os_helper.temp_dir())
16291628
overlay_pth = os.path.join(overlay, 'overlay.pth')
16301629
pkgdir = self.enterContext(os_helper.temp_dir())

Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-23-51-23.gh-issue-149504.pDSCbn.rst

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fix :func:`site.addsitedir` to allow re-entrant calls from within startup
2+
files. Previously, a ``.pth`` file containing an ``import`` line that
3+
called :func:`site.addsitedir` (or a ``.start`` entry point doing the same)
4+
could crash with ``RuntimeError: dictionary changed size during iteration``
5+
during site initialization, breaking tools such as ``uv run --with``.

0 commit comments

Comments
 (0)