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