blob: 14bbd6192a0572df887fe90dcfa4e2775a4120c2 [file] [log] [blame]
Christian Heimes81ee3ef2008-05-04 22:42:01 +00001import sys
2
3import unittest
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +02004from test import support
Brett Cannona721aba2016-09-09 14:57:09 -07005from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
6 INVALID_UNDERSCORE_LITERALS)
Christian Heimes81ee3ef2008-05-04 22:42:01 +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.maxsize), sys.maxsize),
20 (' 1x', ValueError),
21 (' 1 ', 1),
22 (' 1\02 ', ValueError),
23 ('', ValueError),
24 (' ', ValueError),
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000025 (' \t\t ', ValueError),
26 ("\u0200", ValueError)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000027]
28
Serhiy Storchaka15095802015-11-25 15:47:01 +020029class IntSubclass(int):
30 pass
31
Christian Heimes81ee3ef2008-05-04 22:42:01 +000032class IntTestCases(unittest.TestCase):
33
34 def test_basic(self):
35 self.assertEqual(int(314), 314)
36 self.assertEqual(int(3.14), 3)
37 # Check that conversion from float truncates towards zero
38 self.assertEqual(int(-3.14), -3)
39 self.assertEqual(int(3.9), 3)
40 self.assertEqual(int(-3.9), -3)
41 self.assertEqual(int(3.5), 3)
42 self.assertEqual(int(-3.5), -3)
Mark Dickinson5c2db372009-12-05 20:28:34 +000043 self.assertEqual(int("-3"), -3)
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000044 self.assertEqual(int(" -3 "), -3)
45 self.assertEqual(int("\N{EM SPACE}-3\N{EN SPACE}"), -3)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000046 # Different base:
47 self.assertEqual(int("10",16), 16)
48 # Test conversion from strings and various anomalies
49 for s, v in L:
50 for sign in "", "+", "-":
51 for prefix in "", " ", "\t", " \t\t ":
52 ss = prefix + sign + s
53 vv = v
54 if sign == "-" and v is not ValueError:
55 vv = -v
56 try:
57 self.assertEqual(int(ss), vv)
58 except ValueError:
59 pass
60
61 s = repr(-1-sys.maxsize)
62 x = int(s)
63 self.assertEqual(x+1, -sys.maxsize)
Ezio Melottie9615932010-01-24 19:26:24 +000064 self.assertIsInstance(x, int)
65 # should return int
Christian Heimes81ee3ef2008-05-04 22:42:01 +000066 self.assertEqual(int(s[1:]), sys.maxsize+1)
67
Ezio Melottie9615932010-01-24 19:26:24 +000068 # should return int
Christian Heimes81ee3ef2008-05-04 22:42:01 +000069 x = int(1e100)
Ezio Melottie9615932010-01-24 19:26:24 +000070 self.assertIsInstance(x, int)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000071 x = int(-1e100)
Ezio Melottie9615932010-01-24 19:26:24 +000072 self.assertIsInstance(x, int)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000073
74
75 # SF bug 434186: 0x80000000/2 != 0x80000000>>1.
76 # Worked by accident in Windows release build, but failed in debug build.
77 # Failed in all Linux builds.
78 x = -1-sys.maxsize
79 self.assertEqual(x >> 1, x//2)
80
Christian Heimes81ee3ef2008-05-04 22:42:01 +000081 x = int('1' * 600)
Ezio Melottie9615932010-01-24 19:26:24 +000082 self.assertIsInstance(x, int)
83
Christian Heimes81ee3ef2008-05-04 22:42:01 +000084
85 self.assertRaises(TypeError, int, 1, 12)
86
87 self.assertEqual(int('0o123', 0), 83)
88 self.assertEqual(int('0x123', 16), 291)
89
90 # Bug 1679: "0x" is not a valid hex literal
91 self.assertRaises(ValueError, int, "0x", 16)
92 self.assertRaises(ValueError, int, "0x", 0)
93
94 self.assertRaises(ValueError, int, "0o", 8)
95 self.assertRaises(ValueError, int, "0o", 0)
96
97 self.assertRaises(ValueError, int, "0b", 2)
98 self.assertRaises(ValueError, int, "0b", 0)
99
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000100 # SF bug 1334662: int(string, base) wrong answers
101 # Various representations of 2**32 evaluated to 0
102 # rather than 2**32 in previous versions
103
104 self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296)
105 self.assertEqual(int('102002022201221111211', 3), 4294967296)
106 self.assertEqual(int('10000000000000000', 4), 4294967296)
107 self.assertEqual(int('32244002423141', 5), 4294967296)
108 self.assertEqual(int('1550104015504', 6), 4294967296)
109 self.assertEqual(int('211301422354', 7), 4294967296)
110 self.assertEqual(int('40000000000', 8), 4294967296)
111 self.assertEqual(int('12068657454', 9), 4294967296)
112 self.assertEqual(int('4294967296', 10), 4294967296)
113 self.assertEqual(int('1904440554', 11), 4294967296)
114 self.assertEqual(int('9ba461594', 12), 4294967296)
115 self.assertEqual(int('535a79889', 13), 4294967296)
116 self.assertEqual(int('2ca5b7464', 14), 4294967296)
117 self.assertEqual(int('1a20dcd81', 15), 4294967296)
118 self.assertEqual(int('100000000', 16), 4294967296)
119 self.assertEqual(int('a7ffda91', 17), 4294967296)
120 self.assertEqual(int('704he7g4', 18), 4294967296)
121 self.assertEqual(int('4f5aff66', 19), 4294967296)
122 self.assertEqual(int('3723ai4g', 20), 4294967296)
123 self.assertEqual(int('281d55i4', 21), 4294967296)
124 self.assertEqual(int('1fj8b184', 22), 4294967296)
125 self.assertEqual(int('1606k7ic', 23), 4294967296)
126 self.assertEqual(int('mb994ag', 24), 4294967296)
127 self.assertEqual(int('hek2mgl', 25), 4294967296)
128 self.assertEqual(int('dnchbnm', 26), 4294967296)
129 self.assertEqual(int('b28jpdm', 27), 4294967296)
130 self.assertEqual(int('8pfgih4', 28), 4294967296)
131 self.assertEqual(int('76beigg', 29), 4294967296)
132 self.assertEqual(int('5qmcpqg', 30), 4294967296)
133 self.assertEqual(int('4q0jto4', 31), 4294967296)
134 self.assertEqual(int('4000000', 32), 4294967296)
135 self.assertEqual(int('3aokq94', 33), 4294967296)
136 self.assertEqual(int('2qhxjli', 34), 4294967296)
137 self.assertEqual(int('2br45qb', 35), 4294967296)
138 self.assertEqual(int('1z141z4', 36), 4294967296)
139
140 # tests with base 0
141 # this fails on 3.0, but in 2.x the old octal syntax is allowed
142 self.assertEqual(int(' 0o123 ', 0), 83)
143 self.assertEqual(int(' 0o123 ', 0), 83)
144 self.assertEqual(int('000', 0), 0)
145 self.assertEqual(int('0o123', 0), 83)
146 self.assertEqual(int('0x123', 0), 291)
147 self.assertEqual(int('0b100', 0), 4)
148 self.assertEqual(int(' 0O123 ', 0), 83)
149 self.assertEqual(int(' 0X123 ', 0), 291)
150 self.assertEqual(int(' 0B100 ', 0), 4)
151
152 # without base still base 10
153 self.assertEqual(int('0123'), 123)
154 self.assertEqual(int('0123', 10), 123)
155
156 # tests with prefix and base != 0
157 self.assertEqual(int('0x123', 16), 291)
158 self.assertEqual(int('0o123', 8), 83)
159 self.assertEqual(int('0b100', 2), 4)
160 self.assertEqual(int('0X123', 16), 291)
161 self.assertEqual(int('0O123', 8), 83)
162 self.assertEqual(int('0B100', 2), 4)
163
164 # the code has special checks for the first character after the
165 # type prefix
166 self.assertRaises(ValueError, int, '0b2', 2)
167 self.assertRaises(ValueError, int, '0b02', 2)
168 self.assertRaises(ValueError, int, '0B2', 2)
169 self.assertRaises(ValueError, int, '0B02', 2)
170 self.assertRaises(ValueError, int, '0o8', 8)
171 self.assertRaises(ValueError, int, '0o08', 8)
172 self.assertRaises(ValueError, int, '0O8', 8)
173 self.assertRaises(ValueError, int, '0O08', 8)
174 self.assertRaises(ValueError, int, '0xg', 16)
175 self.assertRaises(ValueError, int, '0x0g', 16)
176 self.assertRaises(ValueError, int, '0Xg', 16)
177 self.assertRaises(ValueError, int, '0X0g', 16)
178
179 # SF bug 1334662: int(string, base) wrong answers
180 # Checks for proper evaluation of 2**32 + 1
181 self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297)
182 self.assertEqual(int('102002022201221111212', 3), 4294967297)
183 self.assertEqual(int('10000000000000001', 4), 4294967297)
184 self.assertEqual(int('32244002423142', 5), 4294967297)
185 self.assertEqual(int('1550104015505', 6), 4294967297)
186 self.assertEqual(int('211301422355', 7), 4294967297)
187 self.assertEqual(int('40000000001', 8), 4294967297)
188 self.assertEqual(int('12068657455', 9), 4294967297)
189 self.assertEqual(int('4294967297', 10), 4294967297)
190 self.assertEqual(int('1904440555', 11), 4294967297)
191 self.assertEqual(int('9ba461595', 12), 4294967297)
192 self.assertEqual(int('535a7988a', 13), 4294967297)
193 self.assertEqual(int('2ca5b7465', 14), 4294967297)
194 self.assertEqual(int('1a20dcd82', 15), 4294967297)
195 self.assertEqual(int('100000001', 16), 4294967297)
196 self.assertEqual(int('a7ffda92', 17), 4294967297)
197 self.assertEqual(int('704he7g5', 18), 4294967297)
198 self.assertEqual(int('4f5aff67', 19), 4294967297)
199 self.assertEqual(int('3723ai4h', 20), 4294967297)
200 self.assertEqual(int('281d55i5', 21), 4294967297)
201 self.assertEqual(int('1fj8b185', 22), 4294967297)
202 self.assertEqual(int('1606k7id', 23), 4294967297)
203 self.assertEqual(int('mb994ah', 24), 4294967297)
204 self.assertEqual(int('hek2mgm', 25), 4294967297)
205 self.assertEqual(int('dnchbnn', 26), 4294967297)
206 self.assertEqual(int('b28jpdn', 27), 4294967297)
207 self.assertEqual(int('8pfgih5', 28), 4294967297)
208 self.assertEqual(int('76beigh', 29), 4294967297)
209 self.assertEqual(int('5qmcpqh', 30), 4294967297)
210 self.assertEqual(int('4q0jto5', 31), 4294967297)
211 self.assertEqual(int('4000001', 32), 4294967297)
212 self.assertEqual(int('3aokq95', 33), 4294967297)
213 self.assertEqual(int('2qhxjlj', 34), 4294967297)
214 self.assertEqual(int('2br45qc', 35), 4294967297)
215 self.assertEqual(int('1z141z5', 36), 4294967297)
216
Brett Cannona721aba2016-09-09 14:57:09 -0700217 def test_underscores(self):
218 for lit in VALID_UNDERSCORE_LITERALS:
219 if any(ch in lit for ch in '.eEjJ'):
220 continue
221 self.assertEqual(int(lit, 0), eval(lit))
222 self.assertEqual(int(lit, 0), int(lit.replace('_', ''), 0))
223 for lit in INVALID_UNDERSCORE_LITERALS:
224 if any(ch in lit for ch in '.eEjJ'):
225 continue
226 self.assertRaises(ValueError, int, lit, 0)
227 # Additional test cases with bases != 0, only for the constructor:
228 self.assertEqual(int("1_00", 3), 9)
229 self.assertEqual(int("0_100"), 100) # not valid as a literal!
230 self.assertEqual(int(b"1_00"), 100) # byte underscore
231 self.assertRaises(ValueError, int, "_100")
232 self.assertRaises(ValueError, int, "+_100")
233 self.assertRaises(ValueError, int, "1__00")
234 self.assertRaises(ValueError, int, "100_")
235
Serhiy Storchaka3b317042012-12-27 23:57:00 +0200236 @support.cpython_only
237 def test_small_ints(self):
238 # Bug #3236: Return small longs from PyLong_FromString
239 self.assertIs(int('10'), 10)
240 self.assertIs(int('-1'), -1)
241 self.assertIs(int(b'10'), 10)
242 self.assertIs(int(b'-1'), -1)
243
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200244 def test_no_args(self):
Serhiy Storchakaa29159b2012-12-28 00:34:57 +0200245 self.assertEqual(int(), 0)
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200246
247 def test_keyword_args(self):
248 # Test invoking int() using keyword arguments.
Serhiy Storchakaa29159b2012-12-28 00:34:57 +0200249 self.assertEqual(int(x=1.2), 1)
250 self.assertEqual(int('100', base=2), 4)
251 self.assertEqual(int(x='100', base=2), 4)
Serhiy Storchaka0b386d52012-12-28 09:42:11 +0200252 self.assertRaises(TypeError, int, base=10)
253 self.assertRaises(TypeError, int, base=0)
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200254
Gregory P. Smitha689e522012-12-25 22:38:32 -0800255 def test_int_base_limits(self):
256 """Testing the supported limits of the int() base parameter."""
257 self.assertEqual(int('0', 5), 0)
258 with self.assertRaises(ValueError):
259 int('0', 1)
260 with self.assertRaises(ValueError):
261 int('0', 37)
262 with self.assertRaises(ValueError):
263 int('0', -909) # An old magic value base from Python 2.
264 with self.assertRaises(ValueError):
265 int('0', base=0-(2**234))
266 with self.assertRaises(ValueError):
267 int('0', base=2**234)
268 # Bases 2 through 36 are supported.
269 for base in range(2,37):
270 self.assertEqual(int('0', base=base), 0)
271
272 def test_int_base_bad_types(self):
273 """Not integer types are not valid bases; issue16772."""
274 with self.assertRaises(TypeError):
275 int('0', 5.5)
276 with self.assertRaises(TypeError):
277 int('0', 5.0)
278
Mark Dickinson07c71362013-01-27 10:17:52 +0000279 def test_int_base_indexable(self):
280 class MyIndexable(object):
281 def __init__(self, value):
282 self.value = value
283 def __index__(self):
284 return self.value
285
286 # Check out of range bases.
287 for base in 2**100, -2**100, 1, 37:
288 with self.assertRaises(ValueError):
289 int('43', base)
290
291 # Check in-range bases.
292 self.assertEqual(int('101', base=MyIndexable(2)), 5)
293 self.assertEqual(int('101', base=MyIndexable(10)), 101)
294 self.assertEqual(int('101', base=MyIndexable(36)), 1 + 36**2)
295
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200296 def test_non_numeric_input_types(self):
297 # Test possible non-numeric types for the argument x, including
298 # subclasses of the explicitly documented accepted types.
299 class CustomStr(str): pass
300 class CustomBytes(bytes): pass
301 class CustomByteArray(bytearray): pass
302
Martin Pantereeb896c2015-11-07 02:32:21 +0000303 factories = [
304 bytes,
305 bytearray,
306 lambda b: CustomStr(b.decode()),
307 CustomBytes,
308 CustomByteArray,
309 memoryview,
310 ]
311 try:
312 from array import array
313 except ImportError:
314 pass
315 else:
316 factories.append(lambda b: array('B', b))
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200317
Martin Pantereeb896c2015-11-07 02:32:21 +0000318 for f in factories:
319 x = f(b'100')
320 with self.subTest(type(x)):
321 self.assertEqual(int(x), 100)
322 if isinstance(x, (str, bytes, bytearray)):
323 self.assertEqual(int(x, 2), 4)
324 else:
325 msg = "can't convert non-string"
326 with self.assertRaisesRegex(TypeError, msg):
327 int(x, 2)
328 with self.assertRaisesRegex(ValueError, 'invalid literal'):
329 int(f(b'A' * 0x10))
330
331 def test_int_memoryview(self):
332 self.assertEqual(int(memoryview(b'123')[1:3]), 23)
333 self.assertEqual(int(memoryview(b'123\x00')[1:3]), 23)
334 self.assertEqual(int(memoryview(b'123 ')[1:3]), 23)
335 self.assertEqual(int(memoryview(b'123A')[1:3]), 23)
336 self.assertEqual(int(memoryview(b'1234')[1:3]), 23)
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200337
338 def test_string_float(self):
339 self.assertRaises(ValueError, int, '1.2')
340
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000341 def test_intconversion(self):
342 # Test __int__()
343 class ClassicMissingMethods:
344 pass
345 self.assertRaises(TypeError, int, ClassicMissingMethods())
346
347 class MissingMethods(object):
348 pass
349 self.assertRaises(TypeError, int, MissingMethods())
350
351 class Foo0:
352 def __int__(self):
353 return 42
354
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000355 self.assertEqual(int(Foo0()), 42)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000356
357 class Classic:
358 pass
359 for base in (object, Classic):
360 class IntOverridesTrunc(base):
361 def __int__(self):
362 return 42
363 def __trunc__(self):
364 return -12
365 self.assertEqual(int(IntOverridesTrunc()), 42)
366
367 class JustTrunc(base):
368 def __trunc__(self):
369 return 42
370 self.assertEqual(int(JustTrunc()), 42)
371
Mark Dickinsonc9734482013-04-13 17:44:44 +0100372 class ExceptionalTrunc(base):
373 def __trunc__(self):
374 1 / 0
375 with self.assertRaises(ZeroDivisionError):
376 int(ExceptionalTrunc())
377
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000378 for trunc_result_base in (object, Classic):
379 class Integral(trunc_result_base):
380 def __int__(self):
381 return 42
382
383 class TruncReturnsNonInt(base):
384 def __trunc__(self):
385 return Integral()
386 self.assertEqual(int(TruncReturnsNonInt()), 42)
387
388 class NonIntegral(trunc_result_base):
389 def __trunc__(self):
390 # Check that we avoid infinite recursion.
391 return NonIntegral()
392
393 class TruncReturnsNonIntegral(base):
394 def __trunc__(self):
395 return NonIntegral()
396 try:
397 int(TruncReturnsNonIntegral())
398 except TypeError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000399 self.assertEqual(str(e),
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000400 "__trunc__ returned non-Integral"
401 " (type NonIntegral)")
402 else:
403 self.fail("Failed to raise TypeError with %s" %
404 ((base, trunc_result_base),))
405
Mark Dickinson7c95bb32012-09-27 19:38:59 +0100406 # Regression test for bugs.python.org/issue16060.
407 class BadInt(trunc_result_base):
408 def __int__(self):
409 return 42.0
410
411 class TruncReturnsBadInt(base):
412 def __trunc__(self):
413 return BadInt()
414
415 with self.assertRaises(TypeError):
416 int(TruncReturnsBadInt())
417
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200418 def test_int_subclass_with_int(self):
419 class MyInt(int):
420 def __int__(self):
421 return 42
422
423 class BadInt(int):
424 def __int__(self):
425 return 42.0
426
427 my_int = MyInt(7)
428 self.assertEqual(my_int, 7)
429 self.assertEqual(int(my_int), 42)
430
431 self.assertRaises(TypeError, int, BadInt())
432
433 def test_int_returns_int_subclass(self):
434 class BadInt:
435 def __int__(self):
436 return True
437
438 class BadInt2(int):
439 def __int__(self):
440 return True
441
442 class TruncReturnsBadInt:
443 def __trunc__(self):
444 return BadInt()
445
446 class TruncReturnsIntSubclass:
447 def __trunc__(self):
448 return True
449
450 bad_int = BadInt()
451 with self.assertWarns(DeprecationWarning):
452 n = int(bad_int)
453 self.assertEqual(n, 1)
Serhiy Storchaka54cd1962016-08-21 20:03:08 +0300454 self.assertIs(type(n), int)
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200455
456 bad_int = BadInt2()
457 with self.assertWarns(DeprecationWarning):
458 n = int(bad_int)
459 self.assertEqual(n, 1)
Serhiy Storchaka54cd1962016-08-21 20:03:08 +0300460 self.assertIs(type(n), int)
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200461
462 bad_int = TruncReturnsBadInt()
463 with self.assertWarns(DeprecationWarning):
464 n = int(bad_int)
465 self.assertEqual(n, 1)
Serhiy Storchaka54cd1962016-08-21 20:03:08 +0300466 self.assertIs(type(n), int)
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200467
468 good_int = TruncReturnsIntSubclass()
469 n = int(good_int)
470 self.assertEqual(n, 1)
Serhiy Storchaka54cd1962016-08-21 20:03:08 +0300471 self.assertIs(type(n), int)
Serhiy Storchaka15095802015-11-25 15:47:01 +0200472 n = IntSubclass(good_int)
473 self.assertEqual(n, 1)
474 self.assertIs(type(n), IntSubclass)
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200475
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000476 def test_error_message(self):
Serhiy Storchakaf6d0aee2013-08-03 20:55:06 +0300477 def check(s, base=None):
478 with self.assertRaises(ValueError,
479 msg="int(%r, %r)" % (s, base)) as cm:
480 if base is None:
481 int(s)
482 else:
483 int(s, base)
484 self.assertEqual(cm.exception.args[0],
485 "invalid literal for int() with base %d: %r" %
486 (10 if base is None else base, s))
487
488 check('\xbd')
489 check('123\xbd')
490 check(' 123 456 ')
491
492 check('123\x00')
493 # SF bug 1545497: embedded NULs were not detected with explicit base
494 check('123\x00', 10)
495 check('123\x00 245', 20)
496 check('123\x00 245', 16)
497 check('123\x00245', 20)
498 check('123\x00245', 16)
499 # byte string with embedded NUL
500 check(b'123\x00')
501 check(b'123\x00', 10)
502 # non-UTF-8 byte string
503 check(b'123\xbd')
504 check(b'123\xbd', 10)
505 # lone surrogate in Unicode string
506 check('123\ud800')
507 check('123\ud800', 10)
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000508
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000509if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500510 unittest.main()