@@ -378,6 +378,8 @@ def test_long(self):
378378 self .assertRaises (ValueError , int , '\u3053 \u3093 \u306b \u3061 \u306f ' )
379379
380380
381+ # TODO: RUSTPYTHON
382+ @unittest .expectedFailure
381383 def test_conversion (self ):
382384
383385 class JustLong :
@@ -392,7 +394,8 @@ def __long__(self):
392394 return 42
393395 def __trunc__ (self ):
394396 return 1729
395- self .assertEqual (int (LongTrunc ()), 1729 )
397+ with self .assertWarns (DeprecationWarning ):
398+ self .assertEqual (int (LongTrunc ()), 1729 )
396399
397400 def check_float_conversion (self , n ):
398401 # Check that int -> float conversion behaviour matches
@@ -952,8 +955,13 @@ def test_huge_lshift(self, size):
952955 self .assertEqual (1 << (sys .maxsize + 1000 ), 1 << 1000 << sys .maxsize )
953956
954957 def test_huge_rshift (self ):
955- self .assertEqual (42 >> (1 << 1000 ), 0 )
956- self .assertEqual ((- 42 ) >> (1 << 1000 ), - 1 )
958+ huge_shift = 1 << 1000
959+ self .assertEqual (42 >> huge_shift , 0 )
960+ self .assertEqual ((- 42 ) >> huge_shift , - 1 )
961+ self .assertEqual (1123 >> huge_shift , 0 )
962+ self .assertEqual ((- 1123 ) >> huge_shift , - 1 )
963+ self .assertEqual (2 ** 128 >> huge_shift , 0 )
964+ self .assertEqual (- 2 ** 128 >> huge_shift , - 1 )
957965
958966 @support .cpython_only
959967 @support .bigmemtest (sys .maxsize + 500 , memuse = 2 / 15 , dry_run = False )
@@ -962,6 +970,64 @@ def test_huge_rshift_of_huge(self, size):
962970 self .assertEqual (huge >> (sys .maxsize + 1 ), (1 << 499 ) + 5 )
963971 self .assertEqual (huge >> (sys .maxsize + 1000 ), 0 )
964972
973+ def test_small_rshift (self ):
974+ self .assertEqual (42 >> 1 , 21 )
975+ self .assertEqual ((- 42 ) >> 1 , - 21 )
976+ self .assertEqual (43 >> 1 , 21 )
977+ self .assertEqual ((- 43 ) >> 1 , - 22 )
978+
979+ self .assertEqual (1122 >> 1 , 561 )
980+ self .assertEqual ((- 1122 ) >> 1 , - 561 )
981+ self .assertEqual (1123 >> 1 , 561 )
982+ self .assertEqual ((- 1123 ) >> 1 , - 562 )
983+
984+ self .assertEqual (2 ** 128 >> 1 , 2 ** 127 )
985+ self .assertEqual (- 2 ** 128 >> 1 , - 2 ** 127 )
986+ self .assertEqual ((2 ** 128 + 1 ) >> 1 , 2 ** 127 )
987+ self .assertEqual (- (2 ** 128 + 1 ) >> 1 , - 2 ** 127 - 1 )
988+
989+ def test_medium_rshift (self ):
990+ self .assertEqual (42 >> 9 , 0 )
991+ self .assertEqual ((- 42 ) >> 9 , - 1 )
992+ self .assertEqual (1122 >> 9 , 2 )
993+ self .assertEqual ((- 1122 ) >> 9 , - 3 )
994+ self .assertEqual (2 ** 128 >> 9 , 2 ** 119 )
995+ self .assertEqual (- 2 ** 128 >> 9 , - 2 ** 119 )
996+ # Exercise corner case of the current algorithm, where the result of
997+ # shifting a two-limb int by the limb size still has two limbs.
998+ self .assertEqual ((1 - BASE * BASE ) >> SHIFT , - BASE )
999+ self .assertEqual ((BASE - 1 - BASE * BASE ) >> SHIFT , - BASE )
1000+
1001+ def test_big_rshift (self ):
1002+ self .assertEqual (42 >> 32 , 0 )
1003+ self .assertEqual ((- 42 ) >> 32 , - 1 )
1004+ self .assertEqual (1122 >> 32 , 0 )
1005+ self .assertEqual ((- 1122 ) >> 32 , - 1 )
1006+ self .assertEqual (2 ** 128 >> 32 , 2 ** 96 )
1007+ self .assertEqual (- 2 ** 128 >> 32 , - 2 ** 96 )
1008+
1009+ def test_small_lshift (self ):
1010+ self .assertEqual (42 << 1 , 84 )
1011+ self .assertEqual ((- 42 ) << 1 , - 84 )
1012+ self .assertEqual (561 << 1 , 1122 )
1013+ self .assertEqual ((- 561 ) << 1 , - 1122 )
1014+ self .assertEqual (2 ** 127 << 1 , 2 ** 128 )
1015+ self .assertEqual (- 2 ** 127 << 1 , - 2 ** 128 )
1016+
1017+ def test_medium_lshift (self ):
1018+ self .assertEqual (42 << 9 , 21504 )
1019+ self .assertEqual ((- 42 ) << 9 , - 21504 )
1020+ self .assertEqual (1122 << 9 , 574464 )
1021+ self .assertEqual ((- 1122 ) << 9 , - 574464 )
1022+
1023+ def test_big_lshift (self ):
1024+ self .assertEqual (42 << 32 , 42 * 2 ** 32 )
1025+ self .assertEqual ((- 42 ) << 32 , - 42 * 2 ** 32 )
1026+ self .assertEqual (1122 << 32 , 1122 * 2 ** 32 )
1027+ self .assertEqual ((- 1122 ) << 32 , - 1122 * 2 ** 32 )
1028+ self .assertEqual (2 ** 128 << 32 , 2 ** 160 )
1029+ self .assertEqual (- 2 ** 128 << 32 , - 2 ** 160 )
1030+
9651031 @support .cpython_only
9661032 def test_small_ints_in_huge_calculation (self ):
9671033 a = 2 ** 100
@@ -970,6 +1036,48 @@ def test_small_ints_in_huge_calculation(self):
9701036 self .assertIs (a + b , 1 )
9711037 self .assertIs (c - a , 1 )
9721038
1039+ @support .cpython_only
1040+ def test_pow_uses_cached_small_ints (self ):
1041+ self .assertIs (pow (10 , 3 , 998 ), 2 )
1042+ self .assertIs (10 ** 3 % 998 , 2 )
1043+ a , p , m = 10 , 3 , 998
1044+ self .assertIs (a ** p % m , 2 )
1045+
1046+ self .assertIs (pow (2 , 31 , 2 ** 31 - 1 ), 1 )
1047+ self .assertIs (2 ** 31 % (2 ** 31 - 1 ), 1 )
1048+ a , p , m = 2 , 31 , 2 ** 31 - 1
1049+ self .assertIs (a ** p % m , 1 )
1050+
1051+ self .assertIs (pow (2 , 100 , 2 ** 100 - 3 ), 3 )
1052+ self .assertIs (2 ** 100 % (2 ** 100 - 3 ), 3 )
1053+ a , p , m = 2 , 100 , 2 ** 100 - 3
1054+ self .assertIs (a ** p % m , 3 )
1055+
1056+ @support .cpython_only
1057+ def test_divmod_uses_cached_small_ints (self ):
1058+ big = 10 ** 100
1059+
1060+ self .assertIs ((big + 1 ) % big , 1 )
1061+ self .assertIs ((big + 1 ) // big , 1 )
1062+ self .assertIs (big // (big // 2 ), 2 )
1063+ self .assertIs (big // (big // - 4 ), - 4 )
1064+
1065+ q , r = divmod (2 * big + 3 , big )
1066+ self .assertIs (q , 2 )
1067+ self .assertIs (r , 3 )
1068+
1069+ q , r = divmod (- 4 * big + 100 , big )
1070+ self .assertIs (q , - 4 )
1071+ self .assertIs (r , 100 )
1072+
1073+ q , r = divmod (3 * (- big ) - 1 , - big )
1074+ self .assertIs (q , 3 )
1075+ self .assertIs (r , - 1 )
1076+
1077+ q , r = divmod (3 * big - 1 , - big )
1078+ self .assertIs (q , - 3 )
1079+ self .assertIs (r , - 1 )
1080+
9731081 def test_small_ints (self ):
9741082 for i in range (- 5 , 257 ):
9751083 self .assertIs (i , i + 0 )
@@ -1111,16 +1219,44 @@ def test_round(self):
11111219
11121220 def test_to_bytes (self ):
11131221 def check (tests , byteorder , signed = False ):
1222+ def equivalent_python (n , length , byteorder , signed = False ):
1223+ if byteorder == 'little' :
1224+ order = range (length )
1225+ elif byteorder == 'big' :
1226+ order = reversed (range (length ))
1227+ return bytes ((n >> i * 8 ) & 0xff for i in order )
1228+
11141229 for test , expected in tests .items ():
11151230 try :
11161231 self .assertEqual (
11171232 test .to_bytes (len (expected ), byteorder , signed = signed ),
11181233 expected )
11191234 except Exception as err :
11201235 raise AssertionError (
1121- "failed to convert {0 } with byteorder={1 } and signed={2 }"
1236+ "failed to convert {} with byteorder={} and signed={}"
11221237 .format (test , byteorder , signed )) from err
11231238
1239+ # Test for all default arguments.
1240+ if len (expected ) == 1 and byteorder == 'big' and not signed :
1241+ try :
1242+ self .assertEqual (test .to_bytes (), expected )
1243+ except Exception as err :
1244+ raise AssertionError (
1245+ "failed to convert {} with default arguments"
1246+ .format (test )) from err
1247+
1248+ try :
1249+ self .assertEqual (
1250+ equivalent_python (
1251+ test , len (expected ), byteorder , signed = signed ),
1252+ expected
1253+ )
1254+ except Exception as err :
1255+ raise AssertionError (
1256+ "Code equivalent from docs is not equivalent for "
1257+ "conversion of {0} with byteorder byteorder={1} and "
1258+ "signed={2}" .format (test , byteorder , signed )) from err
1259+
11241260 # Convert integers to signed big-endian byte arrays.
11251261 tests1 = {
11261262 0 : b'\x00 ' ,
@@ -1208,18 +1344,58 @@ def check(tests, byteorder, signed=False):
12081344 b'\xff \xff \xff \xff \xff ' )
12091345 self .assertRaises (OverflowError , (1 ).to_bytes , 0 , 'big' )
12101346
1347+ # gh-98783
1348+ class SubStr (str ):
1349+ pass
1350+ self .assertEqual ((0 ).to_bytes (1 , SubStr ('big' )), b'\x00 ' )
1351+ self .assertEqual ((0 ).to_bytes (0 , SubStr ('little' )), b'' )
1352+
12111353 # TODO: RUSTPYTHON
12121354 @unittest .expectedFailure
12131355 def test_from_bytes (self ):
12141356 def check (tests , byteorder , signed = False ):
1357+ def equivalent_python (byte_array , byteorder , signed = False ):
1358+ if byteorder == 'little' :
1359+ little_ordered = list (byte_array )
1360+ elif byteorder == 'big' :
1361+ little_ordered = list (reversed (byte_array ))
1362+
1363+ n = sum (b << i * 8 for i , b in enumerate (little_ordered ))
1364+ if signed and little_ordered and (little_ordered [- 1 ] & 0x80 ):
1365+ n -= 1 << 8 * len (little_ordered )
1366+
1367+ return n
1368+
12151369 for test , expected in tests .items ():
12161370 try :
12171371 self .assertEqual (
12181372 int .from_bytes (test , byteorder , signed = signed ),
12191373 expected )
12201374 except Exception as err :
12211375 raise AssertionError (
1222- "failed to convert {0} with byteorder={1!r} and signed={2}"
1376+ "failed to convert {} with byteorder={!r} and signed={}"
1377+ .format (test , byteorder , signed )) from err
1378+
1379+ # Test for all default arguments.
1380+ if byteorder == 'big' and not signed :
1381+ try :
1382+ self .assertEqual (
1383+ int .from_bytes (test ),
1384+ expected )
1385+ except Exception as err :
1386+ raise AssertionError (
1387+ "failed to convert {} with default arguments"
1388+ .format (test )) from err
1389+
1390+ try :
1391+ self .assertEqual (
1392+ equivalent_python (test , byteorder , signed = signed ),
1393+ expected
1394+ )
1395+ except Exception as err :
1396+ raise AssertionError (
1397+ "Code equivalent from docs is not equivalent for "
1398+ "conversion of {0} with byteorder={1!r} and signed={2}"
12231399 .format (test , byteorder , signed )) from err
12241400
12251401 # Convert signed big-endian byte arrays to integers.
@@ -1360,6 +1536,35 @@ def __init__(self, value):
13601536 self .assertEqual (i , 1 )
13611537 self .assertEqual (getattr (i , 'foo' , 'none' ), 'bar' )
13621538
1539+ class ValidBytes :
1540+ def __bytes__ (self ):
1541+ return b'\x01 '
1542+ class InvalidBytes :
1543+ def __bytes__ (self ):
1544+ return 'abc'
1545+ class MissingBytes : ...
1546+ class RaisingBytes :
1547+ def __bytes__ (self ):
1548+ 1 / 0
1549+
1550+ self .assertEqual (int .from_bytes (ValidBytes ()), 1 )
1551+ self .assertRaises (TypeError , int .from_bytes , InvalidBytes ())
1552+ self .assertRaises (TypeError , int .from_bytes , MissingBytes ())
1553+ self .assertRaises (ZeroDivisionError , int .from_bytes , RaisingBytes ())
1554+
1555+ # gh-98783
1556+ class SubStr (str ):
1557+ pass
1558+ self .assertEqual (int .from_bytes (b'' , SubStr ('big' )), 0 )
1559+ self .assertEqual (int .from_bytes (b'\x00 ' , SubStr ('little' )), 0 )
1560+
1561+ @support .cpython_only
1562+ def test_from_bytes_small (self ):
1563+ # bpo-46361
1564+ for i in range (- 5 , 257 ):
1565+ b = i .to_bytes (2 , signed = True )
1566+ self .assertIs (int .from_bytes (b , signed = True ), i )
1567+
13631568 def test_access_to_nonexistent_digit_0 (self ):
13641569 # http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that
13651570 # ob_digit[0] was being incorrectly accessed for instances of a
@@ -1391,6 +1596,17 @@ class myint(int):
13911596 self .assertEqual (type (numerator ), int )
13921597 self .assertEqual (type (denominator ), int )
13931598
1599+ def test_square (self ):
1600+ # Multiplication makes a special case of multiplying an int with
1601+ # itself, using a special, faster algorithm. This test is mostly
1602+ # to ensure that no asserts in the implementation trigger, in
1603+ # cases with a maximal amount of carries.
1604+ for bitlen in range (1 , 400 ):
1605+ n = (1 << bitlen ) - 1 # solid string of 1 bits
1606+ with self .subTest (bitlen = bitlen , n = n ):
1607+ # (2**i - 1)**2 = 2**(2*i) - 2*2**i + 1
1608+ self .assertEqual (n ** 2 ,
1609+ (1 << (2 * bitlen )) - (1 << (bitlen + 1 )) + 1 )
13941610
13951611if __name__ == "__main__" :
13961612 unittest .main ()
0 commit comments