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