Skip to content

Commit d7e7f79

Browse files
ionite34mdickinson
andauthored
gh-100637: Fix int and bool __sizeof__ calculation to include the 1 element ob_digit array for 0 and False (#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. Co-authored-by: Mark Dickinson <[email protected]>
1 parent 9dee973 commit d7e7f79

File tree

3 files changed

+7
-2
lines changed

3 files changed

+7
-2
lines changed

Lib/test/test_sys.py

+2-1
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
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

+4-1
Original file line numberDiff line numberDiff line change
@@ -5879,7 +5879,10 @@ int___sizeof___impl(PyObject *self)
58795879
{
58805880
Py_ssize_t res;
58815881

5882-
res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(self))*sizeof(digit);
5882+
res = offsetof(PyLongObject, ob_digit)
5883+
/* using Py_MAX(..., 1) because we always allocate space for at least
5884+
one digit, even though the integer zero has a Py_SIZE of 0 */
5885+
+ Py_MAX(Py_ABS(Py_SIZE(self)), 1)*sizeof(digit);
58835886
return res;
58845887
}
58855888

0 commit comments

Comments
 (0)