Skip to content

gh-151722: Defer GC tracking of frozendict.fromkeys() result until fully built#151967

Open
tonghuaroot wants to merge 1 commit into
python:mainfrom
tonghuaroot:gh-151722-frozendict-fromkeys-ft-race
Open

gh-151722: Defer GC tracking of frozendict.fromkeys() result until fully built#151967
tonghuaroot wants to merge 1 commit into
python:mainfrom
tonghuaroot:gh-151722-frozendict-fromkeys-ft-race

Conversation

@tonghuaroot

@tonghuaroot tonghuaroot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

frozendict.fromkeys() fills its result by iterating the keys and inserting
them one at a time with PyIter_Next(), which runs user code (the iterable's
__next__). In the free-threaded build the result is GC-tracked during this
fill loop, so another thread calling gc.get_objects() can reach and take a
reference to the still half-built frozendict. That breaks the
unique-reference invariant the lock-free insert relies on, tripping
assert(can_modify_dict(mp)) on a debug build (or an unsynchronized write
concurrent with a reader on a release build).

This mirrors gh-151740, which applied the same untrack-during-build /
track-when-complete pattern to frozendict_new() and frozendict_vectorcall().
fromkeys() is the remaining construction path that change did not cover.

This is the separate follow-up for the fromkeys() path; in gh-151740
@corona10 suggested submitting it as its own PR once that one was merged.

Issue: #151722

…til fully built

frozendict.fromkeys() built its result with PyIter_Next() on an already
GC-tracked object, so a half-built frozendict was reachable from another
thread (using the gc module) and could be observed mutating mid-construction
in the free threading build.  Untrack the result while it is being filled and
re-track it once fully built.
@tonghuaroot tonghuaroot force-pushed the gh-151722-frozendict-fromkeys-ft-race branch from 302e646 to d45e42d Compare June 23, 2026 07:07
@corona10 corona10 self-assigned this Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants