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
Bug report
Most built-in types, when subclassed, will have a__sizeof__ that is 8 (pointer size) larger than the parent object, due to having an instance dictionary.
classUserFloat(float):passassertUserFloat().__sizeof__()- (0.0).__sizeof__()==8classUserTuple(tuple):passassertUserTuple().__sizeof__()- ().__sizeof__()==8classUserList(list):passassertUserList().__sizeof__()- [].__sizeof__()==8classUserDict(dict):passassertUserDict().__sizeof__()- {}.__sizeof__()==8
This is unexpectedly, not the case forint andset, which exactly match the original__sizeof__
classUserSet(set):passprint(UserSet().__sizeof__(),set().__sizeof__())# 200 200classUserInt(int):passprint(UserInt().__sizeof__(), (0).__sizeof__())# 24 24
As a result this makes__dictoffset__ usages incorrect as well
fromctypesimportpy_objectclassUserTuple(tuple):passx=UserTuple()x.a=5print(x.__dict__)>> {'a':5}py_object.from_address(id(x)+x.__sizeof__()+UserTuple.__dictoffset__)>>py_object({'a':5})
fromctypesimportpy_objectclassUserInt(int):passx=UserInt()x.a=5print(x.__dict__)>> {'a':5}py_object.from_address(id(x)+x.__sizeof__()+UserInt.__dictoffset__)>>py_object(<NULL>)
Your environment
- CPython versions tested on: 3.11, 3.12.0a3