blob: 2ca6cf2f529f1af698ee048b68151e866bdf12a3 [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
Serhiy Storchaka61565602015-11-20 21:56:21 +0200343 class CustomByteArray(bytearray): pass
344 factories = [str, bytearray, CustomStr, CustomByteArray, buffer]
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200345
346 if have_unicode:
347 class CustomUnicode(unicode): pass
Serhiy Storchaka61565602015-11-20 21:56:21 +0200348 factories += [unicode, CustomUnicode]
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200349
Serhiy Storchaka61565602015-11-20 21:56:21 +0200350 for f in factories:
351 x = f('100')
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200352 msg = 'x has value %s and type %s' % (x, type(x).__name__)
353 try:
Serhiy Storchaka88761452012-12-28 00:32:19 +0200354 self.assertEqual(int(x), 100, msg=msg)
Serhiy Storchaka61565602015-11-20 21:56:21 +0200355 if isinstance(x, basestring):
356 self.assertEqual(int(x, 2), 4, msg=msg)
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200357 except TypeError, err:
358 raise AssertionError('For %s got TypeError: %s' %
359 (type(x).__name__, err))
Serhiy Storchaka61565602015-11-20 21:56:21 +0200360 if not isinstance(x, basestring):
361 errmsg = "can't convert non-string"
362 with self.assertRaisesRegexp(TypeError, errmsg, msg=msg):
363 int(x, 2)
364 errmsg = 'invalid literal'
365 with self.assertRaisesRegexp(ValueError, errmsg, msg=msg):
366 int(f('A' * 0x10))
367
368 def test_int_buffer(self):
369 self.assertEqual(int(buffer('123', 1, 2)), 23)
370 self.assertEqual(int(buffer('123\x00', 1, 2)), 23)
371 self.assertEqual(int(buffer('123 ', 1, 2)), 23)
372 self.assertEqual(int(buffer('123A', 1, 2)), 23)
373 self.assertEqual(int(buffer('1234', 1, 2)), 23)
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200374
375 def test_error_on_string_float_for_x(self):
376 self.assertRaises(ValueError, int, '1.2')
377
378 def test_error_on_bytearray_for_x(self):
379 self.assertRaises(TypeError, int, bytearray('100'), 2)
380
381 def test_error_on_invalid_int_bases(self):
382 for base in [-1, 1, 1000]:
383 self.assertRaises(ValueError, int, '100', base)
384
385 def test_error_on_string_base(self):
386 self.assertRaises(TypeError, int, 100, base='foo')
Andrew Svetlovcddcafa2012-12-23 12:44:04 +0200387
Serhiy Storchaka270767b2012-12-27 23:07:00 +0200388 @test_support.cpython_only
389 def test_small_ints(self):
Serhiy Storchakac90be302012-12-28 00:44:20 +0200390 self.assertIs(int('10'), 10)
391 self.assertIs(int('-1'), -1)
Serhiy Storchaka270767b2012-12-27 23:07:00 +0200392 if have_unicode:
Serhiy Storchakac90be302012-12-28 00:44:20 +0200393 self.assertIs(int(u'10'), 10)
394 self.assertIs(int(u'-1'), -1)
Serhiy Storchaka270767b2012-12-27 23:07:00 +0200395
Benjamin Peterson979395b2008-05-03 21:35:18 +0000396 def test_intconversion(self):
397 # Test __int__()
398 class ClassicMissingMethods:
399 pass
400 self.assertRaises(AttributeError, int, ClassicMissingMethods())
401
402 class MissingMethods(object):
403 pass
404 self.assertRaises(TypeError, int, MissingMethods())
405
406 class Foo0:
407 def __int__(self):
408 return 42
409
410 class Foo1(object):
411 def __int__(self):
412 return 42
413
414 class Foo2(int):
415 def __int__(self):
416 return 42
417
418 class Foo3(int):
419 def __int__(self):
420 return self
421
422 class Foo4(int):
423 def __int__(self):
424 return 42L
425
426 class Foo5(int):
427 def __int__(self):
428 return 42.
429
430 self.assertEqual(int(Foo0()), 42)
431 self.assertEqual(int(Foo1()), 42)
432 self.assertEqual(int(Foo2()), 42)
433 self.assertEqual(int(Foo3()), 0)
434 self.assertEqual(int(Foo4()), 42L)
435 self.assertRaises(TypeError, int, Foo5())
436
437 class Classic:
438 pass
439 for base in (object, Classic):
440 class IntOverridesTrunc(base):
441 def __int__(self):
442 return 42
443 def __trunc__(self):
444 return -12
445 self.assertEqual(int(IntOverridesTrunc()), 42)
446
447 class JustTrunc(base):
448 def __trunc__(self):
449 return 42
450 self.assertEqual(int(JustTrunc()), 42)
451
452 for trunc_result_base in (object, Classic):
453 class Integral(trunc_result_base):
454 def __int__(self):
455 return 42
456
457 class TruncReturnsNonInt(base):
458 def __trunc__(self):
459 return Integral()
460 self.assertEqual(int(TruncReturnsNonInt()), 42)
461
462 class NonIntegral(trunc_result_base):
463 def __trunc__(self):
464 # Check that we avoid infinite recursion.
465 return NonIntegral()
466
467 class TruncReturnsNonIntegral(base):
468 def __trunc__(self):
469 return NonIntegral()
470 try:
471 int(TruncReturnsNonIntegral())
472 except TypeError as e:
Ezio Melotti2623a372010-11-21 13:34:58 +0000473 self.assertEqual(str(e),
Benjamin Peterson979395b2008-05-03 21:35:18 +0000474 "__trunc__ returned non-Integral"
475 " (type NonIntegral)")
476 else:
477 self.fail("Failed to raise TypeError with %s" %
478 ((base, trunc_result_base),))
479
480def test_main():
481 run_unittest(IntTestCases)
482
483if __name__ == "__main__":
484 test_main()