-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
Description
Bug report
Bug description:
I stumbled upon the following error (code snippet from python 3.12.3 with gcc 13.2.0, but I also checked with 3.11 and 3.13):
>> from abc import ABCMeta
>>> class Abstract(metaclass=ABCMeta):
... ...
...
>>> class Concrete(Abstract):
... __slots__ = ('__weakref__',)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen abc>", line 106, in __new__
TypeError: __weakref__ slot disallowed: we already got one
This also happens when inheriting from abc.ABC
. This surprised me since the documentation does not mention __weakref__
being added.
Adding to my confusion, the common abstract base classes from collections.abc
do not have this behavior (I only checked Mapping
, Sequence
and Collection
), i.e., __weakref__
attribute is not added to the class.
Another peculiarity here is that while a class with metaclass =ABCMeta
is automatically weakref-able, and has a __weakref__
attribute, the __weakref__
cannot be found in its __slots__
, and in fact there might not even be a __slots__
attribute anywhere in the MRO!
>>> import abc
>>> class A(abc.ABC): ...
...
>>> A.__weakref__
<attribute '__weakref__' of 'A' objects>
>>> A.__slots__ # __slots__ attribute exist but no __weakref__
()
>>> class B(metaclass=abc.ABCMeta): ...
...
>>> B.__weakref__
<attribute '__weakref__' of 'B' objects>
>>> B.__slots__ # __slots__ attribute does not exist
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'B' has no attribute '__slots__'. Did you mean: '__class__'?
At the very least this warrant adding documentation to abc.ABC
and abc.ABCMeta
. A better fix IMO is adding __weakref__
to __slots__
.
Another solution (which I like the most) is not adding __weakref__
to abstract classes to begin with, but I suspect this might break some code.
CPython versions tested on:
3.11, 3.12, 3.13
Operating systems tested on:
Linux