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