Bug report
tuple.__sizeof__, int.__sizeof__, and bool.__sizeof__ incorrectly returns a size using an algorithm that assumes the ob_item / ob_digit array is size 0 when ob_size is 0, when this is not true.
print((0).__sizeof__())
>> 24
print((1).__sizeof__())
>> 28
This result of __sizeof__ suggests that int(0) has an ob_digit array size of 0, and thus 4 less bytes (considering array dtype of c_uint32). However, this is not correct.
https://github.com/python/cpython/blob/3.11/Include/cpython/longintrepr.h#L79-L82
Code paths for the creation of int(0) and other PyVarObject types all initialize with an array of size 1. Such the struct of int(0) holds a c_uint32 array of size 1, and element [0] of 0.
The result 24 of (0).__sizeof__() suggests that this array does not exist for sizing purposes. This seems to be misleading for performance calculations on memory size, and creates unsafe scenarios when moving memory.
Implementations of __sizeof__
(int) (bool also inherits this)
https://github.com/python/cpython/blob/main/Objects/longobject.c#L5876-L5884
res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(self))*sizeof(digit);
(tuple)
https://github.com/python/cpython/blob/main/Objects/typeobject.c#L5929-L5942
Your environment
- CPython versions tested on: 3.11.1 and main branch
- Operating system and architecture: Windows and macOS
Linked PRs
Bug report
tuple.__sizeof__,int.__sizeof__, andbool.__sizeof__incorrectly returns a size using an algorithm that assumes theob_item/ob_digitarray is size 0 whenob_sizeis 0, when this is not true.This result of
__sizeof__suggests that int(0) has anob_digitarray size of 0, and thus 4 less bytes (considering array dtype of c_uint32). However, this is not correct.https://github.com/python/cpython/blob/3.11/Include/cpython/longintrepr.h#L79-L82
Code paths for the creation of
int(0)and other PyVarObject types all initialize with an array of size 1. Such the struct ofint(0)holds a c_uint32 array of size 1, and element [0] of 0.The result
24of(0).__sizeof__()suggests that this array does not exist for sizing purposes. This seems to be misleading for performance calculations on memory size, and creates unsafe scenarios when moving memory.Implementations of
__sizeof__(int) (bool also inherits this)
https://github.com/python/cpython/blob/main/Objects/longobject.c#L5876-L5884
(tuple)
https://github.com/python/cpython/blob/main/Objects/typeobject.c#L5929-L5942
Your environment
Linked PRs