Skip to content

gh-151377: Fix races updating type slots and subclasses - #155370

Draft
nascheme wants to merge 1 commit into
python:mainfrom
nascheme:gh-151377-type-data-race
Draft

gh-151377: Fix races updating type slots and subclasses#155370
nascheme wants to merge 1 commit into
python:mainfrom
nascheme:gh-151377-type-data-race

Conversation

@nascheme

@naschemenascheme commented Aug 7, 2026

Copy link
Copy Markdown
Member
  • Avoid data race in fixup_slot_dispatchers().
  • Set _Py_TYPE_REVEALED_FLAG before the type is published
  • PyType_FromMetaclass() now uses type_ready()/type_ready_publish() rather than PyType_Ready(), like type_new_impl() does, so that it publishes the type the same way. The flag macros are only defined for debug builds now, since that is the only build where the flag exists.
  • Hold the type lock while iterating tp_subclasses.
  • Hold the type lock while the slots of a new type are set up. fixup_slot_dispatchers() previously ran without the type lock held. Another thread could assign to a special method of a base between the point where we look up the special methods in the bases and the point where the type is added to the subclasses of its bases.
  • Do the ready, the slot fixup and the publishing of the type in one type lock critical section. A concurrent assignment to a base now either happens before we look up the special methods, or it finds the type in the subclasses of its bases. The slots are still stored directly rather than with the world stopped, since the type is not reachable by other threads yet.

* Avoid data race in fixup_slot_dispatchers().
* Set _Py_TYPE_REVEALED_FLAG before the type is published
* PyType_FromMetaclass() now uses type_ready()/type_ready_publish()
rather than PyType_Ready(), like type_new_impl() does, so that it
publishes the type the same way. The flag macros are only defined for
debug builds now, since that is the only build where the flag exists.
* Hold the type lock while iterating tp_subclasses.
* Hold the type lock while the slots of a new type are set up.
fixup_slot_dispatchers() previously ran without the type lock held.
Another thread could assign to a special method of a base between the
point where we look up the special methods in the bases and the point
where the type is added to the subclasses of its bases.
* Do the ready, the slot fixup and the publishing of the type in one
type lock critical section. A concurrent assignment to a base now
either happens before we look up the special methods, or it finds the
type in the subclasses of its bases. The slots are still stored
directly rather than with the world stopped, since the type is not
reachable by other threads yet.
Co-authored-by: lipengyu <lipengyu@kylinos.cn>
Assisted-by: Claude Opus 5
Sign up for freeto 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.

1 participant

@nascheme