blob: 365f9a247c9ea441f44bd670b68588a9f0ba8e40 [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)
Serhiy Storchakacf095f82012-12-28 09:31:59 +020063 self.assertRaises(TypeError, self.ntype, base=10)
64 self.assertRaises(TypeError, self.ntype, base=0)
Chris Jerdonek6f70fe82012-12-27 12:53:29 -080065
66class IntTestCases(IntLongCommonTests, unittest.TestCase):
67
68 ntype = int
Benjamin Peterson979395b2008-05-03 21:35:18 +000069
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)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000100 self.assertIsInstance(x, int)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000101 # should return long
102 self.assertEqual(int(s[1:]), sys.maxint+1)
103
104 # should return long
105 x = int(1e100)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000106 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000107 x = int(-1e100)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000108 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000109
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)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000126 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000127
128 if have_unicode:
129 x = int(unichr(0x661) * 600)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000130 self.assertIsInstance(x, long)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000131
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)
Mark Dickinson784a47f2010-05-26 19:06:33 +0000199 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)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000205
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
Mark Dickinson1a707982008-12-17 16:14:37 +0000271 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:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000279 self.assertTrue(2**(k-1) <= abs(x) < 2**k)
Mark Dickinson1a707982008-12-17 16:14:37 +0000280 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
Mark Dickinson6736cf82009-04-20 21:13:33 +0000305 @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
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200339 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:
Serhiy Storchaka88761452012-12-28 00:32:19 +0200352 self.assertEqual(int(x), 100, msg=msg)
353 self.assertEqual(int(x, 2), 4, msg=msg)
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200354 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')
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200370
Serhiy Storchaka270767b2012-12-27 23:07:00 +0200371 @test_support.cpython_only
372 def test_small_ints(self):
Serhiy Storchakac90be302012-12-28 00:44:20 +0200373 self.assertIs(int('10'), 10)
374 self.assertIs(int('-1'), -1)
Serhiy Storchaka270767b2012-12-27 23:07:00 +0200375 if have_unicode:
Serhiy Storchakac90be302012-12-28 00:44:20 +0200376 self.assertIs(int(u'10'), 10)
377 self.assertIs(int(u'-1'), -1)
Serhiy Storchaka270767b2012-12-27 23:07:00 +0200378
Benjamin Peterson979395b2008-05-03 21:35:18 +0000379 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:
Ezio Melotti2623a372010-11-21 13:34:58 +0000456 self.assertEqual(str(e),
Benjamin Peterson979395b2008-05-03 21:35:18 +0000457 "__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()