blob: 045ef7c76adc86322be6b53859f9f3016ec2e988 [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
Chris Jerdonek6f70fe82012-12-27 12:53:29 -080048class 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
Benjamin Peterson979395b2008-05-03 21:35:18 +000067
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)
Ezio Melottib0f5adc2010-01-24 16:58:36 +000098 self.assertIsInstance(x, int)
Benjamin Peterson979395b2008-05-03 21:35:18 +000099 # should return long
100 self.assertEqual(int(s[1:]), sys.maxint+1)
101
102 # should return long
103 x = int(1e100)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000104 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000105 x = int(-1e100)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000106 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000107
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)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000124 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000125
126 if have_unicode:
127 x = int(unichr(0x661) * 600)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000128 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000129
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)
Mark Dickinson784a47f2010-05-26 19:06:33 +0000197 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)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000203
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
Mark Dickinson1a707982008-12-17 16:14:37 +0000269 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:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000277 self.assertTrue(2**(k-1) <= abs(x) < 2**k)
Mark Dickinson1a707982008-12-17 16:14:37 +0000278 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
Mark Dickinson6736cf82009-04-20 21:13:33 +0000303 @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
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200337 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
Benjamin Peterson979395b2008-05-03 21:35:18 +0000381 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:
Ezio Melotti2623a372010-11-21 13:34:58 +0000458 self.assertEqual(str(e),
Benjamin Peterson979395b2008-05-03 21:35:18 +0000459 "__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()