blob: 4e00622325a0c0d3059de8c59e13122e1589480a [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
307 class Foo1(object):
308 def __int__(self):
309 return 42
310
311 class Foo2(int):
312 def __int__(self):
313 return 42
314
315 class Foo3(int):
316 def __int__(self):
317 return self
318
319 class Foo4(int):
320 def __int__(self):
321 return 42
322
323 class Foo5(int):
324 def __int__(self):
325 return 42.
326
327 self.assertEqual(int(Foo0()), 42)
328 self.assertEqual(int(Foo1()), 42)
329 self.assertEqual(int(Foo2()), 42)
330 self.assertEqual(int(Foo3()), 0)
331 self.assertEqual(int(Foo4()), 42)
332 self.assertRaises(TypeError, int, Foo5())
333
334 class Classic:
335 pass
336 for base in (object, Classic):
337 class IntOverridesTrunc(base):
338 def __int__(self):
339 return 42
340 def __trunc__(self):
341 return -12
342 self.assertEqual(int(IntOverridesTrunc()), 42)
343
344 class JustTrunc(base):
345 def __trunc__(self):
346 return 42
347 self.assertEqual(int(JustTrunc()), 42)
348
Mark Dickinsonc9734482013-04-13 17:44:44 +0100349 class ExceptionalTrunc(base):
350 def __trunc__(self):
351 1 / 0
352 with self.assertRaises(ZeroDivisionError):
353 int(ExceptionalTrunc())
354
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000355 for trunc_result_base in (object, Classic):
356 class Integral(trunc_result_base):
357 def __int__(self):
358 return 42
359
360 class TruncReturnsNonInt(base):
361 def __trunc__(self):
362 return Integral()
363 self.assertEqual(int(TruncReturnsNonInt()), 42)
364
365 class NonIntegral(trunc_result_base):
366 def __trunc__(self):
367 # Check that we avoid infinite recursion.
368 return NonIntegral()
369
370 class TruncReturnsNonIntegral(base):
371 def __trunc__(self):
372 return NonIntegral()
373 try:
374 int(TruncReturnsNonIntegral())
375 except TypeError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000376 self.assertEqual(str(e),
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000377 "__trunc__ returned non-Integral"
378 " (type NonIntegral)")
379 else:
380 self.fail("Failed to raise TypeError with %s" %
381 ((base, trunc_result_base),))
382
Mark Dickinson7c95bb32012-09-27 19:38:59 +0100383 # Regression test for bugs.python.org/issue16060.
384 class BadInt(trunc_result_base):
385 def __int__(self):
386 return 42.0
387
388 class TruncReturnsBadInt(base):
389 def __trunc__(self):
390 return BadInt()
391
392 with self.assertRaises(TypeError):
393 int(TruncReturnsBadInt())
394
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000395 def test_error_message(self):
Serhiy Storchakaf6d0aee2013-08-03 20:55:06 +0300396 def check(s, base=None):
397 with self.assertRaises(ValueError,
398 msg="int(%r, %r)" % (s, base)) as cm:
399 if base is None:
400 int(s)
401 else:
402 int(s, base)
403 self.assertEqual(cm.exception.args[0],
404 "invalid literal for int() with base %d: %r" %
405 (10 if base is None else base, s))
406
407 check('\xbd')
408 check('123\xbd')
409 check(' 123 456 ')
410
411 check('123\x00')
412 # SF bug 1545497: embedded NULs were not detected with explicit base
413 check('123\x00', 10)
414 check('123\x00 245', 20)
415 check('123\x00 245', 16)
416 check('123\x00245', 20)
417 check('123\x00245', 16)
418 # byte string with embedded NUL
419 check(b'123\x00')
420 check(b'123\x00', 10)
421 # non-UTF-8 byte string
422 check(b'123\xbd')
423 check(b'123\xbd', 10)
424 # lone surrogate in Unicode string
425 check('123\ud800')
426 check('123\ud800', 10)
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000427
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000428def test_main():
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200429 support.run_unittest(IntTestCases)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000430
431if __name__ == "__main__":
432 test_main()