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