Skip to content

Commit 50409a2

Browse files
miss-islingtonionite34mdickinson
authored
[3.11] gh-100637: Fix int and bool __sizeof__ calculation to include the 1 element ob_digit array for 0 and False (GH-100663) (#100717)
gh-100637: Fix int and bool __sizeof__ calculation to include the 1 element ob_digit array for 0 and False (GH-100663) Fixes behaviour where int (and subtypes like bool) __sizeof__ under-reports true size as it did not take into account the size 1 `ob_digit` array for the zero int. (cherry picked from commit d7e7f79) Co-authored-by: Ionite <[email protected]> Co-authored-by: Mark Dickinson <[email protected]>
1 parent 861cdef commit 50409a2

File tree

3 files changed

+7
-2
lines changed

3 files changed

+7
-2
lines changed

Lib/test/test_sys.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,7 @@ def test_objecttypes(self):
13221322
check = self.check_sizeof
13231323
# bool
13241324
check(True, vsize('') + self.longdigit)
1325+
check(False, vsize('') + self.longdigit)
13251326
# buffer
13261327
# XXX
13271328
# builtin_function_or_method
@@ -1459,7 +1460,7 @@ def get_gen(): yield 1
14591460
# listreverseiterator (list)
14601461
check(reversed([]), size('nP'))
14611462
# int
1462-
check(0, vsize(''))
1463+
check(0, vsize('') + self.longdigit)
14631464
check(1, vsize('') + self.longdigit)
14641465
check(-1, vsize('') + self.longdigit)
14651466
PyLong_BASE = 2**sys.int_info.bits_per_digit
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix :func:`int.__sizeof__` calculation to include the 1 element ob_digit array for 0 and False.

Objects/longobject.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5661,7 +5661,10 @@ int___sizeof___impl(PyObject *self)
56615661
{
56625662
Py_ssize_t res;
56635663

5664-
res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(self))*sizeof(digit);
5664+
res = offsetof(PyLongObject, ob_digit)
5665+
/* using Py_MAX(..., 1) because we always allocate space for at least
5666+
one digit, even though the integer zero has a Py_SIZE of 0 */
5667+
+ Py_MAX(Py_ABS(Py_SIZE(self)), 1)*sizeof(digit);
56655668
return res;
56665669
}
56675670

0 commit comments

Comments
 (0)