test_int.py revision 8d30ad7c8ad5df59be8a65c8f8dab0d13be00dab
1import sys 2 3import unittest 4from test import test_support 5from test.test_support import run_unittest, have_unicode 6import math 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.maxint), sys.maxint), 20 (' 1x', ValueError), 21 (' 1 ', 1), 22 (' 1\02 ', ValueError), 23 ('', ValueError), 24 (' ', ValueError), 25 (' \t\t ', ValueError) 26] 27if have_unicode: 28 L += [ 29 (unicode('0'), 0), 30 (unicode('1'), 1), 31 (unicode('9'), 9), 32 (unicode('10'), 10), 33 (unicode('99'), 99), 34 (unicode('100'), 100), 35 (unicode('314'), 314), 36 (unicode(' 314'), 314), 37 (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314), 38 (unicode(' \t\t 314 \t\t '), 314), 39 (unicode(' 1x'), ValueError), 40 (unicode(' 1 '), 1), 41 (unicode(' 1\02 '), ValueError), 42 (unicode(''), ValueError), 43 (unicode(' '), ValueError), 44 (unicode(' \t\t '), ValueError), 45 (unichr(0x200), ValueError), 46] 47 48class IntSubclass(int): 49 pass 50 51class IntLongCommonTests(object): 52 53 """Mixin of test cases to share between both test_int and test_long.""" 54 55 # Change to int or long in the TestCase subclass. 56 ntype = None 57 58 def test_no_args(self): 59 self.assertEqual(self.ntype(), 0) 60 61 def test_keyword_args(self): 62 # Test invoking constructor using keyword arguments. 63 self.assertEqual(self.ntype(x=1.2), 1) 64 self.assertEqual(self.ntype('100', base=2), 4) 65 self.assertEqual(self.ntype(x='100', base=2), 4) 66 self.assertRaises(TypeError, self.ntype, base=10) 67 self.assertRaises(TypeError, self.ntype, base=0) 68 69class IntTestCases(IntLongCommonTests, unittest.TestCase): 70 71 ntype = int 72 73 def test_basic(self): 74 self.assertEqual(int(314), 314) 75 self.assertEqual(int(3.14), 3) 76 self.assertEqual(int(314L), 314) 77 # Check that conversion from float truncates towards zero 78 self.assertEqual(int(-3.14), -3) 79 self.assertEqual(int(3.9), 3) 80 self.assertEqual(int(-3.9), -3) 81 self.assertEqual(int(3.5), 3) 82 self.assertEqual(int(-3.5), -3) 83 # Different base: 84 self.assertEqual(int("10",16), 16L) 85 if have_unicode: 86 self.assertEqual(int(unicode("10"),16), 16L) 87 # Test conversion from strings and various anomalies 88 for s, v in L: 89 for sign in "", "+", "-": 90 for prefix in "", " ", "\t", " \t\t ": 91 ss = prefix + sign + s 92 vv = v 93 if sign == "-" and v is not ValueError: 94 vv = -v 95 try: 96 self.assertEqual(int(ss), vv) 97 except v: 98 pass 99 100 s = repr(-1-sys.maxint) 101 x = int(s) 102 self.assertEqual(x+1, -sys.maxint) 103 self.assertIsInstance(x, int) 104 # should return long 105 self.assertEqual(int(s[1:]), sys.maxint+1) 106 107 # should return long 108 x = int(1e100) 109 self.assertIsInstance(x, long) 110 x = int(-1e100) 111 self.assertIsInstance(x, long) 112 113 114 # SF bug 434186: 0x80000000/2 != 0x80000000>>1. 115 # Worked by accident in Windows release build, but failed in debug build. 116 # Failed in all Linux builds. 117 x = -1-sys.maxint 118 self.assertEqual(x >> 1, x//2) 119 120 self.assertRaises(ValueError, int, '123\0') 121 self.assertRaises(ValueError, int, '53', 40) 122 123 # SF bug 1545497: embedded NULs were not detected with 124 # explicit base 125 self.assertRaises(ValueError, int, '123\0', 10) 126 self.assertRaises(ValueError, int, '123\x00 245', 20) 127 128 x = int('1' * 600) 129 self.assertIsInstance(x, long) 130 131 if have_unicode: 132 x = int(unichr(0x661) * 600) 133 self.assertIsInstance(x, long) 134 135 self.assertRaises(TypeError, int, 1, 12) 136 137 self.assertEqual(int('0123', 0), 83) 138 self.assertEqual(int('0x123', 16), 291) 139 140 # Bug 1679: "0x" is not a valid hex literal 141 self.assertRaises(ValueError, int, "0x", 16) 142 self.assertRaises(ValueError, int, "0x", 0) 143 144 self.assertRaises(ValueError, int, "0o", 8) 145 self.assertRaises(ValueError, int, "0o", 0) 146 147 self.assertRaises(ValueError, int, "0b", 2) 148 self.assertRaises(ValueError, int, "0b", 0) 149 150 151 # SF bug 1334662: int(string, base) wrong answers 152 # Various representations of 2**32 evaluated to 0 153 # rather than 2**32 in previous versions 154 155 self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296L) 156 self.assertEqual(int('102002022201221111211', 3), 4294967296L) 157 self.assertEqual(int('10000000000000000', 4), 4294967296L) 158 self.assertEqual(int('32244002423141', 5), 4294967296L) 159 self.assertEqual(int('1550104015504', 6), 4294967296L) 160 self.assertEqual(int('211301422354', 7), 4294967296L) 161 self.assertEqual(int('40000000000', 8), 4294967296L) 162 self.assertEqual(int('12068657454', 9), 4294967296L) 163 self.assertEqual(int('4294967296', 10), 4294967296L) 164 self.assertEqual(int('1904440554', 11), 4294967296L) 165 self.assertEqual(int('9ba461594', 12), 4294967296L) 166 self.assertEqual(int('535a79889', 13), 4294967296L) 167 self.assertEqual(int('2ca5b7464', 14), 4294967296L) 168 self.assertEqual(int('1a20dcd81', 15), 4294967296L) 169 self.assertEqual(int('100000000', 16), 4294967296L) 170 self.assertEqual(int('a7ffda91', 17), 4294967296L) 171 self.assertEqual(int('704he7g4', 18), 4294967296L) 172 self.assertEqual(int('4f5aff66', 19), 4294967296L) 173 self.assertEqual(int('3723ai4g', 20), 4294967296L) 174 self.assertEqual(int('281d55i4', 21), 4294967296L) 175 self.assertEqual(int('1fj8b184', 22), 4294967296L) 176 self.assertEqual(int('1606k7ic', 23), 4294967296L) 177 self.assertEqual(int('mb994ag', 24), 4294967296L) 178 self.assertEqual(int('hek2mgl', 25), 4294967296L) 179 self.assertEqual(int('dnchbnm', 26), 4294967296L) 180 self.assertEqual(int('b28jpdm', 27), 4294967296L) 181 self.assertEqual(int('8pfgih4', 28), 4294967296L) 182 self.assertEqual(int('76beigg', 29), 4294967296L) 183 self.assertEqual(int('5qmcpqg', 30), 4294967296L) 184 self.assertEqual(int('4q0jto4', 31), 4294967296L) 185 self.assertEqual(int('4000000', 32), 4294967296L) 186 self.assertEqual(int('3aokq94', 33), 4294967296L) 187 self.assertEqual(int('2qhxjli', 34), 4294967296L) 188 self.assertEqual(int('2br45qb', 35), 4294967296L) 189 self.assertEqual(int('1z141z4', 36), 4294967296L) 190 191 # tests with base 0 192 # this fails on 3.0, but in 2.x the old octal syntax is allowed 193 self.assertEqual(int(' 0123 ', 0), 83) 194 self.assertEqual(int(' 0123 ', 0), 83) 195 self.assertEqual(int('000', 0), 0) 196 self.assertEqual(int('0o123', 0), 83) 197 self.assertEqual(int('0x123', 0), 291) 198 self.assertEqual(int('0b100', 0), 4) 199 self.assertEqual(int(' 0O123 ', 0), 83) 200 self.assertEqual(int(' 0X123 ', 0), 291) 201 self.assertEqual(int(' 0B100 ', 0), 4) 202 self.assertEqual(int('0', 0), 0) 203 self.assertEqual(int('+0', 0), 0) 204 self.assertEqual(int('-0', 0), 0) 205 self.assertEqual(int('00', 0), 0) 206 self.assertRaises(ValueError, int, '08', 0) 207 self.assertRaises(ValueError, int, '-012395', 0) 208 209 # without base still base 10 210 self.assertEqual(int('0123'), 123) 211 self.assertEqual(int('0123', 10), 123) 212 213 # tests with prefix and base != 0 214 self.assertEqual(int('0x123', 16), 291) 215 self.assertEqual(int('0o123', 8), 83) 216 self.assertEqual(int('0b100', 2), 4) 217 self.assertEqual(int('0X123', 16), 291) 218 self.assertEqual(int('0O123', 8), 83) 219 self.assertEqual(int('0B100', 2), 4) 220 221 # the code has special checks for the first character after the 222 # type prefix 223 self.assertRaises(ValueError, int, '0b2', 2) 224 self.assertRaises(ValueError, int, '0b02', 2) 225 self.assertRaises(ValueError, int, '0B2', 2) 226 self.assertRaises(ValueError, int, '0B02', 2) 227 self.assertRaises(ValueError, int, '0o8', 8) 228 self.assertRaises(ValueError, int, '0o08', 8) 229 self.assertRaises(ValueError, int, '0O8', 8) 230 self.assertRaises(ValueError, int, '0O08', 8) 231 self.assertRaises(ValueError, int, '0xg', 16) 232 self.assertRaises(ValueError, int, '0x0g', 16) 233 self.assertRaises(ValueError, int, '0Xg', 16) 234 self.assertRaises(ValueError, int, '0X0g', 16) 235 236 # SF bug 1334662: int(string, base) wrong answers 237 # Checks for proper evaluation of 2**32 + 1 238 self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297L) 239 self.assertEqual(int('102002022201221111212', 3), 4294967297L) 240 self.assertEqual(int('10000000000000001', 4), 4294967297L) 241 self.assertEqual(int('32244002423142', 5), 4294967297L) 242 self.assertEqual(int('1550104015505', 6), 4294967297L) 243 self.assertEqual(int('211301422355', 7), 4294967297L) 244 self.assertEqual(int('40000000001', 8), 4294967297L) 245 self.assertEqual(int('12068657455', 9), 4294967297L) 246 self.assertEqual(int('4294967297', 10), 4294967297L) 247 self.assertEqual(int('1904440555', 11), 4294967297L) 248 self.assertEqual(int('9ba461595', 12), 4294967297L) 249 self.assertEqual(int('535a7988a', 13), 4294967297L) 250 self.assertEqual(int('2ca5b7465', 14), 4294967297L) 251 self.assertEqual(int('1a20dcd82', 15), 4294967297L) 252 self.assertEqual(int('100000001', 16), 4294967297L) 253 self.assertEqual(int('a7ffda92', 17), 4294967297L) 254 self.assertEqual(int('704he7g5', 18), 4294967297L) 255 self.assertEqual(int('4f5aff67', 19), 4294967297L) 256 self.assertEqual(int('3723ai4h', 20), 4294967297L) 257 self.assertEqual(int('281d55i5', 21), 4294967297L) 258 self.assertEqual(int('1fj8b185', 22), 4294967297L) 259 self.assertEqual(int('1606k7id', 23), 4294967297L) 260 self.assertEqual(int('mb994ah', 24), 4294967297L) 261 self.assertEqual(int('hek2mgm', 25), 4294967297L) 262 self.assertEqual(int('dnchbnn', 26), 4294967297L) 263 self.assertEqual(int('b28jpdn', 27), 4294967297L) 264 self.assertEqual(int('8pfgih5', 28), 4294967297L) 265 self.assertEqual(int('76beigh', 29), 4294967297L) 266 self.assertEqual(int('5qmcpqh', 30), 4294967297L) 267 self.assertEqual(int('4q0jto5', 31), 4294967297L) 268 self.assertEqual(int('4000001', 32), 4294967297L) 269 self.assertEqual(int('3aokq95', 33), 4294967297L) 270 self.assertEqual(int('2qhxjlj', 34), 4294967297L) 271 self.assertEqual(int('2br45qc', 35), 4294967297L) 272 self.assertEqual(int('1z141z5', 36), 4294967297L) 273 274 def test_bit_length(self): 275 tiny = 1e-10 276 for x in xrange(-65000, 65000): 277 k = x.bit_length() 278 # Check equivalence with Python version 279 self.assertEqual(k, len(bin(x).lstrip('-0b'))) 280 # Behaviour as specified in the docs 281 if x != 0: 282 self.assertTrue(2**(k-1) <= abs(x) < 2**k) 283 else: 284 self.assertEqual(k, 0) 285 # Alternative definition: x.bit_length() == 1 + floor(log_2(x)) 286 if x != 0: 287 # When x is an exact power of 2, numeric errors can 288 # cause floor(log(x)/log(2)) to be one too small; for 289 # small x this can be fixed by adding a small quantity 290 # to the quotient before taking the floor. 291 self.assertEqual(k, 1 + math.floor( 292 math.log(abs(x))/math.log(2) + tiny)) 293 294 self.assertEqual((0).bit_length(), 0) 295 self.assertEqual((1).bit_length(), 1) 296 self.assertEqual((-1).bit_length(), 1) 297 self.assertEqual((2).bit_length(), 2) 298 self.assertEqual((-2).bit_length(), 2) 299 for i in [2, 3, 15, 16, 17, 31, 32, 33, 63, 64]: 300 a = 2**i 301 self.assertEqual((a-1).bit_length(), i) 302 self.assertEqual((1-a).bit_length(), i) 303 self.assertEqual((a).bit_length(), i+1) 304 self.assertEqual((-a).bit_length(), i+1) 305 self.assertEqual((a+1).bit_length(), i+1) 306 self.assertEqual((-a-1).bit_length(), i+1) 307 308 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), 309 "test requires IEEE 754 doubles") 310 def test_float_conversion(self): 311 # values exactly representable as floats 312 exact_values = [-2, -1, 0, 1, 2, 2**52, 2**53-1, 2**53, 2**53+2, 313 2**53+4, 2**54-4, 2**54-2, 2**63, -2**63, 2**64, 314 -2**64, 10**20, 10**21, 10**22] 315 for value in exact_values: 316 self.assertEqual(int(float(int(value))), value) 317 318 # test round-half-to-even 319 self.assertEqual(int(float(2**53+1)), 2**53) 320 self.assertEqual(int(float(2**53+2)), 2**53+2) 321 self.assertEqual(int(float(2**53+3)), 2**53+4) 322 self.assertEqual(int(float(2**53+5)), 2**53+4) 323 self.assertEqual(int(float(2**53+6)), 2**53+6) 324 self.assertEqual(int(float(2**53+7)), 2**53+8) 325 326 self.assertEqual(int(float(-2**53-1)), -2**53) 327 self.assertEqual(int(float(-2**53-2)), -2**53-2) 328 self.assertEqual(int(float(-2**53-3)), -2**53-4) 329 self.assertEqual(int(float(-2**53-5)), -2**53-4) 330 self.assertEqual(int(float(-2**53-6)), -2**53-6) 331 self.assertEqual(int(float(-2**53-7)), -2**53-8) 332 333 self.assertEqual(int(float(2**54-2)), 2**54-2) 334 self.assertEqual(int(float(2**54-1)), 2**54) 335 self.assertEqual(int(float(2**54+2)), 2**54) 336 self.assertEqual(int(float(2**54+3)), 2**54+4) 337 self.assertEqual(int(float(2**54+5)), 2**54+4) 338 self.assertEqual(int(float(2**54+6)), 2**54+8) 339 self.assertEqual(int(float(2**54+10)), 2**54+8) 340 self.assertEqual(int(float(2**54+11)), 2**54+12) 341 342 def test_valid_non_numeric_input_types_for_x(self): 343 # Test possible valid non-numeric types for x, including subclasses 344 # of the allowed built-in types. 345 class CustomStr(str): pass 346 class CustomByteArray(bytearray): pass 347 factories = [str, bytearray, CustomStr, CustomByteArray, buffer] 348 349 if have_unicode: 350 class CustomUnicode(unicode): pass 351 factories += [unicode, CustomUnicode] 352 353 for f in factories: 354 x = f('100') 355 msg = 'x has value %s and type %s' % (x, type(x).__name__) 356 try: 357 self.assertEqual(int(x), 100, msg=msg) 358 if isinstance(x, basestring): 359 self.assertEqual(int(x, 2), 4, msg=msg) 360 except TypeError, err: 361 raise AssertionError('For %s got TypeError: %s' % 362 (type(x).__name__, err)) 363 if not isinstance(x, basestring): 364 errmsg = "can't convert non-string" 365 with self.assertRaisesRegexp(TypeError, errmsg, msg=msg): 366 int(x, 2) 367 errmsg = 'invalid literal' 368 with self.assertRaisesRegexp(ValueError, errmsg, msg=msg): 369 int(f('A' * 0x10)) 370 371 def test_int_buffer(self): 372 self.assertEqual(int(buffer('123', 1, 2)), 23) 373 self.assertEqual(int(buffer('123\x00', 1, 2)), 23) 374 self.assertEqual(int(buffer('123 ', 1, 2)), 23) 375 self.assertEqual(int(buffer('123A', 1, 2)), 23) 376 self.assertEqual(int(buffer('1234', 1, 2)), 23) 377 378 def test_error_on_string_float_for_x(self): 379 self.assertRaises(ValueError, int, '1.2') 380 381 def test_error_on_bytearray_for_x(self): 382 self.assertRaises(TypeError, int, bytearray('100'), 2) 383 384 def test_error_on_invalid_int_bases(self): 385 for base in [-1, 1, 1000]: 386 self.assertRaises(ValueError, int, '100', base) 387 388 def test_error_on_string_base(self): 389 self.assertRaises(TypeError, int, 100, base='foo') 390 391 @test_support.cpython_only 392 def test_small_ints(self): 393 self.assertIs(int('10'), 10) 394 self.assertIs(int('-1'), -1) 395 if have_unicode: 396 self.assertIs(int(u'10'), 10) 397 self.assertIs(int(u'-1'), -1) 398 399 def test_intconversion(self): 400 # Test __int__() 401 class ClassicMissingMethods: 402 pass 403 self.assertRaises(AttributeError, int, ClassicMissingMethods()) 404 405 class MissingMethods(object): 406 pass 407 self.assertRaises(TypeError, int, MissingMethods()) 408 409 class Foo0: 410 def __int__(self): 411 return 42 412 413 class Foo1(object): 414 def __int__(self): 415 return 42 416 417 class Foo2(int): 418 def __int__(self): 419 return 42 420 421 class Foo3(int): 422 def __int__(self): 423 return self 424 425 class Foo4(int): 426 def __int__(self): 427 return 42L 428 429 class Foo5(int): 430 def __int__(self): 431 return 42. 432 433 self.assertEqual(int(Foo0()), 42) 434 self.assertEqual(int(Foo1()), 42) 435 self.assertEqual(int(Foo2()), 42) 436 self.assertEqual(int(Foo3()), 0) 437 self.assertEqual(int(Foo4()), 42L) 438 self.assertRaises(TypeError, int, Foo5()) 439 440 class Classic: 441 pass 442 for base in (object, Classic): 443 class IntOverridesTrunc(base): 444 def __int__(self): 445 return 42 446 def __trunc__(self): 447 return -12 448 self.assertEqual(int(IntOverridesTrunc()), 42) 449 450 class JustTrunc(base): 451 def __trunc__(self): 452 return 42 453 self.assertEqual(int(JustTrunc()), 42) 454 455 for trunc_result_base in (object, Classic): 456 class Integral(trunc_result_base): 457 def __int__(self): 458 return 42 459 460 class TruncReturnsNonInt(base): 461 def __trunc__(self): 462 return Integral() 463 self.assertEqual(int(TruncReturnsNonInt()), 42) 464 465 class NonIntegral(trunc_result_base): 466 def __trunc__(self): 467 # Check that we avoid infinite recursion. 468 return NonIntegral() 469 470 class TruncReturnsNonIntegral(base): 471 def __trunc__(self): 472 return NonIntegral() 473 try: 474 int(TruncReturnsNonIntegral()) 475 except TypeError as e: 476 self.assertEqual(str(e), 477 "__trunc__ returned non-Integral" 478 " (type NonIntegral)") 479 else: 480 self.fail("Failed to raise TypeError with %s" % 481 ((base, trunc_result_base),)) 482 483 class TruncReturnsIntSubclass(base): 484 def __trunc__(self): 485 return True 486 good_int = TruncReturnsIntSubclass() 487 n = int(good_int) 488 self.assertEqual(n, 1) 489 self.assertIs(type(n), bool) 490 n = IntSubclass(good_int) 491 self.assertEqual(n, 1) 492 self.assertIs(type(n), IntSubclass) 493 494 495def test_main(): 496 run_unittest(IntTestCases) 497 498if __name__ == "__main__": 499 test_main() 500