@@ -378,6 +378,8 @@ def test_long(self):
378
378
self .assertRaises (ValueError , int , '\u3053 \u3093 \u306b \u3061 \u306f ' )
379
379
380
380
381
+ # TODO: RUSTPYTHON
382
+ @unittest .expectedFailure
381
383
def test_conversion (self ):
382
384
383
385
class JustLong :
@@ -392,7 +394,8 @@ def __long__(self):
392
394
return 42
393
395
def __trunc__ (self ):
394
396
return 1729
395
- self .assertEqual (int (LongTrunc ()), 1729 )
397
+ with self .assertWarns (DeprecationWarning ):
398
+ self .assertEqual (int (LongTrunc ()), 1729 )
396
399
397
400
def check_float_conversion (self , n ):
398
401
# Check that int -> float conversion behaviour matches
@@ -952,8 +955,13 @@ def test_huge_lshift(self, size):
952
955
self .assertEqual (1 << (sys .maxsize + 1000 ), 1 << 1000 << sys .maxsize )
953
956
954
957
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 )
957
965
958
966
@support .cpython_only
959
967
@support .bigmemtest (sys .maxsize + 500 , memuse = 2 / 15 , dry_run = False )
@@ -962,6 +970,64 @@ def test_huge_rshift_of_huge(self, size):
962
970
self .assertEqual (huge >> (sys .maxsize + 1 ), (1 << 499 ) + 5 )
963
971
self .assertEqual (huge >> (sys .maxsize + 1000 ), 0 )
964
972
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
+
965
1031
@support .cpython_only
966
1032
def test_small_ints_in_huge_calculation (self ):
967
1033
a = 2 ** 100
@@ -970,6 +1036,48 @@ def test_small_ints_in_huge_calculation(self):
970
1036
self .assertIs (a + b , 1 )
971
1037
self .assertIs (c - a , 1 )
972
1038
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
+
973
1081
def test_small_ints (self ):
974
1082
for i in range (- 5 , 257 ):
975
1083
self .assertIs (i , i + 0 )
@@ -1111,16 +1219,44 @@ def test_round(self):
1111
1219
1112
1220
def test_to_bytes (self ):
1113
1221
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
+
1114
1229
for test , expected in tests .items ():
1115
1230
try :
1116
1231
self .assertEqual (
1117
1232
test .to_bytes (len (expected ), byteorder , signed = signed ),
1118
1233
expected )
1119
1234
except Exception as err :
1120
1235
raise AssertionError (
1121
- "failed to convert {0 } with byteorder={1 } and signed={2 }"
1236
+ "failed to convert {} with byteorder={} and signed={}"
1122
1237
.format (test , byteorder , signed )) from err
1123
1238
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
+
1124
1260
# Convert integers to signed big-endian byte arrays.
1125
1261
tests1 = {
1126
1262
0 : b'\x00 ' ,
@@ -1208,18 +1344,58 @@ def check(tests, byteorder, signed=False):
1208
1344
b'\xff \xff \xff \xff \xff ' )
1209
1345
self .assertRaises (OverflowError , (1 ).to_bytes , 0 , 'big' )
1210
1346
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
+
1211
1353
# TODO: RUSTPYTHON
1212
1354
@unittest .expectedFailure
1213
1355
def test_from_bytes (self ):
1214
1356
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
+
1215
1369
for test , expected in tests .items ():
1216
1370
try :
1217
1371
self .assertEqual (
1218
1372
int .from_bytes (test , byteorder , signed = signed ),
1219
1373
expected )
1220
1374
except Exception as err :
1221
1375
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}"
1223
1399
.format (test , byteorder , signed )) from err
1224
1400
1225
1401
# Convert signed big-endian byte arrays to integers.
@@ -1360,6 +1536,35 @@ def __init__(self, value):
1360
1536
self .assertEqual (i , 1 )
1361
1537
self .assertEqual (getattr (i , 'foo' , 'none' ), 'bar' )
1362
1538
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
+
1363
1568
def test_access_to_nonexistent_digit_0 (self ):
1364
1569
# http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that
1365
1570
# ob_digit[0] was being incorrectly accessed for instances of a
@@ -1391,6 +1596,17 @@ class myint(int):
1391
1596
self .assertEqual (type (numerator ), int )
1392
1597
self .assertEqual (type (denominator ), int )
1393
1598
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 )
1394
1610
1395
1611
if __name__ == "__main__" :
1396
1612
unittest .main ()
0 commit comments