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 @@ -1596,5 +1596,44 @@ def test_square(self):
1596
1596
self .assertEqual (n ** 2 ,
1597
1597
(1 << (2 * bitlen )) - (1 << (bitlen + 1 )) + 1 )
1598
1598
1599
+ def test___sizeof__ (self ):
1600
+ self .assertEqual (int .__itemsize__ , sys .int_info .sizeof_digit )
1601
+
1602
+ # Pairs (test_value, number of allocated digits)
1603
+ test_values = [
1604
+ # We always allocate space for at least one digit, even for
1605
+ # a value of zero; sys.getsizeof should reflect that.
1606
+ (0 , 1 ),
1607
+ (1 , 1 ),
1608
+ (- 1 , 1 ),
1609
+ (BASE - 1 , 1 ),
1610
+ (1 - BASE , 1 ),
1611
+ (BASE , 2 ),
1612
+ (- BASE , 2 ),
1613
+ (BASE * BASE - 1 , 2 ),
1614
+ (BASE * BASE , 3 ),
1615
+ ]
1616
+
1617
+ for value , ndigits in test_values :
1618
+ with self .subTest (value ):
1619
+ self .assertEqual (
1620
+ value .__sizeof__ (),
1621
+ int .__basicsize__ + int .__itemsize__ * ndigits
1622
+ )
1623
+
1624
+ # Same test for a subclass of int.
1625
+ class MyInt (int ):
1626
+ pass
1627
+
1628
+ self .assertEqual (MyInt .__itemsize__ , sys .int_info .sizeof_digit )
1629
+
1630
+ for value , ndigits in test_values :
1631
+ with self .subTest (value ):
1632
+ self .assertEqual (
1633
+ MyInt (value ).__sizeof__ (),
1634
+ MyInt .__basicsize__ + MyInt .__itemsize__ * ndigits
1635
+ )
1636
+
1637
+
1599
1638
if __name__ == "__main__" :
1600
1639
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 *
@@ -154,8 +156,8 @@ bool_dealloc(PyObject* Py_UNUSED(ignore))
154
156
PyTypeObject PyBool_Type = {
155
157
PyVarObject_HEAD_INIT (& PyType_Type , 0 )
156
158
"bool" ,
157
- sizeof (struct _longobject ),
158
- 0 ,
159
+ offsetof (struct _longobject , ob_digit ), /* tp_basicsize */
160
+ sizeof ( digit ), /* tp_itemsize */
159
161
bool_dealloc , /* tp_dealloc */
160
162
0 , /* tp_vectorcall_offset */
161
163
0 , /* tp_getattr */
Original file line number Diff line number Diff line change @@ -5664,13 +5664,10 @@ static Py_ssize_t
5664
5664
int___sizeof___impl (PyObject * self )
5665
5665
/*[clinic end generated code: output=3303f008eaa6a0a5 input=9b51620c76fc4507]*/
5666
5666
{
5667
- Py_ssize_t res ;
5668
-
5669
- res = offsetof(PyLongObject , ob_digit )
5670
- /* using Py_MAX(..., 1) because we always allocate space for at least
5671
- one digit, even though the integer zero has a Py_SIZE of 0 */
5672
- + Py_MAX (Py_ABS (Py_SIZE (self )), 1 )* sizeof (digit );
5673
- return res ;
5667
+ /* using Py_MAX(..., 1) because we always allocate space for at least
5668
+ one digit, even though the integer zero has a Py_SIZE of 0 */
5669
+ Py_ssize_t ndigits = Py_MAX (Py_ABS (Py_SIZE (self )), 1 );
5670
+ return Py_TYPE (self )-> tp_basicsize + Py_TYPE (self )-> tp_itemsize * ndigits ;
5674
5671
}
5675
5672
5676
5673
/*[clinic input]
You can’t perform that action at this time.
0 commit comments