File tree Expand file tree Collapse file tree 3 files changed +42
-7
lines changed
Misc/NEWS.d/next/Core and Builtins Expand file tree Collapse file tree 3 files changed +42
-7
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 `int ` subclasses.
Original file line number Diff line number Diff line change @@ -5882,13 +5882,8 @@ 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 , 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
+ Py_ssize_t ndigits = Py_MAX (Py_ABS (Py_SIZE (self )), 1 );
5886
+ return Py_TYPE (self )-> tp_basicsize + Py_TYPE (self )-> tp_itemsize * ndigits ;
5892
5887
}
5893
5888
5894
5889
/*[clinic input]
You can’t perform that action at this time.
0 commit comments