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

@nascheme nascheme 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 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.

1 participant