Skip to content

We have run out of flags bits in PyTypeObject's tp_flags #134860

Description

@markshannon

PyTypeObject's tp_flags field is defined as an unsigned long. In effect this means that we have only 32 bits we can use for flags. We have already used all 32 of them.

Bits 15 and 16 are reserved for Stackless Python. Since Stackless Python is pining for the fjords, we could recycle those two bits. However that's not going to last long with likely changes necessary for parallelism and performance.

Any change to PyTypeObject breaks both API and ABI, but that's OK because:

  • Adding a field or changing the size of a field is a backwards compatible API change.
  • The existence of PyTypeObject is part of the stable ABI, but its layout is not.

The cleanest change, IMO, is to change unsigned long tp_flags to uint64_t tp_flags which gives us another 32 bits, which should last many more years.

Activity

  1. ronaldoussoren commented on May 29, 2025

    @ronaldoussoren
    Contributor

    Flags are also an unsigned int in PyType_Spec, which is part of the stable ABI. See https://docs.python.org/3/c-api/type.html#c.PyType_Spec.flags

  2. encukou commented on Jul 11, 2025

    @encukou
    Member

    Let's add a new field for new internal flags, so they don't clutter the public API. (Moving _Py_TPFLAGS_STATIC_BUILTIN and _Py_TPFLAGS_MATCH_SELF there would free up two bits.
    And also switch to uint64_t.

    Flags are also an unsigned int in PyType_Spec, which is part of the stable ABI.

    For new flags we can add slots, and teach PyType_From* & PyType_GetSlot to handle bits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions