17db96d56Sopenharmony_ciimport sys 27db96d56Sopenharmony_ciimport time 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ciimport unittest 57db96d56Sopenharmony_cifrom test import support 67db96d56Sopenharmony_cifrom test.test_grammar import (VALID_UNDERSCORE_LITERALS, 77db96d56Sopenharmony_ci INVALID_UNDERSCORE_LITERALS) 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ciL = [ 107db96d56Sopenharmony_ci ('0', 0), 117db96d56Sopenharmony_ci ('1', 1), 127db96d56Sopenharmony_ci ('9', 9), 137db96d56Sopenharmony_ci ('10', 10), 147db96d56Sopenharmony_ci ('99', 99), 157db96d56Sopenharmony_ci ('100', 100), 167db96d56Sopenharmony_ci ('314', 314), 177db96d56Sopenharmony_ci (' 314', 314), 187db96d56Sopenharmony_ci ('314 ', 314), 197db96d56Sopenharmony_ci (' \t\t 314 \t\t ', 314), 207db96d56Sopenharmony_ci (repr(sys.maxsize), sys.maxsize), 217db96d56Sopenharmony_ci (' 1x', ValueError), 227db96d56Sopenharmony_ci (' 1 ', 1), 237db96d56Sopenharmony_ci (' 1\02 ', ValueError), 247db96d56Sopenharmony_ci ('', ValueError), 257db96d56Sopenharmony_ci (' ', ValueError), 267db96d56Sopenharmony_ci (' \t\t ', ValueError), 277db96d56Sopenharmony_ci ("\u0200", ValueError) 287db96d56Sopenharmony_ci] 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ciclass IntSubclass(int): 317db96d56Sopenharmony_ci pass 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ciclass IntTestCases(unittest.TestCase): 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci def test_basic(self): 367db96d56Sopenharmony_ci self.assertEqual(int(314), 314) 377db96d56Sopenharmony_ci self.assertEqual(int(3.14), 3) 387db96d56Sopenharmony_ci # Check that conversion from float truncates towards zero 397db96d56Sopenharmony_ci self.assertEqual(int(-3.14), -3) 407db96d56Sopenharmony_ci self.assertEqual(int(3.9), 3) 417db96d56Sopenharmony_ci self.assertEqual(int(-3.9), -3) 427db96d56Sopenharmony_ci self.assertEqual(int(3.5), 3) 437db96d56Sopenharmony_ci self.assertEqual(int(-3.5), -3) 447db96d56Sopenharmony_ci self.assertEqual(int("-3"), -3) 457db96d56Sopenharmony_ci self.assertEqual(int(" -3 "), -3) 467db96d56Sopenharmony_ci self.assertEqual(int("\N{EM SPACE}-3\N{EN SPACE}"), -3) 477db96d56Sopenharmony_ci # Different base: 487db96d56Sopenharmony_ci self.assertEqual(int("10",16), 16) 497db96d56Sopenharmony_ci # Test conversion from strings and various anomalies 507db96d56Sopenharmony_ci for s, v in L: 517db96d56Sopenharmony_ci for sign in "", "+", "-": 527db96d56Sopenharmony_ci for prefix in "", " ", "\t", " \t\t ": 537db96d56Sopenharmony_ci ss = prefix + sign + s 547db96d56Sopenharmony_ci vv = v 557db96d56Sopenharmony_ci if sign == "-" and v is not ValueError: 567db96d56Sopenharmony_ci vv = -v 577db96d56Sopenharmony_ci try: 587db96d56Sopenharmony_ci self.assertEqual(int(ss), vv) 597db96d56Sopenharmony_ci except ValueError: 607db96d56Sopenharmony_ci pass 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci s = repr(-1-sys.maxsize) 637db96d56Sopenharmony_ci x = int(s) 647db96d56Sopenharmony_ci self.assertEqual(x+1, -sys.maxsize) 657db96d56Sopenharmony_ci self.assertIsInstance(x, int) 667db96d56Sopenharmony_ci # should return int 677db96d56Sopenharmony_ci self.assertEqual(int(s[1:]), sys.maxsize+1) 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci # should return int 707db96d56Sopenharmony_ci x = int(1e100) 717db96d56Sopenharmony_ci self.assertIsInstance(x, int) 727db96d56Sopenharmony_ci x = int(-1e100) 737db96d56Sopenharmony_ci self.assertIsInstance(x, int) 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci # SF bug 434186: 0x80000000/2 != 0x80000000>>1. 777db96d56Sopenharmony_ci # Worked by accident in Windows release build, but failed in debug build. 787db96d56Sopenharmony_ci # Failed in all Linux builds. 797db96d56Sopenharmony_ci x = -1-sys.maxsize 807db96d56Sopenharmony_ci self.assertEqual(x >> 1, x//2) 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci x = int('1' * 600) 837db96d56Sopenharmony_ci self.assertIsInstance(x, int) 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci self.assertRaises(TypeError, int, 1, 12) 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci self.assertEqual(int('0o123', 0), 83) 897db96d56Sopenharmony_ci self.assertEqual(int('0x123', 16), 291) 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci # Bug 1679: "0x" is not a valid hex literal 927db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "0x", 16) 937db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "0x", 0) 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "0o", 8) 967db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "0o", 0) 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "0b", 2) 997db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "0b", 0) 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci # SF bug 1334662: int(string, base) wrong answers 1027db96d56Sopenharmony_ci # Various representations of 2**32 evaluated to 0 1037db96d56Sopenharmony_ci # rather than 2**32 in previous versions 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296) 1067db96d56Sopenharmony_ci self.assertEqual(int('102002022201221111211', 3), 4294967296) 1077db96d56Sopenharmony_ci self.assertEqual(int('10000000000000000', 4), 4294967296) 1087db96d56Sopenharmony_ci self.assertEqual(int('32244002423141', 5), 4294967296) 1097db96d56Sopenharmony_ci self.assertEqual(int('1550104015504', 6), 4294967296) 1107db96d56Sopenharmony_ci self.assertEqual(int('211301422354', 7), 4294967296) 1117db96d56Sopenharmony_ci self.assertEqual(int('40000000000', 8), 4294967296) 1127db96d56Sopenharmony_ci self.assertEqual(int('12068657454', 9), 4294967296) 1137db96d56Sopenharmony_ci self.assertEqual(int('4294967296', 10), 4294967296) 1147db96d56Sopenharmony_ci self.assertEqual(int('1904440554', 11), 4294967296) 1157db96d56Sopenharmony_ci self.assertEqual(int('9ba461594', 12), 4294967296) 1167db96d56Sopenharmony_ci self.assertEqual(int('535a79889', 13), 4294967296) 1177db96d56Sopenharmony_ci self.assertEqual(int('2ca5b7464', 14), 4294967296) 1187db96d56Sopenharmony_ci self.assertEqual(int('1a20dcd81', 15), 4294967296) 1197db96d56Sopenharmony_ci self.assertEqual(int('100000000', 16), 4294967296) 1207db96d56Sopenharmony_ci self.assertEqual(int('a7ffda91', 17), 4294967296) 1217db96d56Sopenharmony_ci self.assertEqual(int('704he7g4', 18), 4294967296) 1227db96d56Sopenharmony_ci self.assertEqual(int('4f5aff66', 19), 4294967296) 1237db96d56Sopenharmony_ci self.assertEqual(int('3723ai4g', 20), 4294967296) 1247db96d56Sopenharmony_ci self.assertEqual(int('281d55i4', 21), 4294967296) 1257db96d56Sopenharmony_ci self.assertEqual(int('1fj8b184', 22), 4294967296) 1267db96d56Sopenharmony_ci self.assertEqual(int('1606k7ic', 23), 4294967296) 1277db96d56Sopenharmony_ci self.assertEqual(int('mb994ag', 24), 4294967296) 1287db96d56Sopenharmony_ci self.assertEqual(int('hek2mgl', 25), 4294967296) 1297db96d56Sopenharmony_ci self.assertEqual(int('dnchbnm', 26), 4294967296) 1307db96d56Sopenharmony_ci self.assertEqual(int('b28jpdm', 27), 4294967296) 1317db96d56Sopenharmony_ci self.assertEqual(int('8pfgih4', 28), 4294967296) 1327db96d56Sopenharmony_ci self.assertEqual(int('76beigg', 29), 4294967296) 1337db96d56Sopenharmony_ci self.assertEqual(int('5qmcpqg', 30), 4294967296) 1347db96d56Sopenharmony_ci self.assertEqual(int('4q0jto4', 31), 4294967296) 1357db96d56Sopenharmony_ci self.assertEqual(int('4000000', 32), 4294967296) 1367db96d56Sopenharmony_ci self.assertEqual(int('3aokq94', 33), 4294967296) 1377db96d56Sopenharmony_ci self.assertEqual(int('2qhxjli', 34), 4294967296) 1387db96d56Sopenharmony_ci self.assertEqual(int('2br45qb', 35), 4294967296) 1397db96d56Sopenharmony_ci self.assertEqual(int('1z141z4', 36), 4294967296) 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ci # tests with base 0 1427db96d56Sopenharmony_ci # this fails on 3.0, but in 2.x the old octal syntax is allowed 1437db96d56Sopenharmony_ci self.assertEqual(int(' 0o123 ', 0), 83) 1447db96d56Sopenharmony_ci self.assertEqual(int(' 0o123 ', 0), 83) 1457db96d56Sopenharmony_ci self.assertEqual(int('000', 0), 0) 1467db96d56Sopenharmony_ci self.assertEqual(int('0o123', 0), 83) 1477db96d56Sopenharmony_ci self.assertEqual(int('0x123', 0), 291) 1487db96d56Sopenharmony_ci self.assertEqual(int('0b100', 0), 4) 1497db96d56Sopenharmony_ci self.assertEqual(int(' 0O123 ', 0), 83) 1507db96d56Sopenharmony_ci self.assertEqual(int(' 0X123 ', 0), 291) 1517db96d56Sopenharmony_ci self.assertEqual(int(' 0B100 ', 0), 4) 1527db96d56Sopenharmony_ci with self.assertRaises(ValueError): 1537db96d56Sopenharmony_ci int('010', 0) 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ci # without base still base 10 1567db96d56Sopenharmony_ci self.assertEqual(int('0123'), 123) 1577db96d56Sopenharmony_ci self.assertEqual(int('0123', 10), 123) 1587db96d56Sopenharmony_ci 1597db96d56Sopenharmony_ci # tests with prefix and base != 0 1607db96d56Sopenharmony_ci self.assertEqual(int('0x123', 16), 291) 1617db96d56Sopenharmony_ci self.assertEqual(int('0o123', 8), 83) 1627db96d56Sopenharmony_ci self.assertEqual(int('0b100', 2), 4) 1637db96d56Sopenharmony_ci self.assertEqual(int('0X123', 16), 291) 1647db96d56Sopenharmony_ci self.assertEqual(int('0O123', 8), 83) 1657db96d56Sopenharmony_ci self.assertEqual(int('0B100', 2), 4) 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci # the code has special checks for the first character after the 1687db96d56Sopenharmony_ci # type prefix 1697db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0b2', 2) 1707db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0b02', 2) 1717db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0B2', 2) 1727db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0B02', 2) 1737db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0o8', 8) 1747db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0o08', 8) 1757db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0O8', 8) 1767db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0O08', 8) 1777db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0xg', 16) 1787db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0x0g', 16) 1797db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0Xg', 16) 1807db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '0X0g', 16) 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ci # SF bug 1334662: int(string, base) wrong answers 1837db96d56Sopenharmony_ci # Checks for proper evaluation of 2**32 + 1 1847db96d56Sopenharmony_ci self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297) 1857db96d56Sopenharmony_ci self.assertEqual(int('102002022201221111212', 3), 4294967297) 1867db96d56Sopenharmony_ci self.assertEqual(int('10000000000000001', 4), 4294967297) 1877db96d56Sopenharmony_ci self.assertEqual(int('32244002423142', 5), 4294967297) 1887db96d56Sopenharmony_ci self.assertEqual(int('1550104015505', 6), 4294967297) 1897db96d56Sopenharmony_ci self.assertEqual(int('211301422355', 7), 4294967297) 1907db96d56Sopenharmony_ci self.assertEqual(int('40000000001', 8), 4294967297) 1917db96d56Sopenharmony_ci self.assertEqual(int('12068657455', 9), 4294967297) 1927db96d56Sopenharmony_ci self.assertEqual(int('4294967297', 10), 4294967297) 1937db96d56Sopenharmony_ci self.assertEqual(int('1904440555', 11), 4294967297) 1947db96d56Sopenharmony_ci self.assertEqual(int('9ba461595', 12), 4294967297) 1957db96d56Sopenharmony_ci self.assertEqual(int('535a7988a', 13), 4294967297) 1967db96d56Sopenharmony_ci self.assertEqual(int('2ca5b7465', 14), 4294967297) 1977db96d56Sopenharmony_ci self.assertEqual(int('1a20dcd82', 15), 4294967297) 1987db96d56Sopenharmony_ci self.assertEqual(int('100000001', 16), 4294967297) 1997db96d56Sopenharmony_ci self.assertEqual(int('a7ffda92', 17), 4294967297) 2007db96d56Sopenharmony_ci self.assertEqual(int('704he7g5', 18), 4294967297) 2017db96d56Sopenharmony_ci self.assertEqual(int('4f5aff67', 19), 4294967297) 2027db96d56Sopenharmony_ci self.assertEqual(int('3723ai4h', 20), 4294967297) 2037db96d56Sopenharmony_ci self.assertEqual(int('281d55i5', 21), 4294967297) 2047db96d56Sopenharmony_ci self.assertEqual(int('1fj8b185', 22), 4294967297) 2057db96d56Sopenharmony_ci self.assertEqual(int('1606k7id', 23), 4294967297) 2067db96d56Sopenharmony_ci self.assertEqual(int('mb994ah', 24), 4294967297) 2077db96d56Sopenharmony_ci self.assertEqual(int('hek2mgm', 25), 4294967297) 2087db96d56Sopenharmony_ci self.assertEqual(int('dnchbnn', 26), 4294967297) 2097db96d56Sopenharmony_ci self.assertEqual(int('b28jpdn', 27), 4294967297) 2107db96d56Sopenharmony_ci self.assertEqual(int('8pfgih5', 28), 4294967297) 2117db96d56Sopenharmony_ci self.assertEqual(int('76beigh', 29), 4294967297) 2127db96d56Sopenharmony_ci self.assertEqual(int('5qmcpqh', 30), 4294967297) 2137db96d56Sopenharmony_ci self.assertEqual(int('4q0jto5', 31), 4294967297) 2147db96d56Sopenharmony_ci self.assertEqual(int('4000001', 32), 4294967297) 2157db96d56Sopenharmony_ci self.assertEqual(int('3aokq95', 33), 4294967297) 2167db96d56Sopenharmony_ci self.assertEqual(int('2qhxjlj', 34), 4294967297) 2177db96d56Sopenharmony_ci self.assertEqual(int('2br45qc', 35), 4294967297) 2187db96d56Sopenharmony_ci self.assertEqual(int('1z141z5', 36), 4294967297) 2197db96d56Sopenharmony_ci 2207db96d56Sopenharmony_ci def test_invalid_signs(self): 2217db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2227db96d56Sopenharmony_ci int('+') 2237db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2247db96d56Sopenharmony_ci int('-') 2257db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2267db96d56Sopenharmony_ci int('- 1') 2277db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2287db96d56Sopenharmony_ci int('+ 1') 2297db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2307db96d56Sopenharmony_ci int(' + 1 ') 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci def test_unicode(self): 2337db96d56Sopenharmony_ci self.assertEqual(int("१२३४५६७८९०1234567890"), 12345678901234567890) 2347db96d56Sopenharmony_ci self.assertEqual(int('١٢٣٤٥٦٧٨٩٠'), 1234567890) 2357db96d56Sopenharmony_ci self.assertEqual(int("१२३४५६७८९०1234567890", 0), 12345678901234567890) 2367db96d56Sopenharmony_ci self.assertEqual(int('١٢٣٤٥٦٧٨٩٠', 0), 1234567890) 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ci def test_underscores(self): 2397db96d56Sopenharmony_ci for lit in VALID_UNDERSCORE_LITERALS: 2407db96d56Sopenharmony_ci if any(ch in lit for ch in '.eEjJ'): 2417db96d56Sopenharmony_ci continue 2427db96d56Sopenharmony_ci self.assertEqual(int(lit, 0), eval(lit)) 2437db96d56Sopenharmony_ci self.assertEqual(int(lit, 0), int(lit.replace('_', ''), 0)) 2447db96d56Sopenharmony_ci for lit in INVALID_UNDERSCORE_LITERALS: 2457db96d56Sopenharmony_ci if any(ch in lit for ch in '.eEjJ'): 2467db96d56Sopenharmony_ci continue 2477db96d56Sopenharmony_ci self.assertRaises(ValueError, int, lit, 0) 2487db96d56Sopenharmony_ci # Additional test cases with bases != 0, only for the constructor: 2497db96d56Sopenharmony_ci self.assertEqual(int("1_00", 3), 9) 2507db96d56Sopenharmony_ci self.assertEqual(int("0_100"), 100) # not valid as a literal! 2517db96d56Sopenharmony_ci self.assertEqual(int(b"1_00"), 100) # byte underscore 2527db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "_100") 2537db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "+_100") 2547db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "1__00") 2557db96d56Sopenharmony_ci self.assertRaises(ValueError, int, "100_") 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci @support.cpython_only 2587db96d56Sopenharmony_ci def test_small_ints(self): 2597db96d56Sopenharmony_ci # Bug #3236: Return small longs from PyLong_FromString 2607db96d56Sopenharmony_ci self.assertIs(int('10'), 10) 2617db96d56Sopenharmony_ci self.assertIs(int('-1'), -1) 2627db96d56Sopenharmony_ci self.assertIs(int(b'10'), 10) 2637db96d56Sopenharmony_ci self.assertIs(int(b'-1'), -1) 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci def test_no_args(self): 2667db96d56Sopenharmony_ci self.assertEqual(int(), 0) 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ci def test_keyword_args(self): 2697db96d56Sopenharmony_ci # Test invoking int() using keyword arguments. 2707db96d56Sopenharmony_ci self.assertEqual(int('100', base=2), 4) 2717db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'keyword argument'): 2727db96d56Sopenharmony_ci int(x=1.2) 2737db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'keyword argument'): 2747db96d56Sopenharmony_ci int(x='100', base=2) 2757db96d56Sopenharmony_ci self.assertRaises(TypeError, int, base=10) 2767db96d56Sopenharmony_ci self.assertRaises(TypeError, int, base=0) 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_ci def test_int_base_limits(self): 2797db96d56Sopenharmony_ci """Testing the supported limits of the int() base parameter.""" 2807db96d56Sopenharmony_ci self.assertEqual(int('0', 5), 0) 2817db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2827db96d56Sopenharmony_ci int('0', 1) 2837db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2847db96d56Sopenharmony_ci int('0', 37) 2857db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2867db96d56Sopenharmony_ci int('0', -909) # An old magic value base from Python 2. 2877db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2887db96d56Sopenharmony_ci int('0', base=0-(2**234)) 2897db96d56Sopenharmony_ci with self.assertRaises(ValueError): 2907db96d56Sopenharmony_ci int('0', base=2**234) 2917db96d56Sopenharmony_ci # Bases 2 through 36 are supported. 2927db96d56Sopenharmony_ci for base in range(2,37): 2937db96d56Sopenharmony_ci self.assertEqual(int('0', base=base), 0) 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ci def test_int_base_bad_types(self): 2967db96d56Sopenharmony_ci """Not integer types are not valid bases; issue16772.""" 2977db96d56Sopenharmony_ci with self.assertRaises(TypeError): 2987db96d56Sopenharmony_ci int('0', 5.5) 2997db96d56Sopenharmony_ci with self.assertRaises(TypeError): 3007db96d56Sopenharmony_ci int('0', 5.0) 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ci def test_int_base_indexable(self): 3037db96d56Sopenharmony_ci class MyIndexable(object): 3047db96d56Sopenharmony_ci def __init__(self, value): 3057db96d56Sopenharmony_ci self.value = value 3067db96d56Sopenharmony_ci def __index__(self): 3077db96d56Sopenharmony_ci return self.value 3087db96d56Sopenharmony_ci 3097db96d56Sopenharmony_ci # Check out of range bases. 3107db96d56Sopenharmony_ci for base in 2**100, -2**100, 1, 37: 3117db96d56Sopenharmony_ci with self.assertRaises(ValueError): 3127db96d56Sopenharmony_ci int('43', base) 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_ci # Check in-range bases. 3157db96d56Sopenharmony_ci self.assertEqual(int('101', base=MyIndexable(2)), 5) 3167db96d56Sopenharmony_ci self.assertEqual(int('101', base=MyIndexable(10)), 101) 3177db96d56Sopenharmony_ci self.assertEqual(int('101', base=MyIndexable(36)), 1 + 36**2) 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_ci def test_non_numeric_input_types(self): 3207db96d56Sopenharmony_ci # Test possible non-numeric types for the argument x, including 3217db96d56Sopenharmony_ci # subclasses of the explicitly documented accepted types. 3227db96d56Sopenharmony_ci class CustomStr(str): pass 3237db96d56Sopenharmony_ci class CustomBytes(bytes): pass 3247db96d56Sopenharmony_ci class CustomByteArray(bytearray): pass 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci factories = [ 3277db96d56Sopenharmony_ci bytes, 3287db96d56Sopenharmony_ci bytearray, 3297db96d56Sopenharmony_ci lambda b: CustomStr(b.decode()), 3307db96d56Sopenharmony_ci CustomBytes, 3317db96d56Sopenharmony_ci CustomByteArray, 3327db96d56Sopenharmony_ci memoryview, 3337db96d56Sopenharmony_ci ] 3347db96d56Sopenharmony_ci try: 3357db96d56Sopenharmony_ci from array import array 3367db96d56Sopenharmony_ci except ImportError: 3377db96d56Sopenharmony_ci pass 3387db96d56Sopenharmony_ci else: 3397db96d56Sopenharmony_ci factories.append(lambda b: array('B', b)) 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_ci for f in factories: 3427db96d56Sopenharmony_ci x = f(b'100') 3437db96d56Sopenharmony_ci with self.subTest(type(x)): 3447db96d56Sopenharmony_ci self.assertEqual(int(x), 100) 3457db96d56Sopenharmony_ci if isinstance(x, (str, bytes, bytearray)): 3467db96d56Sopenharmony_ci self.assertEqual(int(x, 2), 4) 3477db96d56Sopenharmony_ci else: 3487db96d56Sopenharmony_ci msg = "can't convert non-string" 3497db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, msg): 3507db96d56Sopenharmony_ci int(x, 2) 3517db96d56Sopenharmony_ci with self.assertRaisesRegex(ValueError, 'invalid literal'): 3527db96d56Sopenharmony_ci int(f(b'A' * 0x10)) 3537db96d56Sopenharmony_ci 3547db96d56Sopenharmony_ci def test_int_memoryview(self): 3557db96d56Sopenharmony_ci self.assertEqual(int(memoryview(b'123')[1:3]), 23) 3567db96d56Sopenharmony_ci self.assertEqual(int(memoryview(b'123\x00')[1:3]), 23) 3577db96d56Sopenharmony_ci self.assertEqual(int(memoryview(b'123 ')[1:3]), 23) 3587db96d56Sopenharmony_ci self.assertEqual(int(memoryview(b'123A')[1:3]), 23) 3597db96d56Sopenharmony_ci self.assertEqual(int(memoryview(b'1234')[1:3]), 23) 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci def test_string_float(self): 3627db96d56Sopenharmony_ci self.assertRaises(ValueError, int, '1.2') 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci def test_intconversion(self): 3657db96d56Sopenharmony_ci # Test __int__() 3667db96d56Sopenharmony_ci class ClassicMissingMethods: 3677db96d56Sopenharmony_ci pass 3687db96d56Sopenharmony_ci self.assertRaises(TypeError, int, ClassicMissingMethods()) 3697db96d56Sopenharmony_ci 3707db96d56Sopenharmony_ci class MissingMethods(object): 3717db96d56Sopenharmony_ci pass 3727db96d56Sopenharmony_ci self.assertRaises(TypeError, int, MissingMethods()) 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ci class Foo0: 3757db96d56Sopenharmony_ci def __int__(self): 3767db96d56Sopenharmony_ci return 42 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ci self.assertEqual(int(Foo0()), 42) 3797db96d56Sopenharmony_ci 3807db96d56Sopenharmony_ci class Classic: 3817db96d56Sopenharmony_ci pass 3827db96d56Sopenharmony_ci for base in (object, Classic): 3837db96d56Sopenharmony_ci class IntOverridesTrunc(base): 3847db96d56Sopenharmony_ci def __int__(self): 3857db96d56Sopenharmony_ci return 42 3867db96d56Sopenharmony_ci def __trunc__(self): 3877db96d56Sopenharmony_ci return -12 3887db96d56Sopenharmony_ci self.assertEqual(int(IntOverridesTrunc()), 42) 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_ci class JustTrunc(base): 3917db96d56Sopenharmony_ci def __trunc__(self): 3927db96d56Sopenharmony_ci return 42 3937db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 3947db96d56Sopenharmony_ci self.assertEqual(int(JustTrunc()), 42) 3957db96d56Sopenharmony_ci 3967db96d56Sopenharmony_ci class ExceptionalTrunc(base): 3977db96d56Sopenharmony_ci def __trunc__(self): 3987db96d56Sopenharmony_ci 1 / 0 3997db96d56Sopenharmony_ci with self.assertRaises(ZeroDivisionError), \ 4007db96d56Sopenharmony_ci self.assertWarns(DeprecationWarning): 4017db96d56Sopenharmony_ci int(ExceptionalTrunc()) 4027db96d56Sopenharmony_ci 4037db96d56Sopenharmony_ci for trunc_result_base in (object, Classic): 4047db96d56Sopenharmony_ci class Index(trunc_result_base): 4057db96d56Sopenharmony_ci def __index__(self): 4067db96d56Sopenharmony_ci return 42 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci class TruncReturnsNonInt(base): 4097db96d56Sopenharmony_ci def __trunc__(self): 4107db96d56Sopenharmony_ci return Index() 4117db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 4127db96d56Sopenharmony_ci self.assertEqual(int(TruncReturnsNonInt()), 42) 4137db96d56Sopenharmony_ci 4147db96d56Sopenharmony_ci class Intable(trunc_result_base): 4157db96d56Sopenharmony_ci def __int__(self): 4167db96d56Sopenharmony_ci return 42 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_ci class TruncReturnsNonIndex(base): 4197db96d56Sopenharmony_ci def __trunc__(self): 4207db96d56Sopenharmony_ci return Intable() 4217db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 4227db96d56Sopenharmony_ci self.assertEqual(int(TruncReturnsNonInt()), 42) 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci class NonIntegral(trunc_result_base): 4257db96d56Sopenharmony_ci def __trunc__(self): 4267db96d56Sopenharmony_ci # Check that we avoid infinite recursion. 4277db96d56Sopenharmony_ci return NonIntegral() 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ci class TruncReturnsNonIntegral(base): 4307db96d56Sopenharmony_ci def __trunc__(self): 4317db96d56Sopenharmony_ci return NonIntegral() 4327db96d56Sopenharmony_ci try: 4337db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 4347db96d56Sopenharmony_ci int(TruncReturnsNonIntegral()) 4357db96d56Sopenharmony_ci except TypeError as e: 4367db96d56Sopenharmony_ci self.assertEqual(str(e), 4377db96d56Sopenharmony_ci "__trunc__ returned non-Integral" 4387db96d56Sopenharmony_ci " (type NonIntegral)") 4397db96d56Sopenharmony_ci else: 4407db96d56Sopenharmony_ci self.fail("Failed to raise TypeError with %s" % 4417db96d56Sopenharmony_ci ((base, trunc_result_base),)) 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci # Regression test for bugs.python.org/issue16060. 4447db96d56Sopenharmony_ci class BadInt(trunc_result_base): 4457db96d56Sopenharmony_ci def __int__(self): 4467db96d56Sopenharmony_ci return 42.0 4477db96d56Sopenharmony_ci 4487db96d56Sopenharmony_ci class TruncReturnsBadInt(base): 4497db96d56Sopenharmony_ci def __trunc__(self): 4507db96d56Sopenharmony_ci return BadInt() 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci with self.assertRaises(TypeError), \ 4537db96d56Sopenharmony_ci self.assertWarns(DeprecationWarning): 4547db96d56Sopenharmony_ci int(TruncReturnsBadInt()) 4557db96d56Sopenharmony_ci 4567db96d56Sopenharmony_ci def test_int_subclass_with_index(self): 4577db96d56Sopenharmony_ci class MyIndex(int): 4587db96d56Sopenharmony_ci def __index__(self): 4597db96d56Sopenharmony_ci return 42 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_ci class BadIndex(int): 4627db96d56Sopenharmony_ci def __index__(self): 4637db96d56Sopenharmony_ci return 42.0 4647db96d56Sopenharmony_ci 4657db96d56Sopenharmony_ci my_int = MyIndex(7) 4667db96d56Sopenharmony_ci self.assertEqual(my_int, 7) 4677db96d56Sopenharmony_ci self.assertEqual(int(my_int), 7) 4687db96d56Sopenharmony_ci 4697db96d56Sopenharmony_ci self.assertEqual(int(BadIndex()), 0) 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci def test_int_subclass_with_int(self): 4727db96d56Sopenharmony_ci class MyInt(int): 4737db96d56Sopenharmony_ci def __int__(self): 4747db96d56Sopenharmony_ci return 42 4757db96d56Sopenharmony_ci 4767db96d56Sopenharmony_ci class BadInt(int): 4777db96d56Sopenharmony_ci def __int__(self): 4787db96d56Sopenharmony_ci return 42.0 4797db96d56Sopenharmony_ci 4807db96d56Sopenharmony_ci my_int = MyInt(7) 4817db96d56Sopenharmony_ci self.assertEqual(my_int, 7) 4827db96d56Sopenharmony_ci self.assertEqual(int(my_int), 42) 4837db96d56Sopenharmony_ci 4847db96d56Sopenharmony_ci my_int = BadInt(7) 4857db96d56Sopenharmony_ci self.assertEqual(my_int, 7) 4867db96d56Sopenharmony_ci self.assertRaises(TypeError, int, my_int) 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_ci def test_int_returns_int_subclass(self): 4897db96d56Sopenharmony_ci class BadIndex: 4907db96d56Sopenharmony_ci def __index__(self): 4917db96d56Sopenharmony_ci return True 4927db96d56Sopenharmony_ci 4937db96d56Sopenharmony_ci class BadIndex2(int): 4947db96d56Sopenharmony_ci def __index__(self): 4957db96d56Sopenharmony_ci return True 4967db96d56Sopenharmony_ci 4977db96d56Sopenharmony_ci class BadInt: 4987db96d56Sopenharmony_ci def __int__(self): 4997db96d56Sopenharmony_ci return True 5007db96d56Sopenharmony_ci 5017db96d56Sopenharmony_ci class BadInt2(int): 5027db96d56Sopenharmony_ci def __int__(self): 5037db96d56Sopenharmony_ci return True 5047db96d56Sopenharmony_ci 5057db96d56Sopenharmony_ci class TruncReturnsBadIndex: 5067db96d56Sopenharmony_ci def __trunc__(self): 5077db96d56Sopenharmony_ci return BadIndex() 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_ci class TruncReturnsBadInt: 5107db96d56Sopenharmony_ci def __trunc__(self): 5117db96d56Sopenharmony_ci return BadInt() 5127db96d56Sopenharmony_ci 5137db96d56Sopenharmony_ci class TruncReturnsIntSubclass: 5147db96d56Sopenharmony_ci def __trunc__(self): 5157db96d56Sopenharmony_ci return True 5167db96d56Sopenharmony_ci 5177db96d56Sopenharmony_ci bad_int = BadIndex() 5187db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 5197db96d56Sopenharmony_ci n = int(bad_int) 5207db96d56Sopenharmony_ci self.assertEqual(n, 1) 5217db96d56Sopenharmony_ci self.assertIs(type(n), int) 5227db96d56Sopenharmony_ci 5237db96d56Sopenharmony_ci bad_int = BadIndex2() 5247db96d56Sopenharmony_ci n = int(bad_int) 5257db96d56Sopenharmony_ci self.assertEqual(n, 0) 5267db96d56Sopenharmony_ci self.assertIs(type(n), int) 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_ci bad_int = BadInt() 5297db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 5307db96d56Sopenharmony_ci n = int(bad_int) 5317db96d56Sopenharmony_ci self.assertEqual(n, 1) 5327db96d56Sopenharmony_ci self.assertIs(type(n), int) 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_ci bad_int = BadInt2() 5357db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 5367db96d56Sopenharmony_ci n = int(bad_int) 5377db96d56Sopenharmony_ci self.assertEqual(n, 1) 5387db96d56Sopenharmony_ci self.assertIs(type(n), int) 5397db96d56Sopenharmony_ci 5407db96d56Sopenharmony_ci bad_int = TruncReturnsBadIndex() 5417db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 5427db96d56Sopenharmony_ci n = int(bad_int) 5437db96d56Sopenharmony_ci self.assertEqual(n, 1) 5447db96d56Sopenharmony_ci self.assertIs(type(n), int) 5457db96d56Sopenharmony_ci 5467db96d56Sopenharmony_ci bad_int = TruncReturnsBadInt() 5477db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 5487db96d56Sopenharmony_ci self.assertRaises(TypeError, int, bad_int) 5497db96d56Sopenharmony_ci 5507db96d56Sopenharmony_ci good_int = TruncReturnsIntSubclass() 5517db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 5527db96d56Sopenharmony_ci n = int(good_int) 5537db96d56Sopenharmony_ci self.assertEqual(n, 1) 5547db96d56Sopenharmony_ci self.assertIs(type(n), int) 5557db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 5567db96d56Sopenharmony_ci n = IntSubclass(good_int) 5577db96d56Sopenharmony_ci self.assertEqual(n, 1) 5587db96d56Sopenharmony_ci self.assertIs(type(n), IntSubclass) 5597db96d56Sopenharmony_ci 5607db96d56Sopenharmony_ci def test_error_message(self): 5617db96d56Sopenharmony_ci def check(s, base=None): 5627db96d56Sopenharmony_ci with self.assertRaises(ValueError, 5637db96d56Sopenharmony_ci msg="int(%r, %r)" % (s, base)) as cm: 5647db96d56Sopenharmony_ci if base is None: 5657db96d56Sopenharmony_ci int(s) 5667db96d56Sopenharmony_ci else: 5677db96d56Sopenharmony_ci int(s, base) 5687db96d56Sopenharmony_ci self.assertEqual(cm.exception.args[0], 5697db96d56Sopenharmony_ci "invalid literal for int() with base %d: %r" % 5707db96d56Sopenharmony_ci (10 if base is None else base, s)) 5717db96d56Sopenharmony_ci 5727db96d56Sopenharmony_ci check('\xbd') 5737db96d56Sopenharmony_ci check('123\xbd') 5747db96d56Sopenharmony_ci check(' 123 456 ') 5757db96d56Sopenharmony_ci 5767db96d56Sopenharmony_ci check('123\x00') 5777db96d56Sopenharmony_ci # SF bug 1545497: embedded NULs were not detected with explicit base 5787db96d56Sopenharmony_ci check('123\x00', 10) 5797db96d56Sopenharmony_ci check('123\x00 245', 20) 5807db96d56Sopenharmony_ci check('123\x00 245', 16) 5817db96d56Sopenharmony_ci check('123\x00245', 20) 5827db96d56Sopenharmony_ci check('123\x00245', 16) 5837db96d56Sopenharmony_ci # byte string with embedded NUL 5847db96d56Sopenharmony_ci check(b'123\x00') 5857db96d56Sopenharmony_ci check(b'123\x00', 10) 5867db96d56Sopenharmony_ci # non-UTF-8 byte string 5877db96d56Sopenharmony_ci check(b'123\xbd') 5887db96d56Sopenharmony_ci check(b'123\xbd', 10) 5897db96d56Sopenharmony_ci # lone surrogate in Unicode string 5907db96d56Sopenharmony_ci check('123\ud800') 5917db96d56Sopenharmony_ci check('123\ud800', 10) 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ci def test_issue31619(self): 5947db96d56Sopenharmony_ci self.assertEqual(int('1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1', 2), 5957db96d56Sopenharmony_ci 0b1010101010101010101010101010101) 5967db96d56Sopenharmony_ci self.assertEqual(int('1_2_3_4_5_6_7_0_1_2_3', 8), 0o12345670123) 5977db96d56Sopenharmony_ci self.assertEqual(int('1_2_3_4_5_6_7_8_9', 16), 0x123456789) 5987db96d56Sopenharmony_ci self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807) 5997db96d56Sopenharmony_ci 6007db96d56Sopenharmony_ci 6017db96d56Sopenharmony_ciclass IntStrDigitLimitsTests(unittest.TestCase): 6027db96d56Sopenharmony_ci 6037db96d56Sopenharmony_ci int_class = int # Override this in subclasses to reuse the suite. 6047db96d56Sopenharmony_ci 6057db96d56Sopenharmony_ci def setUp(self): 6067db96d56Sopenharmony_ci super().setUp() 6077db96d56Sopenharmony_ci self._previous_limit = sys.get_int_max_str_digits() 6087db96d56Sopenharmony_ci sys.set_int_max_str_digits(2048) 6097db96d56Sopenharmony_ci 6107db96d56Sopenharmony_ci def tearDown(self): 6117db96d56Sopenharmony_ci sys.set_int_max_str_digits(self._previous_limit) 6127db96d56Sopenharmony_ci super().tearDown() 6137db96d56Sopenharmony_ci 6147db96d56Sopenharmony_ci def test_disabled_limit(self): 6157db96d56Sopenharmony_ci self.assertGreater(sys.get_int_max_str_digits(), 0) 6167db96d56Sopenharmony_ci self.assertLess(sys.get_int_max_str_digits(), 20_000) 6177db96d56Sopenharmony_ci with support.adjust_int_max_str_digits(0): 6187db96d56Sopenharmony_ci self.assertEqual(sys.get_int_max_str_digits(), 0) 6197db96d56Sopenharmony_ci i = self.int_class('1' * 20_000) 6207db96d56Sopenharmony_ci str(i) 6217db96d56Sopenharmony_ci self.assertGreater(sys.get_int_max_str_digits(), 0) 6227db96d56Sopenharmony_ci 6237db96d56Sopenharmony_ci def test_max_str_digits_edge_cases(self): 6247db96d56Sopenharmony_ci """Ignore the +/- sign and space padding.""" 6257db96d56Sopenharmony_ci int_class = self.int_class 6267db96d56Sopenharmony_ci maxdigits = sys.get_int_max_str_digits() 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_ci int_class('1' * maxdigits) 6297db96d56Sopenharmony_ci int_class(' ' + '1' * maxdigits) 6307db96d56Sopenharmony_ci int_class('1' * maxdigits + ' ') 6317db96d56Sopenharmony_ci int_class('+' + '1' * maxdigits) 6327db96d56Sopenharmony_ci int_class('-' + '1' * maxdigits) 6337db96d56Sopenharmony_ci self.assertEqual(len(str(10 ** (maxdigits - 1))), maxdigits) 6347db96d56Sopenharmony_ci 6357db96d56Sopenharmony_ci def check(self, i, base=None): 6367db96d56Sopenharmony_ci with self.assertRaises(ValueError): 6377db96d56Sopenharmony_ci if base is None: 6387db96d56Sopenharmony_ci self.int_class(i) 6397db96d56Sopenharmony_ci else: 6407db96d56Sopenharmony_ci self.int_class(i, base) 6417db96d56Sopenharmony_ci 6427db96d56Sopenharmony_ci def test_max_str_digits(self): 6437db96d56Sopenharmony_ci maxdigits = sys.get_int_max_str_digits() 6447db96d56Sopenharmony_ci 6457db96d56Sopenharmony_ci self.check('1' * (maxdigits + 1)) 6467db96d56Sopenharmony_ci self.check(' ' + '1' * (maxdigits + 1)) 6477db96d56Sopenharmony_ci self.check('1' * (maxdigits + 1) + ' ') 6487db96d56Sopenharmony_ci self.check('+' + '1' * (maxdigits + 1)) 6497db96d56Sopenharmony_ci self.check('-' + '1' * (maxdigits + 1)) 6507db96d56Sopenharmony_ci self.check('1' * (maxdigits + 1)) 6517db96d56Sopenharmony_ci 6527db96d56Sopenharmony_ci i = 10 ** maxdigits 6537db96d56Sopenharmony_ci with self.assertRaises(ValueError): 6547db96d56Sopenharmony_ci str(i) 6557db96d56Sopenharmony_ci 6567db96d56Sopenharmony_ci def test_denial_of_service_prevented_int_to_str(self): 6577db96d56Sopenharmony_ci """Regression test: ensure we fail before performing O(N**2) work.""" 6587db96d56Sopenharmony_ci maxdigits = sys.get_int_max_str_digits() 6597db96d56Sopenharmony_ci assert maxdigits < 50_000, maxdigits # A test prerequisite. 6607db96d56Sopenharmony_ci get_time = time.process_time 6617db96d56Sopenharmony_ci if get_time() <= 0: # some platforms like WASM lack process_time() 6627db96d56Sopenharmony_ci get_time = time.monotonic 6637db96d56Sopenharmony_ci 6647db96d56Sopenharmony_ci huge_int = int(f'0x{"c"*65_000}', base=16) # 78268 decimal digits. 6657db96d56Sopenharmony_ci digits = 78_268 6667db96d56Sopenharmony_ci with support.adjust_int_max_str_digits(digits): 6677db96d56Sopenharmony_ci start = get_time() 6687db96d56Sopenharmony_ci huge_decimal = str(huge_int) 6697db96d56Sopenharmony_ci seconds_to_convert = get_time() - start 6707db96d56Sopenharmony_ci self.assertEqual(len(huge_decimal), digits) 6717db96d56Sopenharmony_ci # Ensuring that we chose a slow enough conversion to measure. 6727db96d56Sopenharmony_ci # It takes 0.1 seconds on a Zen based cloud VM in an opt build. 6737db96d56Sopenharmony_ci # Some OSes have a low res 1/64s timer, skip if hard to measure. 6747db96d56Sopenharmony_ci if seconds_to_convert < 1/64: 6757db96d56Sopenharmony_ci raise unittest.SkipTest('"slow" conversion took only ' 6767db96d56Sopenharmony_ci f'{seconds_to_convert} seconds.') 6777db96d56Sopenharmony_ci 6787db96d56Sopenharmony_ci # We test with the limit almost at the size needed to check performance. 6797db96d56Sopenharmony_ci # The performant limit check is slightly fuzzy, give it a some room. 6807db96d56Sopenharmony_ci with support.adjust_int_max_str_digits(int(.995 * digits)): 6817db96d56Sopenharmony_ci with self.assertRaises(ValueError) as err: 6827db96d56Sopenharmony_ci start = get_time() 6837db96d56Sopenharmony_ci str(huge_int) 6847db96d56Sopenharmony_ci seconds_to_fail_huge = get_time() - start 6857db96d56Sopenharmony_ci self.assertIn('conversion', str(err.exception)) 6867db96d56Sopenharmony_ci self.assertLessEqual(seconds_to_fail_huge, seconds_to_convert/2) 6877db96d56Sopenharmony_ci 6887db96d56Sopenharmony_ci # Now we test that a conversion that would take 30x as long also fails 6897db96d56Sopenharmony_ci # in a similarly fast fashion. 6907db96d56Sopenharmony_ci extra_huge_int = int(f'0x{"c"*500_000}', base=16) # 602060 digits. 6917db96d56Sopenharmony_ci with self.assertRaises(ValueError) as err: 6927db96d56Sopenharmony_ci start = get_time() 6937db96d56Sopenharmony_ci # If not limited, 8 seconds said Zen based cloud VM. 6947db96d56Sopenharmony_ci str(extra_huge_int) 6957db96d56Sopenharmony_ci seconds_to_fail_extra_huge = get_time() - start 6967db96d56Sopenharmony_ci self.assertIn('conversion', str(err.exception)) 6977db96d56Sopenharmony_ci self.assertLess(seconds_to_fail_extra_huge, seconds_to_convert/2) 6987db96d56Sopenharmony_ci 6997db96d56Sopenharmony_ci def test_denial_of_service_prevented_str_to_int(self): 7007db96d56Sopenharmony_ci """Regression test: ensure we fail before performing O(N**2) work.""" 7017db96d56Sopenharmony_ci maxdigits = sys.get_int_max_str_digits() 7027db96d56Sopenharmony_ci assert maxdigits < 100_000, maxdigits # A test prerequisite. 7037db96d56Sopenharmony_ci get_time = time.process_time 7047db96d56Sopenharmony_ci if get_time() <= 0: # some platforms like WASM lack process_time() 7057db96d56Sopenharmony_ci get_time = time.monotonic 7067db96d56Sopenharmony_ci 7077db96d56Sopenharmony_ci digits = 133700 7087db96d56Sopenharmony_ci huge = '8'*digits 7097db96d56Sopenharmony_ci with support.adjust_int_max_str_digits(digits): 7107db96d56Sopenharmony_ci start = get_time() 7117db96d56Sopenharmony_ci int(huge) 7127db96d56Sopenharmony_ci seconds_to_convert = get_time() - start 7137db96d56Sopenharmony_ci # Ensuring that we chose a slow enough conversion to measure. 7147db96d56Sopenharmony_ci # It takes 0.1 seconds on a Zen based cloud VM in an opt build. 7157db96d56Sopenharmony_ci # Some OSes have a low res 1/64s timer, skip if hard to measure. 7167db96d56Sopenharmony_ci if seconds_to_convert < 1/64: 7177db96d56Sopenharmony_ci raise unittest.SkipTest('"slow" conversion took only ' 7187db96d56Sopenharmony_ci f'{seconds_to_convert} seconds.') 7197db96d56Sopenharmony_ci 7207db96d56Sopenharmony_ci with support.adjust_int_max_str_digits(digits - 1): 7217db96d56Sopenharmony_ci with self.assertRaises(ValueError) as err: 7227db96d56Sopenharmony_ci start = get_time() 7237db96d56Sopenharmony_ci int(huge) 7247db96d56Sopenharmony_ci seconds_to_fail_huge = get_time() - start 7257db96d56Sopenharmony_ci self.assertIn('conversion', str(err.exception)) 7267db96d56Sopenharmony_ci self.assertLessEqual(seconds_to_fail_huge, seconds_to_convert/2) 7277db96d56Sopenharmony_ci 7287db96d56Sopenharmony_ci # Now we test that a conversion that would take 30x as long also fails 7297db96d56Sopenharmony_ci # in a similarly fast fashion. 7307db96d56Sopenharmony_ci extra_huge = '7'*1_200_000 7317db96d56Sopenharmony_ci with self.assertRaises(ValueError) as err: 7327db96d56Sopenharmony_ci start = get_time() 7337db96d56Sopenharmony_ci # If not limited, 8 seconds in the Zen based cloud VM. 7347db96d56Sopenharmony_ci int(extra_huge) 7357db96d56Sopenharmony_ci seconds_to_fail_extra_huge = get_time() - start 7367db96d56Sopenharmony_ci self.assertIn('conversion', str(err.exception)) 7377db96d56Sopenharmony_ci self.assertLessEqual(seconds_to_fail_extra_huge, seconds_to_convert/2) 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci def test_power_of_two_bases_unlimited(self): 7407db96d56Sopenharmony_ci """The limit does not apply to power of 2 bases.""" 7417db96d56Sopenharmony_ci maxdigits = sys.get_int_max_str_digits() 7427db96d56Sopenharmony_ci 7437db96d56Sopenharmony_ci for base in (2, 4, 8, 16, 32): 7447db96d56Sopenharmony_ci with self.subTest(base=base): 7457db96d56Sopenharmony_ci self.int_class('1' * (maxdigits + 1), base) 7467db96d56Sopenharmony_ci assert maxdigits < 100_000 7477db96d56Sopenharmony_ci self.int_class('1' * 100_000, base) 7487db96d56Sopenharmony_ci 7497db96d56Sopenharmony_ci def test_underscores_ignored(self): 7507db96d56Sopenharmony_ci maxdigits = sys.get_int_max_str_digits() 7517db96d56Sopenharmony_ci 7527db96d56Sopenharmony_ci triples = maxdigits // 3 7537db96d56Sopenharmony_ci s = '111' * triples 7547db96d56Sopenharmony_ci s_ = '1_11' * triples 7557db96d56Sopenharmony_ci self.int_class(s) # succeeds 7567db96d56Sopenharmony_ci self.int_class(s_) # succeeds 7577db96d56Sopenharmony_ci self.check(f'{s}111') 7587db96d56Sopenharmony_ci self.check(f'{s_}_111') 7597db96d56Sopenharmony_ci 7607db96d56Sopenharmony_ci def test_sign_not_counted(self): 7617db96d56Sopenharmony_ci int_class = self.int_class 7627db96d56Sopenharmony_ci max_digits = sys.get_int_max_str_digits() 7637db96d56Sopenharmony_ci s = '5' * max_digits 7647db96d56Sopenharmony_ci i = int_class(s) 7657db96d56Sopenharmony_ci pos_i = int_class(f'+{s}') 7667db96d56Sopenharmony_ci assert i == pos_i 7677db96d56Sopenharmony_ci neg_i = int_class(f'-{s}') 7687db96d56Sopenharmony_ci assert -pos_i == neg_i 7697db96d56Sopenharmony_ci str(pos_i) 7707db96d56Sopenharmony_ci str(neg_i) 7717db96d56Sopenharmony_ci 7727db96d56Sopenharmony_ci def _other_base_helper(self, base): 7737db96d56Sopenharmony_ci int_class = self.int_class 7747db96d56Sopenharmony_ci max_digits = sys.get_int_max_str_digits() 7757db96d56Sopenharmony_ci s = '2' * max_digits 7767db96d56Sopenharmony_ci i = int_class(s, base) 7777db96d56Sopenharmony_ci if base > 10: 7787db96d56Sopenharmony_ci with self.assertRaises(ValueError): 7797db96d56Sopenharmony_ci str(i) 7807db96d56Sopenharmony_ci elif base < 10: 7817db96d56Sopenharmony_ci str(i) 7827db96d56Sopenharmony_ci with self.assertRaises(ValueError) as err: 7837db96d56Sopenharmony_ci int_class(f'{s}1', base) 7847db96d56Sopenharmony_ci 7857db96d56Sopenharmony_ci def test_int_from_other_bases(self): 7867db96d56Sopenharmony_ci base = 3 7877db96d56Sopenharmony_ci with self.subTest(base=base): 7887db96d56Sopenharmony_ci self._other_base_helper(base) 7897db96d56Sopenharmony_ci base = 36 7907db96d56Sopenharmony_ci with self.subTest(base=base): 7917db96d56Sopenharmony_ci self._other_base_helper(base) 7927db96d56Sopenharmony_ci 7937db96d56Sopenharmony_ci 7947db96d56Sopenharmony_ciclass IntSubclassStrDigitLimitsTests(IntStrDigitLimitsTests): 7957db96d56Sopenharmony_ci int_class = IntSubclass 7967db96d56Sopenharmony_ci 7977db96d56Sopenharmony_ci 7987db96d56Sopenharmony_ciif __name__ == "__main__": 7997db96d56Sopenharmony_ci unittest.main() 800