[Python-checkins] gh-100637: Fix int and bool __sizeof__ calculation to include the 1 element ob_digit array for 0 and False (#100663)

mdickinson webhook-mailer at python.org
Mon Jan 2 16:11:59 EST 2023


https://github.com/python/cpython/commit/d7e7f79ca7c2029e46a06d21a7a5abea631b5d13
commit: d7e7f79ca7c2029e46a06d21a7a5abea631b5d13
branch: main
author: Ionite <dev at ionite.io>
committer: mdickinson <dickinsm at gmail.com>
date: 2023-01-02T21:11:49Z
summary:

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 <dickinsm at gmail.com>

files:
A Misc/NEWS.d/next/Core and Builtins/2023-01-01-15-59-48.gh-issue-100637.M2n6Kg.rst
M Lib/test/test_sys.py
M Objects/longobject.c

diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 17a5026e2571..232b79971dc2 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1322,6 +1322,7 @@ def test_objecttypes(self):
         check = self.check_sizeof
         # bool
         check(True, vsize('') + self.longdigit)
+        check(False, vsize('') + self.longdigit)
         # buffer
         # XXX
         # builtin_function_or_method
@@ -1459,7 +1460,7 @@ def get_gen(): yield 1
         # listreverseiterator (list)
         check(reversed([]), size('nP'))
         # int
-        check(0, vsize(''))
+        check(0, vsize('') + self.longdigit)
         check(1, vsize('') + self.longdigit)
         check(-1, vsize('') + self.longdigit)
         PyLong_BASE = 2**sys.int_info.bits_per_digit
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-01-15-59-48.gh-issue-100637.M2n6Kg.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-01-15-59-48.gh-issue-100637.M2n6Kg.rst
new file mode 100644
index 000000000000..164f6f5f2f44
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-01-15-59-48.gh-issue-100637.M2n6Kg.rst	
@@ -0,0 +1 @@
+Fix :func:`int.__sizeof__` calculation to include the 1 element ob_digit array for 0 and False.
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 0df3b9a9d564..1db4ca418e06 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -5879,7 +5879,10 @@ int___sizeof___impl(PyObject *self)
 {
     Py_ssize_t res;
 
-    res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(self))*sizeof(digit);
+    res = offsetof(PyLongObject, ob_digit)
+        /* using Py_MAX(..., 1) because we always allocate space for at least
+           one digit, even though the integer zero has a Py_SIZE of 0 */
+        + Py_MAX(Py_ABS(Py_SIZE(self)), 1)*sizeof(digit);
     return res;
 }
 



More information about the Python-checkins mailing list