Skip to content

__sizeof__ incorrectly ignores the size 1 array in PyVarObjects (bool, int, tuple) when ob_size is 0 #100637

Closed
@ionite34

Description

@ionite34

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions