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 values = ['100', CustomStr('100')] 344 345 if have_unicode: 346 class CustomUnicode(unicode): pass 347 values += [unicode('100'), CustomUnicode(unicode('100'))] 348 349 for x in values: 350 msg = 'x has value %s and type %s' % (x, type(x).__name__) 351 try: 352 self.assertEqual(int(x), 100, msg=msg) 353 self.assertEqual(int(x, 2), 4, msg=msg) 354 except TypeError, err: 355 raise AssertionError('For %s got TypeError: %s' % 356 (type(x).__name__, err)) 357 358 def test_error_on_string_float_for_x(self): 359 self.assertRaises(ValueError, int, '1.2') 360 361 def test_error_on_bytearray_for_x(self): 362 self.assertRaises(TypeError, int, bytearray('100'), 2) 363 364 def test_error_on_invalid_int_bases(self): 365 for base in [-1, 1, 1000]: 366 self.assertRaises(ValueError, int, '100', base) 367 368 def test_error_on_string_base(self): 369 self.assertRaises(TypeError, int, 100, base='foo') 370 371 @test_support.cpython_only 372 def test_small_ints(self): 373 self.assertIs(int('10'), 10) 374 self.assertIs(int('-1'), -1) 375 if have_unicode: 376 self.assertIs(int(u'10'), 10) 377 self.assertIs(int(u'-1'), -1) 378 379 def test_intconversion(self): 380 # Test __int__() 381 class ClassicMissingMethods: 382 pass 383 self.assertRaises(AttributeError, int, ClassicMissingMethods()) 384 385 class MissingMethods(object): 386 pass 387 self.assertRaises(TypeError, int, MissingMethods()) 388 389 class Foo0: 390 def __int__(self): 391 return 42 392 393 class Foo1(object): 394 def __int__(self): 395 return 42 396 397 class Foo2(int): 398 def __int__(self): 399 return 42 400 401 class Foo3(int): 402 def __int__(self): 403 return self 404 405 class Foo4(int): 406 def __int__(self): 407 return 42L 408 409 class Foo5(int): 410 def __int__(self): 411 return 42. 412 413 self.assertEqual(int(Foo0()), 42) 414 self.assertEqual(int(Foo1()), 42) 415 self.assertEqual(int(Foo2()), 42) 416 self.assertEqual(int(Foo3()), 0) 417 self.assertEqual(int(Foo4()), 42L) 418 self.assertRaises(TypeError, int, Foo5()) 419 420 class Classic: 421 pass 422 for base in (object, Classic): 423 class IntOverridesTrunc(base): 424 def __int__(self): 425 return 42 426 def __trunc__(self): 427 return -12 428 self.assertEqual(int(IntOverridesTrunc()), 42) 429 430 class JustTrunc(base): 431 def __trunc__(self): 432 return 42 433 self.assertEqual(int(JustTrunc()), 42) 434 435 for trunc_result_base in (object, Classic): 436 class Integral(trunc_result_base): 437 def __int__(self): 438 return 42 439 440 class TruncReturnsNonInt(base): 441 def __trunc__(self): 442 return Integral() 443 self.assertEqual(int(TruncReturnsNonInt()), 42) 444 445 class NonIntegral(trunc_result_base): 446 def __trunc__(self): 447 # Check that we avoid infinite recursion. 448 return NonIntegral() 449 450 class TruncReturnsNonIntegral(base): 451 def __trunc__(self): 452 return NonIntegral() 453 try: 454 int(TruncReturnsNonIntegral()) 455 except TypeError as e: 456 self.assertEqual(str(e), 457 "__trunc__ returned non-Integral" 458 " (type NonIntegral)") 459 else: 460 self.fail("Failed to raise TypeError with %s" % 461 ((base, trunc_result_base),)) 462 463def test_main(): 464 run_unittest(IntTestCases) 465 466if __name__ == "__main__": 467 test_main() 468