File tree 4 files changed +48
-9
lines changed
Misc/NEWS.d/next/Core and Builtins
4 files changed +48
-9
lines changed Original file line number Diff line number Diff line change @@ -1601,5 +1601,44 @@ def test_square(self):
1601
1601
self .assertEqual (n ** 2 ,
1602
1602
(1 << (2 * bitlen )) - (1 << (bitlen + 1 )) + 1 )
1603
1603
1604
+ def test___sizeof__ (self ):
1605
+ self .assertEqual (int .__itemsize__ , sys .int_info .sizeof_digit )
1606
+
1607
+ # Pairs (test_value, number of allocated digits)
1608
+ test_values = [
1609
+ # We always allocate space for at least one digit, even for
1610
+ # a value of zero; sys.getsizeof should reflect that.
1611
+ (0 , 1 ),
1612
+ (1 , 1 ),
1613
+ (- 1 , 1 ),
1614
+ (BASE - 1 , 1 ),
1615
+ (1 - BASE , 1 ),
1616
+ (BASE , 2 ),
1617
+ (- BASE , 2 ),
1618
+ (BASE * BASE - 1 , 2 ),
1619
+ (BASE * BASE , 3 ),
1620
+ ]
1621
+
1622
+ for value , ndigits in test_values :
1623
+ with self .subTest (value ):
1624
+ self .assertEqual (
1625
+ value .__sizeof__ (),
1626
+ int .__basicsize__ + int .__itemsize__ * ndigits
1627
+ )
1628
+
1629
+ # Same test for a subclass of int.
1630
+ class MyInt (int ):
1631
+ pass
1632
+
1633
+ self .assertEqual (MyInt .__itemsize__ , sys .int_info .sizeof_digit )
1634
+
1635
+ for value , ndigits in test_values :
1636
+ with self .subTest (value ):
1637
+ self .assertEqual (
1638
+ MyInt (value ).__sizeof__ (),
1639
+ MyInt .__basicsize__ + MyInt .__itemsize__ * ndigits
1640
+ )
1641
+
1642
+
1604
1643
if __name__ == "__main__" :
1605
1644
unittest .main ()
Original file line number Diff line number Diff line change
1
+ Fix :func: `sys.getsizeof ` reporting for :class: `int ` subclasses.
Original file line number Diff line number Diff line change 4
4
#include "pycore_object.h" // _Py_FatalRefcountError()
5
5
#include "pycore_runtime.h" // _Py_ID()
6
6
7
+ #include <stddef.h>
8
+
7
9
/* We define bool_repr to return "False" or "True" */
8
10
9
11
static PyObject *
@@ -153,8 +155,8 @@ bool_dealloc(PyObject* Py_UNUSED(ignore))
153
155
PyTypeObject PyBool_Type = {
154
156
PyVarObject_HEAD_INIT (& PyType_Type , 0 )
155
157
"bool" ,
156
- sizeof (struct _longobject ),
157
- 0 ,
158
+ offsetof (struct _longobject , long_value . ob_digit ), /* tp_basicsize */
159
+ sizeof ( digit ), /* tp_itemsize */
158
160
bool_dealloc , /* tp_dealloc */
159
161
0 , /* tp_vectorcall_offset */
160
162
0 , /* tp_getattr */
Original file line number Diff line number Diff line change @@ -5882,13 +5882,10 @@ static Py_ssize_t
5882
5882
int___sizeof___impl (PyObject * self )
5883
5883
/*[clinic end generated code: output=3303f008eaa6a0a5 input=9b51620c76fc4507]*/
5884
5884
{
5885
- Py_ssize_t res ;
5886
-
5887
- res = offsetof(PyLongObject , long_value .ob_digit )
5888
- /* using Py_MAX(..., 1) because we always allocate space for at least
5889
- one digit, even though the integer zero has a Py_SIZE of 0 */
5890
- + Py_MAX (Py_ABS (Py_SIZE (self )), 1 )* sizeof (digit );
5891
- return res ;
5885
+ /* using Py_MAX(..., 1) because we always allocate space for at least
5886
+ one digit, even though the integer zero has a Py_SIZE of 0 */
5887
+ Py_ssize_t ndigits = Py_MAX (Py_ABS (Py_SIZE (self )), 1 );
5888
+ return Py_TYPE (self )-> tp_basicsize + Py_TYPE (self )-> tp_itemsize * ndigits ;
5892
5889
}
5893
5890
5894
5891
/*[clinic input]
You can’t perform that action at this time.
0 commit comments