What is the __weakrefoffset__
attribute for? What does the integer value signify?
>>> int.__weakrefoffset__
0
>>> class A:
... pass
...
>>> A.__weakrefoffset__
24
>>> type.__weakrefoffset__
368
>>> class B:
... __slots__ = ()
...
>>> B.__weakrefoffset__
0
All types seem to have this attribute. But there's no mention about that in docs nor in PEP 205.
In CPython, the layout of a simple type like float
is three fields: its type pointer, its reference count, and its value (here, a double
). For list
, the value is three variables (the pointer to the separately-allocated array, its capacity, and the used size). These types do not support attributes or weak references to save space.
If a Python class inherits from one of these, it’s critical that it be able to support attributes, and yet there is no fixed offset at which to place the __dict__
pointer (without wasting memory by putting it at a large unused offset). So the dictionary is stored wherever there is room, and its offset in bytes is recorded in the type. For base classes where the size is variable (like tuple
, which includes all its pointers directly), there is special support for storing the __dict__
pointer past the end of the variable-size section (e.g., type("",(tuple,),{}).__dictoffset__
is -8).
The situation with weak references is exactly analogous, except that there is no support for (subclasses of) variable-sized types. A __weakrefoffset__
of 0 (which is conveniently the default for C static variables) indicates no support, since of course the object’s type is known to always be at the beginning of its layout.