Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Closed
Description
In Python, the__dict__ and__weakref__ slots are treated specially (slots meaning__slots__, nottp_slots)
They are automatically insert by the VM when creating a class.
classC(list):pass>>>C().__dict__{}
In order to support inheritance, specifically multiple inheritance, the VM can lay out subclasses in ways that differ from the superclass.
This is OK, provided__dict__ and__weakref__ are only accessed though thetp_dictoffset andtp_weaklistoffset offsets.
But, if either field is accessed directly, then we access invalid memory and 💥
test.py:
from_testcapiimportHeapCTypeWithDictclassI3(HeapCTypeWithDict,list):passi=I3()i.append(0)print(i.dictobj)
$ python3.10~/test/test.py Segmentation fault (core dumped)We have (accidentally) fixed this for__dict__ in 3.11, although at the expense breaking backwards compatibility for some C extensions. However, the problem still remains for__weakref__.
Backwards incompatibility
from_testcapiimportHeapCTypeWithDictclassI3(HeapCTypeWithDict,list):passprint("OK")
$ python3.10 test.py OK$ python3.12 test.py Traceback (most recent call last): File"test.py", line 3,in<module> class I3(HeapCTypeWithDict, list): passTypeError: multiple bases have instance lay-out conflict