1import sys 2 3import unittest 4from test import support 5from test.test_grammar import (VALID_UNDERSCORE_LITERALS, 6 INVALID_UNDERSCORE_LITERALS) 7 8L = [ 9 ('0', 0), 10 ('1', 1), 11 ('9', 9), 12 ('10', 10), 13 ('99', 99), 14 ('100', 100), 15 ('314', 314), 16 (' 314', 314), 17 ('314 ', 314), 18 (' \t\t 314 \t\t ', 314), 19 (repr(sys.maxsize), sys.maxsize), 20 (' 1x', ValueError), 21 (' 1 ', 1), 22 (' 1\02 ', ValueError), 23 ('', ValueError), 24 (' ', ValueError), 25 (' \t\t ', ValueError), 26 ("\u0200", ValueError) 27] 28 29class IntSubclass(int): 30 pass 31 32class IntTestCases(unittest.TestCase): 33 34 def test_basic(self): 35 self.assertEqual(int(314), 314) 36 self.assertEqual(int(3.14), 3) 37 # Check that conversion from float truncates towards zero 38 self.assertEqual(int(-3.14), -3) 39 self.assertEqual(int(3.9), 3) 40 self.assertEqual(int(-3.9), -3) 41 self.assertEqual(int(3.5), 3) 42 self.assertEqual(int(-3.5), -3) 43 self.assertEqual(int("-3"), -3) 44 self.assertEqual(int(" -3 "), -3) 45 self.assertEqual(int("\N{EM SPACE}-3\N{EN SPACE}"), -3) 46 # Different base: 47 self.assertEqual(int("10",16), 16) 48 # Test conversion from strings and various anomalies 49 for s, v in L: 50 for sign in "", "+", "-": 51 for prefix in "", " ", "\t", " \t\t ": 52 ss = prefix + sign + s 53 vv = v 54 if sign == "-" and v is not ValueError: 55 vv = -v 56 try: 57 self.assertEqual(int(ss), vv) 58 except ValueError: 59 pass 60 61 s = repr(-1-sys.maxsize) 62 x = int(s) 63 self.assertEqual(x+1, -sys.maxsize) 64 self.assertIsInstance(x, int) 65 # should return int 66 self.assertEqual(int(s[1:]), sys.maxsize+1) 67 68 # should return int 69 x = int(1e100) 70 self.assertIsInstance(x, int) 71 x = int(-1e100) 72 self.assertIsInstance(x, int) 73 74 75 # SF bug 434186: 0x80000000/2 != 0x80000000>>1. 76 # Worked by accident in Windows release build, but failed in debug build. 77 # Failed in all Linux builds. 78 x = -1-sys.maxsize 79 self.assertEqual(x >> 1, x//2) 80 81 x = int('1' * 600) 82 self.assertIsInstance(x, int) 83 84 85 self.assertRaises(TypeError, int, 1, 12) 86 87 self.assertEqual(int('0o123', 0), 83) 88 self.assertEqual(int('0x123', 16), 291) 89 90 # Bug 1679: "0x" is not a valid hex literal 91 self.assertRaises(ValueError, int, "0x", 16) 92 self.assertRaises(ValueError, int, "0x", 0) 93 94 self.assertRaises(ValueError, int, "0o", 8) 95 self.assertRaises(ValueError, int, "0o", 0) 96 97 self.assertRaises(ValueError, int, "0b", 2) 98 self.assertRaises(ValueError, int, "0b", 0) 99 100 # SF bug 1334662: int(string, base) wrong answers 101 # Various representations of 2**32 evaluated to 0 102 # rather than 2**32 in previous versions 103 104 self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296) 105 self.assertEqual(int('102002022201221111211', 3), 4294967296) 106 self.assertEqual(int('10000000000000000', 4), 4294967296) 107 self.assertEqual(int('32244002423141', 5), 4294967296) 108 self.assertEqual(int('1550104015504', 6), 4294967296) 109 self.assertEqual(int('211301422354', 7), 4294967296) 110 self.assertEqual(int('40000000000', 8), 4294967296) 111 self.assertEqual(int('12068657454', 9), 4294967296) 112 self.assertEqual(int('4294967296', 10), 4294967296) 113 self.assertEqual(int('1904440554', 11), 4294967296) 114 self.assertEqual(int('9ba461594', 12), 4294967296) 115 self.assertEqual(int('535a79889', 13), 4294967296) 116 self.assertEqual(int('2ca5b7464', 14), 4294967296) 117 self.assertEqual(int('1a20dcd81', 15), 4294967296) 118 self.assertEqual(int('100000000', 16), 4294967296) 119 self.assertEqual(int('a7ffda91', 17), 4294967296) 120 self.assertEqual(int('704he7g4', 18), 4294967296) 121 self.assertEqual(int('4f5aff66', 19), 4294967296) 122 self.assertEqual(int('3723ai4g', 20), 4294967296) 123 self.assertEqual(int('281d55i4', 21), 4294967296) 124 self.assertEqual(int('1fj8b184', 22), 4294967296) 125 self.assertEqual(int('1606k7ic', 23), 4294967296) 126 self.assertEqual(int('mb994ag', 24), 4294967296) 127 self.assertEqual(int('hek2mgl', 25), 4294967296) 128 self.assertEqual(int('dnchbnm', 26), 4294967296) 129 self.assertEqual(int('b28jpdm', 27), 4294967296) 130 self.assertEqual(int('8pfgih4', 28), 4294967296) 131 self.assertEqual(int('76beigg', 29), 4294967296) 132 self.assertEqual(int('5qmcpqg', 30), 4294967296) 133 self.assertEqual(int('4q0jto4', 31), 4294967296) 134 self.assertEqual(int('4000000', 32), 4294967296) 135 self.assertEqual(int('3aokq94', 33), 4294967296) 136 self.assertEqual(int('2qhxjli', 34), 4294967296) 137 self.assertEqual(int('2br45qb', 35), 4294967296) 138 self.assertEqual(int('1z141z4', 36), 4294967296) 139 140 # tests with base 0 141 # this fails on 3.0, but in 2.x the old octal syntax is allowed 142 self.assertEqual(int(' 0o123 ', 0), 83) 143 self.assertEqual(int(' 0o123 ', 0), 83) 144 self.assertEqual(int('000', 0), 0) 145 self.assertEqual(int('0o123', 0), 83) 146 self.assertEqual(int('0x123', 0), 291) 147 self.assertEqual(int('0b100', 0), 4) 148 self.assertEqual(int(' 0O123 ', 0), 83) 149 self.assertEqual(int(' 0X123 ', 0), 291) 150 self.assertEqual(int(' 0B100 ', 0), 4) 151 152 # without base still base 10 153 self.assertEqual(int('0123'), 123) 154 self.assertEqual(int('0123', 10), 123) 155 156 # tests with prefix and base != 0 157 self.assertEqual(int('0x123', 16), 291) 158 self.assertEqual(int('0o123', 8), 83) 159 self.assertEqual(int('0b100', 2), 4) 160 self.assertEqual(int('0X123', 16), 291) 161 self.assertEqual(int('0O123', 8), 83) 162 self.assertEqual(int('0B100', 2), 4) 163 164 # the code has special checks for the first character after the 165 # type prefix 166 self.assertRaises(ValueError, int, '0b2', 2) 167 self.assertRaises(ValueError, int, '0b02', 2) 168 self.assertRaises(ValueError, int, '0B2', 2) 169 self.assertRaises(ValueError, int, '0B02', 2) 170 self.assertRaises(ValueError, int, '0o8', 8) 171 self.assertRaises(ValueError, int, '0o08', 8) 172 self.assertRaises(ValueError, int, '0O8', 8) 173 self.assertRaises(ValueError, int, '0O08', 8) 174 self.assertRaises(ValueError, int, '0xg', 16) 175 self.assertRaises(ValueError, int, '0x0g', 16) 176 self.assertRaises(ValueError, int, '0Xg', 16) 177 self.assertRaises(ValueError, int, '0X0g', 16) 178 179 # SF bug 1334662: int(string, base) wrong answers 180 # Checks for proper evaluation of 2**32 + 1 181 self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297) 182 self.assertEqual(int('102002022201221111212', 3), 4294967297) 183 self.assertEqual(int('10000000000000001', 4), 4294967297) 184 self.assertEqual(int('32244002423142', 5), 4294967297) 185 self.assertEqual(int('1550104015505', 6), 4294967297) 186 self.assertEqual(int('211301422355', 7), 4294967297) 187 self.assertEqual(int('40000000001', 8), 4294967297) 188 self.assertEqual(int('12068657455', 9), 4294967297) 189 self.assertEqual(int('4294967297', 10), 4294967297) 190 self.assertEqual(int('1904440555', 11), 4294967297) 191 self.assertEqual(int('9ba461595', 12), 4294967297) 192 self.assertEqual(int('535a7988a', 13), 4294967297) 193 self.assertEqual(int('2ca5b7465', 14), 4294967297) 194 self.assertEqual(int('1a20dcd82', 15), 4294967297) 195 self.assertEqual(int('100000001', 16), 4294967297) 196 self.assertEqual(int('a7ffda92', 17), 4294967297) 197 self.assertEqual(int('704he7g5', 18), 4294967297) 198 self.assertEqual(int('4f5aff67', 19), 4294967297) 199 self.assertEqual(int('3723ai4h', 20), 4294967297) 200 self.assertEqual(int('281d55i5', 21), 4294967297) 201 self.assertEqual(int('1fj8b185', 22), 4294967297) 202 self.assertEqual(int('1606k7id', 23), 4294967297) 203 self.assertEqual(int('mb994ah', 24), 4294967297) 204 self.assertEqual(int('hek2mgm', 25), 4294967297) 205 self.assertEqual(int('dnchbnn', 26), 4294967297) 206 self.assertEqual(int('b28jpdn', 27), 4294967297) 207 self.assertEqual(int('8pfgih5', 28), 4294967297) 208 self.assertEqual(int('76beigh', 29), 4294967297) 209 self.assertEqual(int('5qmcpqh', 30), 4294967297) 210 self.assertEqual(int('4q0jto5', 31), 4294967297) 211 self.assertEqual(int('4000001', 32), 4294967297) 212 self.assertEqual(int('3aokq95', 33), 4294967297) 213 self.assertEqual(int('2qhxjlj', 34), 4294967297) 214 self.assertEqual(int('2br45qc', 35), 4294967297) 215 self.assertEqual(int('1z141z5', 36), 4294967297) 216 217 def test_underscores(self): 218 for lit in VALID_UNDERSCORE_LITERALS: 219 if any(ch in lit for ch in '.eEjJ'): 220 continue 221 self.assertEqual(int(lit, 0), eval(lit)) 222 self.assertEqual(int(lit, 0), int(lit.replace('_', ''), 0)) 223 for lit in INVALID_UNDERSCORE_LITERALS: 224 if any(ch in lit for ch in '.eEjJ'): 225 continue 226 self.assertRaises(ValueError, int, lit, 0) 227 # Additional test cases with bases != 0, only for the constructor: 228 self.assertEqual(int("1_00", 3), 9) 229 self.assertEqual(int("0_100"), 100) # not valid as a literal! 230 self.assertEqual(int(b"1_00"), 100) # byte underscore 231 self.assertRaises(ValueError, int, "_100") 232 self.assertRaises(ValueError, int, "+_100") 233 self.assertRaises(ValueError, int, "1__00") 234 self.assertRaises(ValueError, int, "100_") 235 236 @support.cpython_only 237 def test_small_ints(self): 238 # Bug #3236: Return small longs from PyLong_FromString 239 self.assertIs(int('10'), 10) 240 self.assertIs(int('-1'), -1) 241 self.assertIs(int(b'10'), 10) 242 self.assertIs(int(b'-1'), -1) 243 244 def test_no_args(self): 245 self.assertEqual(int(), 0) 246 247 def test_keyword_args(self): 248 # Test invoking int() using keyword arguments. 249 self.assertEqual(int('100', base=2), 4) 250 with self.assertRaisesRegex(TypeError, 'keyword argument'): 251 int(x=1.2) 252 with self.assertRaisesRegex(TypeError, 'keyword argument'): 253 int(x='100', base=2) 254 self.assertRaises(TypeError, int, base=10) 255 self.assertRaises(TypeError, int, base=0) 256 257 def test_int_base_limits(self): 258 """Testing the supported limits of the int() base parameter.""" 259 self.assertEqual(int('0', 5), 0) 260 with self.assertRaises(ValueError): 261 int('0', 1) 262 with self.assertRaises(ValueError): 263 int('0', 37) 264 with self.assertRaises(ValueError): 265 int('0', -909) # An old magic value base from Python 2. 266 with self.assertRaises(ValueError): 267 int('0', base=0-(2**234)) 268 with self.assertRaises(ValueError): 269 int('0', base=2**234) 270 # Bases 2 through 36 are supported. 271 for base in range(2,37): 272 self.assertEqual(int('0', base=base), 0) 273 274 def test_int_base_bad_types(self): 275 """Not integer types are not valid bases; issue16772.""" 276 with self.assertRaises(TypeError): 277 int('0', 5.5) 278 with self.assertRaises(TypeError): 279 int('0', 5.0) 280 281 def test_int_base_indexable(self): 282 class MyIndexable(object): 283 def __init__(self, value): 284 self.value = value 285 def __index__(self): 286 return self.value 287 288 # Check out of range bases. 289 for base in 2**100, -2**100, 1, 37: 290 with self.assertRaises(ValueError): 291 int('43', base) 292 293 # Check in-range bases. 294 self.assertEqual(int('101', base=MyIndexable(2)), 5) 295 self.assertEqual(int('101', base=MyIndexable(10)), 101) 296 self.assertEqual(int('101', base=MyIndexable(36)), 1 + 36**2) 297 298 def test_non_numeric_input_types(self): 299 # Test possible non-numeric types for the argument x, including 300 # subclasses of the explicitly documented accepted types. 301 class CustomStr(str): pass 302 class CustomBytes(bytes): pass 303 class CustomByteArray(bytearray): pass 304 305 factories = [ 306 bytes, 307 bytearray, 308 lambda b: CustomStr(b.decode()), 309 CustomBytes, 310 CustomByteArray, 311 memoryview, 312 ] 313 try: 314 from array import array 315 except ImportError: 316 pass 317 else: 318 factories.append(lambda b: array('B', b)) 319 320 for f in factories: 321 x = f(b'100') 322 with self.subTest(type(x)): 323 self.assertEqual(int(x), 100) 324 if isinstance(x, (str, bytes, bytearray)): 325 self.assertEqual(int(x, 2), 4) 326 else: 327 msg = "can't convert non-string" 328 with self.assertRaisesRegex(TypeError, msg): 329 int(x, 2) 330 with self.assertRaisesRegex(ValueError, 'invalid literal'): 331 int(f(b'A' * 0x10)) 332 333 def test_int_memoryview(self): 334 self.assertEqual(int(memoryview(b'123')[1:3]), 23) 335 self.assertEqual(int(memoryview(b'123\x00')[1:3]), 23) 336 self.assertEqual(int(memoryview(b'123 ')[1:3]), 23) 337 self.assertEqual(int(memoryview(b'123A')[1:3]), 23) 338 self.assertEqual(int(memoryview(b'1234')[1:3]), 23) 339 340 def test_string_float(self): 341 self.assertRaises(ValueError, int, '1.2') 342 343 def test_intconversion(self): 344 # Test __int__() 345 class ClassicMissingMethods: 346 pass 347 self.assertRaises(TypeError, int, ClassicMissingMethods()) 348 349 class MissingMethods(object): 350 pass 351 self.assertRaises(TypeError, int, MissingMethods()) 352 353 class Foo0: 354 def __int__(self): 355 return 42 356 357 self.assertEqual(int(Foo0()), 42) 358 359 class Classic: 360 pass 361 for base in (object, Classic): 362 class IntOverridesTrunc(base): 363 def __int__(self): 364 return 42 365 def __trunc__(self): 366 return -12 367 self.assertEqual(int(IntOverridesTrunc()), 42) 368 369 class JustTrunc(base): 370 def __trunc__(self): 371 return 42 372 self.assertEqual(int(JustTrunc()), 42) 373 374 class ExceptionalTrunc(base): 375 def __trunc__(self): 376 1 / 0 377 with self.assertRaises(ZeroDivisionError): 378 int(ExceptionalTrunc()) 379 380 for trunc_result_base in (object, Classic): 381 class Index(trunc_result_base): 382 def __index__(self): 383 return 42 384 385 class TruncReturnsNonInt(base): 386 def __trunc__(self): 387 return Index() 388 self.assertEqual(int(TruncReturnsNonInt()), 42) 389 390 class Intable(trunc_result_base): 391 def __int__(self): 392 return 42 393 394 class TruncReturnsNonIndex(base): 395 def __trunc__(self): 396 return Intable() 397 self.assertEqual(int(TruncReturnsNonInt()), 42) 398 399 class NonIntegral(trunc_result_base): 400 def __trunc__(self): 401 # Check that we avoid infinite recursion. 402 return NonIntegral() 403 404 class TruncReturnsNonIntegral(base): 405 def __trunc__(self): 406 return NonIntegral() 407 try: 408 int(TruncReturnsNonIntegral()) 409 except TypeError as e: 410 self.assertEqual(str(e), 411 "__trunc__ returned non-Integral" 412 " (type NonIntegral)") 413 else: 414 self.fail("Failed to raise TypeError with %s" % 415 ((base, trunc_result_base),)) 416 417 # Regression test for bugs.python.org/issue16060. 418 class BadInt(trunc_result_base): 419 def __int__(self): 420 return 42.0 421 422 class TruncReturnsBadInt(base): 423 def __trunc__(self): 424 return BadInt() 425 426 with self.assertRaises(TypeError): 427 int(TruncReturnsBadInt()) 428 429 def test_int_subclass_with_index(self): 430 class MyIndex(int): 431 def __index__(self): 432 return 42 433 434 class BadIndex(int): 435 def __index__(self): 436 return 42.0 437 438 my_int = MyIndex(7) 439 self.assertEqual(my_int, 7) 440 self.assertEqual(int(my_int), 7) 441 442 self.assertEqual(int(BadIndex()), 0) 443 444 def test_int_subclass_with_int(self): 445 class MyInt(int): 446 def __int__(self): 447 return 42 448 449 class BadInt(int): 450 def __int__(self): 451 return 42.0 452 453 my_int = MyInt(7) 454 self.assertEqual(my_int, 7) 455 self.assertEqual(int(my_int), 42) 456 457 my_int = BadInt(7) 458 self.assertEqual(my_int, 7) 459 self.assertRaises(TypeError, int, my_int) 460 461 def test_int_returns_int_subclass(self): 462 class BadIndex: 463 def __index__(self): 464 return True 465 466 class BadIndex2(int): 467 def __index__(self): 468 return True 469 470 class BadInt: 471 def __int__(self): 472 return True 473 474 class BadInt2(int): 475 def __int__(self): 476 return True 477 478 class TruncReturnsBadIndex: 479 def __trunc__(self): 480 return BadIndex() 481 482 class TruncReturnsBadInt: 483 def __trunc__(self): 484 return BadInt() 485 486 class TruncReturnsIntSubclass: 487 def __trunc__(self): 488 return True 489 490 bad_int = BadIndex() 491 with self.assertWarns(DeprecationWarning): 492 n = int(bad_int) 493 self.assertEqual(n, 1) 494 self.assertIs(type(n), int) 495 496 bad_int = BadIndex2() 497 n = int(bad_int) 498 self.assertEqual(n, 0) 499 self.assertIs(type(n), int) 500 501 bad_int = BadInt() 502 with self.assertWarns(DeprecationWarning): 503 n = int(bad_int) 504 self.assertEqual(n, 1) 505 self.assertIs(type(n), int) 506 507 bad_int = BadInt2() 508 with self.assertWarns(DeprecationWarning): 509 n = int(bad_int) 510 self.assertEqual(n, 1) 511 self.assertIs(type(n), int) 512 513 bad_int = TruncReturnsBadIndex() 514 with self.assertWarns(DeprecationWarning): 515 n = int(bad_int) 516 self.assertEqual(n, 1) 517 self.assertIs(type(n), int) 518 519 bad_int = TruncReturnsBadInt() 520 self.assertRaises(TypeError, int, bad_int) 521 522 good_int = TruncReturnsIntSubclass() 523 n = int(good_int) 524 self.assertEqual(n, 1) 525 self.assertIs(type(n), int) 526 n = IntSubclass(good_int) 527 self.assertEqual(n, 1) 528 self.assertIs(type(n), IntSubclass) 529 530 def test_error_message(self): 531 def check(s, base=None): 532 with self.assertRaises(ValueError, 533 msg="int(%r, %r)" % (s, base)) as cm: 534 if base is None: 535 int(s) 536 else: 537 int(s, base) 538 self.assertEqual(cm.exception.args[0], 539 "invalid literal for int() with base %d: %r" % 540 (10 if base is None else base, s)) 541 542 check('\xbd') 543 check('123\xbd') 544 check(' 123 456 ') 545 546 check('123\x00') 547 # SF bug 1545497: embedded NULs were not detected with explicit base 548 check('123\x00', 10) 549 check('123\x00 245', 20) 550 check('123\x00 245', 16) 551 check('123\x00245', 20) 552 check('123\x00245', 16) 553 # byte string with embedded NUL 554 check(b'123\x00') 555 check(b'123\x00', 10) 556 # non-UTF-8 byte string 557 check(b'123\xbd') 558 check(b'123\xbd', 10) 559 # lone surrogate in Unicode string 560 check('123\ud800') 561 check('123\ud800', 10) 562 563 def test_issue31619(self): 564 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), 565 0b1010101010101010101010101010101) 566 self.assertEqual(int('1_2_3_4_5_6_7_0_1_2_3', 8), 0o12345670123) 567 self.assertEqual(int('1_2_3_4_5_6_7_8_9', 16), 0x123456789) 568 self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807) 569 570 571class IntStrDigitLimitsTests(unittest.TestCase): 572 573 int_class = int # Override this in subclasses to reuse the suite. 574 575 def setUp(self): 576 super().setUp() 577 self._previous_limit = sys.get_int_max_str_digits() 578 sys.set_int_max_str_digits(2048) 579 580 def tearDown(self): 581 sys.set_int_max_str_digits(self._previous_limit) 582 super().tearDown() 583 584 def test_disabled_limit(self): 585 self.assertGreater(sys.get_int_max_str_digits(), 0) 586 self.assertLess(sys.get_int_max_str_digits(), 20_000) 587 with support.adjust_int_max_str_digits(0): 588 self.assertEqual(sys.get_int_max_str_digits(), 0) 589 i = self.int_class('1' * 20_000) 590 str(i) 591 self.assertGreater(sys.get_int_max_str_digits(), 0) 592 593 def test_max_str_digits_edge_cases(self): 594 """Ignore the +/- sign and space padding.""" 595 int_class = self.int_class 596 maxdigits = sys.get_int_max_str_digits() 597 598 int_class('1' * maxdigits) 599 int_class(' ' + '1' * maxdigits) 600 int_class('1' * maxdigits + ' ') 601 int_class('+' + '1' * maxdigits) 602 int_class('-' + '1' * maxdigits) 603 self.assertEqual(len(str(10 ** (maxdigits - 1))), maxdigits) 604 605 def check(self, i, base=None): 606 with self.assertRaises(ValueError): 607 if base is None: 608 self.int_class(i) 609 else: 610 self.int_class(i, base) 611 612 def test_max_str_digits(self): 613 maxdigits = sys.get_int_max_str_digits() 614 615 self.check('1' * (maxdigits + 1)) 616 self.check(' ' + '1' * (maxdigits + 1)) 617 self.check('1' * (maxdigits + 1) + ' ') 618 self.check('+' + '1' * (maxdigits + 1)) 619 self.check('-' + '1' * (maxdigits + 1)) 620 self.check('1' * (maxdigits + 1)) 621 622 i = 10 ** maxdigits 623 with self.assertRaises(ValueError): 624 str(i) 625 626 def test_power_of_two_bases_unlimited(self): 627 """The limit does not apply to power of 2 bases.""" 628 maxdigits = sys.get_int_max_str_digits() 629 630 for base in (2, 4, 8, 16, 32): 631 with self.subTest(base=base): 632 self.int_class('1' * (maxdigits + 1), base) 633 assert maxdigits < 100_000 634 self.int_class('1' * 100_000, base) 635 636 def test_underscores_ignored(self): 637 maxdigits = sys.get_int_max_str_digits() 638 639 triples = maxdigits // 3 640 s = '111' * triples 641 s_ = '1_11' * triples 642 self.int_class(s) # succeeds 643 self.int_class(s_) # succeeds 644 self.check(f'{s}111') 645 self.check(f'{s_}_111') 646 647 def test_sign_not_counted(self): 648 int_class = self.int_class 649 max_digits = sys.get_int_max_str_digits() 650 s = '5' * max_digits 651 i = int_class(s) 652 pos_i = int_class(f'+{s}') 653 assert i == pos_i 654 neg_i = int_class(f'-{s}') 655 assert -pos_i == neg_i 656 str(pos_i) 657 str(neg_i) 658 659 def _other_base_helper(self, base): 660 int_class = self.int_class 661 max_digits = sys.get_int_max_str_digits() 662 s = '2' * max_digits 663 i = int_class(s, base) 664 if base > 10: 665 with self.assertRaises(ValueError): 666 str(i) 667 elif base < 10: 668 str(i) 669 with self.assertRaises(ValueError) as err: 670 int_class(f'{s}1', base) 671 672 def test_int_from_other_bases(self): 673 base = 3 674 with self.subTest(base=base): 675 self._other_base_helper(base) 676 base = 36 677 with self.subTest(base=base): 678 self._other_base_helper(base) 679 680 681class IntSubclassStrDigitLimitsTests(IntStrDigitLimitsTests): 682 int_class = IntSubclass 683 684 685if __name__ == "__main__": 686 unittest.main() 687