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