Skip to content

Conversation

@serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Nov 16, 2025

  • Allow defining the dict and weakref slots for any class.
  • Allow defining any slots for a class derived from the type class or other "variable-length" built-in type with the Py_TPFLAGS_ITEMS_AT_END flag.

📚 Documentation preview 📚: https://cpython-previews--141636.org.readthedocs.build/

…sses

* Allow defining the __dict__ and __weakref__ __slots__ for any class.
* Allow defining any __slots__ for a class derived from the type class or
  other "variable-length" built-in type with the Py_TPFLAGS_ITEMS_AT_END flag.
@serhiy-storchaka serhiy-storchaka force-pushed the special-slots-with-items2 branch from 8c3d950 to c17b254 Compare November 16, 2025 20:35
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
@picnixz
Copy link
Member

picnixz commented Nov 17, 2025

Well.. that's weird. The docs still fail?

…e-103740.rXIj5h.rst

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
@serhiy-storchaka
Copy link
Member Author

Thank you. I noticed this error yesterday (this is is the second time I make such error in a month), but it was already late night.

@picnixz
Copy link
Member

picnixz commented Nov 17, 2025

No worry! don't hesitate to ping in the future if you encounter other Sphinx errors!

Copy link
Member

@encukou encukou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!
I need a bit more time to review the code; sending docs suggestions in the meantime.

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Comment on lines +2637 to +2638
For example, *__slots__* other than *__dict__* and *__weakref__* cannot
be defined on subclasses of :class:`int`, :class:`bytes`, or :class:`tuple`.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use "they"?

Suggested change
For example, *__slots__* other than *__dict__* and *__weakref__* cannot
be defined on subclasses of :class:`int`, :class:`bytes`, or :class:`tuple`.
For example, they cannot be defined on subclasses of
:class:`int`, :class:`bytes`, or :class:`tuple`.

@encukou
Copy link
Member

encukou commented Nov 18, 2025

The only Py_TPFLAGS_ITEMS_AT_END type in stdlib is type itself.
So, this PR allows slotted types. Adding data descriptors to types leads to some rather hard-to-explain behaviour, for example:

>>> class Meta(type):
...     __slots__ = ['foo']  # now possible
...     
>>> class X(metaclass=Meta):
...     def foo(self): return 'f'
...     
>>> X().foo
<bound method X.foo of <__main__.X object at 0x7f7c579c2900>>
>>> X.foo
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    X.foo
AttributeError: 'Meta' object has no attribute 'foo'
>>> X.foo = slice
>>> X.foo(X())
slice(None, <__main__.X object at 0x7f7c5788c050>, None)
>>> X().foo()
'f'

Do we want to make this easier?

@serhiy-storchaka
Copy link
Member Author

I did not have any use case for this feature, but this looks interesting. We already have data descriptors (__module__, __qualname__, etc). And we can get the same with properties:

class Meta(type):
    @property
    def foo(self):
        return slice

class X(metaclass=Meta):
    def foo(self): return 'f'
 
print(X.foo(X()))
print(X().foo())

@encukou
Copy link
Member

encukou commented Nov 19, 2025

Yes, descriptors are already weird. But given stdlib's non-usage of Py_TPFLAGS_ITEMS_AT_END, this feature looks to be specifically about allowing descriptors for type, so I'm not sure we want it.

What about explicitly disabling arbitrary __slots__ on type subclasses, given how many optimizations assume that the __dict__ is authoritative?


The __dict__ & __weakref__ change looks uncontroversial -- and easier to explain, too.

@serhiy-storchaka
Copy link
Member Author

Was not it the same with PEP 697? It allowed extending type in C. This PR allows to extend it in Python.

Anyway, I am only interesting in extending tuples. Adding support for special slots would be a side effect. Supporting __slots__ in the type subclasses is not necessary, it would only look inconsistent to not support it after PEP 697.

@serhiy-storchaka
Copy link
Member Author

See #141755.

@encukou
Copy link
Member

encukou commented Nov 19, 2025

PEP 697's “extending” was about adding a C-level chunk of memory, not about Python attributes. You can already extend type in Python. It has a __dict__.

Having a __dict__ also means the memory savings from __slots__ will be tiny, unless you have many slots. (Not to mention that type itself is huge.)

@serhiy-storchaka
Copy link
Member Author

The other half of this PR (very simple) has been moved to #141764.

@serhiy-storchaka
Copy link
Member Author

Lets discuss this not in PRs, but in the issue #103740.

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.

3 participants