blob: 492123000b1da5668aa7235f05a11065072837ce [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
76 self.assertRaises(ValueError, int, '123\0')
77 self.assertRaises(ValueError, int, '53', 40)
78
79 # SF bug 1545497: embedded NULs were not detected with
80 # explicit base
81 self.assertRaises(ValueError, int, '123\0', 10)
82 self.assertRaises(ValueError, int, '123\x00 245', 20)
83
84 x = int('1' * 600)
Ezio Melottie9615932010-01-24 19:26:24 +000085 self.assertIsInstance(x, int)
86
Christian Heimes81ee3ef2008-05-04 22:42:01 +000087
88 self.assertRaises(TypeError, int, 1, 12)
89
90 self.assertEqual(int('0o123', 0), 83)
91 self.assertEqual(int('0x123', 16), 291)
92
93 # Bug 1679: "0x" is not a valid hex literal
94 self.assertRaises(ValueError, int, "0x", 16)
95 self.assertRaises(ValueError, int, "0x", 0)
96
97 self.assertRaises(ValueError, int, "0o", 8)
98 self.assertRaises(ValueError, int, "0o", 0)
99
100 self.assertRaises(ValueError, int, "0b", 2)
101 self.assertRaises(ValueError, int, "0b", 0)
102
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000103 # SF bug 1334662: int(string, base) wrong answers
104 # Various representations of 2**32 evaluated to 0
105 # rather than 2**32 in previous versions
106
107 self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296)
108 self.assertEqual(int('102002022201221111211', 3), 4294967296)
109 self.assertEqual(int('10000000000000000', 4), 4294967296)
110 self.assertEqual(int('32244002423141', 5), 4294967296)
111 self.assertEqual(int('1550104015504', 6), 4294967296)
112 self.assertEqual(int('211301422354', 7), 4294967296)
113 self.assertEqual(int('40000000000', 8), 4294967296)
114 self.assertEqual(int('12068657454', 9), 4294967296)
115 self.assertEqual(int('4294967296', 10), 4294967296)
116 self.assertEqual(int('1904440554', 11), 4294967296)
117 self.assertEqual(int('9ba461594', 12), 4294967296)
118 self.assertEqual(int('535a79889', 13), 4294967296)
119 self.assertEqual(int('2ca5b7464', 14), 4294967296)
120 self.assertEqual(int('1a20dcd81', 15), 4294967296)
121 self.assertEqual(int('100000000', 16), 4294967296)
122 self.assertEqual(int('a7ffda91', 17), 4294967296)
123 self.assertEqual(int('704he7g4', 18), 4294967296)
124 self.assertEqual(int('4f5aff66', 19), 4294967296)
125 self.assertEqual(int('3723ai4g', 20), 4294967296)
126 self.assertEqual(int('281d55i4', 21), 4294967296)
127 self.assertEqual(int('1fj8b184', 22), 4294967296)
128 self.assertEqual(int('1606k7ic', 23), 4294967296)
129 self.assertEqual(int('mb994ag', 24), 4294967296)
130 self.assertEqual(int('hek2mgl', 25), 4294967296)
131 self.assertEqual(int('dnchbnm', 26), 4294967296)
132 self.assertEqual(int('b28jpdm', 27), 4294967296)
133 self.assertEqual(int('8pfgih4', 28), 4294967296)
134 self.assertEqual(int('76beigg', 29), 4294967296)
135 self.assertEqual(int('5qmcpqg', 30), 4294967296)
136 self.assertEqual(int('4q0jto4', 31), 4294967296)
137 self.assertEqual(int('4000000', 32), 4294967296)
138 self.assertEqual(int('3aokq94', 33), 4294967296)
139 self.assertEqual(int('2qhxjli', 34), 4294967296)
140 self.assertEqual(int('2br45qb', 35), 4294967296)
141 self.assertEqual(int('1z141z4', 36), 4294967296)
142
143 # tests with base 0
144 # this fails on 3.0, but in 2.x the old octal syntax is allowed
145 self.assertEqual(int(' 0o123 ', 0), 83)
146 self.assertEqual(int(' 0o123 ', 0), 83)
147 self.assertEqual(int('000', 0), 0)
148 self.assertEqual(int('0o123', 0), 83)
149 self.assertEqual(int('0x123', 0), 291)
150 self.assertEqual(int('0b100', 0), 4)
151 self.assertEqual(int(' 0O123 ', 0), 83)
152 self.assertEqual(int(' 0X123 ', 0), 291)
153 self.assertEqual(int(' 0B100 ', 0), 4)
154
155 # without base still base 10
156 self.assertEqual(int('0123'), 123)
157 self.assertEqual(int('0123', 10), 123)
158
159 # tests with prefix and base != 0
160 self.assertEqual(int('0x123', 16), 291)
161 self.assertEqual(int('0o123', 8), 83)
162 self.assertEqual(int('0b100', 2), 4)
163 self.assertEqual(int('0X123', 16), 291)
164 self.assertEqual(int('0O123', 8), 83)
165 self.assertEqual(int('0B100', 2), 4)
166
167 # the code has special checks for the first character after the
168 # type prefix
169 self.assertRaises(ValueError, int, '0b2', 2)
170 self.assertRaises(ValueError, int, '0b02', 2)
171 self.assertRaises(ValueError, int, '0B2', 2)
172 self.assertRaises(ValueError, int, '0B02', 2)
173 self.assertRaises(ValueError, int, '0o8', 8)
174 self.assertRaises(ValueError, int, '0o08', 8)
175 self.assertRaises(ValueError, int, '0O8', 8)
176 self.assertRaises(ValueError, int, '0O08', 8)
177 self.assertRaises(ValueError, int, '0xg', 16)
178 self.assertRaises(ValueError, int, '0x0g', 16)
179 self.assertRaises(ValueError, int, '0Xg', 16)
180 self.assertRaises(ValueError, int, '0X0g', 16)
181
182 # SF bug 1334662: int(string, base) wrong answers
183 # Checks for proper evaluation of 2**32 + 1
184 self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297)
185 self.assertEqual(int('102002022201221111212', 3), 4294967297)
186 self.assertEqual(int('10000000000000001', 4), 4294967297)
187 self.assertEqual(int('32244002423142', 5), 4294967297)
188 self.assertEqual(int('1550104015505', 6), 4294967297)
189 self.assertEqual(int('211301422355', 7), 4294967297)
190 self.assertEqual(int('40000000001', 8), 4294967297)
191 self.assertEqual(int('12068657455', 9), 4294967297)
192 self.assertEqual(int('4294967297', 10), 4294967297)
193 self.assertEqual(int('1904440555', 11), 4294967297)
194 self.assertEqual(int('9ba461595', 12), 4294967297)
195 self.assertEqual(int('535a7988a', 13), 4294967297)
196 self.assertEqual(int('2ca5b7465', 14), 4294967297)
197 self.assertEqual(int('1a20dcd82', 15), 4294967297)
198 self.assertEqual(int('100000001', 16), 4294967297)
199 self.assertEqual(int('a7ffda92', 17), 4294967297)
200 self.assertEqual(int('704he7g5', 18), 4294967297)
201 self.assertEqual(int('4f5aff67', 19), 4294967297)
202 self.assertEqual(int('3723ai4h', 20), 4294967297)
203 self.assertEqual(int('281d55i5', 21), 4294967297)
204 self.assertEqual(int('1fj8b185', 22), 4294967297)
205 self.assertEqual(int('1606k7id', 23), 4294967297)
206 self.assertEqual(int('mb994ah', 24), 4294967297)
207 self.assertEqual(int('hek2mgm', 25), 4294967297)
208 self.assertEqual(int('dnchbnn', 26), 4294967297)
209 self.assertEqual(int('b28jpdn', 27), 4294967297)
210 self.assertEqual(int('8pfgih5', 28), 4294967297)
211 self.assertEqual(int('76beigh', 29), 4294967297)
212 self.assertEqual(int('5qmcpqh', 30), 4294967297)
213 self.assertEqual(int('4q0jto5', 31), 4294967297)
214 self.assertEqual(int('4000001', 32), 4294967297)
215 self.assertEqual(int('3aokq95', 33), 4294967297)
216 self.assertEqual(int('2qhxjlj', 34), 4294967297)
217 self.assertEqual(int('2br45qc', 35), 4294967297)
218 self.assertEqual(int('1z141z5', 36), 4294967297)
219
Serhiy Storchaka3b317042012-12-27 23:57:00 +0200220 @support.cpython_only
221 def test_small_ints(self):
222 # Bug #3236: Return small longs from PyLong_FromString
223 self.assertIs(int('10'), 10)
224 self.assertIs(int('-1'), -1)
225 self.assertIs(int(b'10'), 10)
226 self.assertIs(int(b'-1'), -1)
227
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200228 def test_no_args(self):
Serhiy Storchakaa29159b2012-12-28 00:34:57 +0200229 self.assertEqual(int(), 0)
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200230
231 def test_keyword_args(self):
232 # Test invoking int() using keyword arguments.
Serhiy Storchakaa29159b2012-12-28 00:34:57 +0200233 self.assertEqual(int(x=1.2), 1)
234 self.assertEqual(int('100', base=2), 4)
235 self.assertEqual(int(x='100', base=2), 4)
Serhiy Storchaka0b386d52012-12-28 09:42:11 +0200236 self.assertRaises(TypeError, int, base=10)
237 self.assertRaises(TypeError, int, base=0)
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200238
Gregory P. Smitha689e522012-12-25 22:38:32 -0800239 def test_int_base_limits(self):
240 """Testing the supported limits of the int() base parameter."""
241 self.assertEqual(int('0', 5), 0)
242 with self.assertRaises(ValueError):
243 int('0', 1)
244 with self.assertRaises(ValueError):
245 int('0', 37)
246 with self.assertRaises(ValueError):
247 int('0', -909) # An old magic value base from Python 2.
248 with self.assertRaises(ValueError):
249 int('0', base=0-(2**234))
250 with self.assertRaises(ValueError):
251 int('0', base=2**234)
252 # Bases 2 through 36 are supported.
253 for base in range(2,37):
254 self.assertEqual(int('0', base=base), 0)
255
256 def test_int_base_bad_types(self):
257 """Not integer types are not valid bases; issue16772."""
258 with self.assertRaises(TypeError):
259 int('0', 5.5)
260 with self.assertRaises(TypeError):
261 int('0', 5.0)
262
Mark Dickinson07c71362013-01-27 10:17:52 +0000263 def test_int_base_indexable(self):
264 class MyIndexable(object):
265 def __init__(self, value):
266 self.value = value
267 def __index__(self):
268 return self.value
269
270 # Check out of range bases.
271 for base in 2**100, -2**100, 1, 37:
272 with self.assertRaises(ValueError):
273 int('43', base)
274
275 # Check in-range bases.
276 self.assertEqual(int('101', base=MyIndexable(2)), 5)
277 self.assertEqual(int('101', base=MyIndexable(10)), 101)
278 self.assertEqual(int('101', base=MyIndexable(36)), 1 + 36**2)
279
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200280 def test_non_numeric_input_types(self):
281 # Test possible non-numeric types for the argument x, including
282 # subclasses of the explicitly documented accepted types.
283 class CustomStr(str): pass
284 class CustomBytes(bytes): pass
285 class CustomByteArray(bytearray): pass
286
287 values = [b'100',
288 bytearray(b'100'),
289 CustomStr('100'),
290 CustomBytes(b'100'),
291 CustomByteArray(b'100')]
292
293 for x in values:
294 msg = 'x has type %s' % type(x).__name__
Serhiy Storchakaa29159b2012-12-28 00:34:57 +0200295 self.assertEqual(int(x), 100, msg=msg)
296 self.assertEqual(int(x, 2), 4, msg=msg)
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200297
298 def test_string_float(self):
299 self.assertRaises(ValueError, int, '1.2')
300
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000301 def test_intconversion(self):
302 # Test __int__()
303 class ClassicMissingMethods:
304 pass
305 self.assertRaises(TypeError, int, ClassicMissingMethods())
306
307 class MissingMethods(object):
308 pass
309 self.assertRaises(TypeError, int, MissingMethods())
310
311 class Foo0:
312 def __int__(self):
313 return 42
314
315 class Foo1(object):
316 def __int__(self):
317 return 42
318
319 class Foo2(int):
320 def __int__(self):
321 return 42
322
323 class Foo3(int):
324 def __int__(self):
325 return self
326
327 class Foo4(int):
328 def __int__(self):
329 return 42
330
331 class Foo5(int):
332 def __int__(self):
333 return 42.
334
335 self.assertEqual(int(Foo0()), 42)
336 self.assertEqual(int(Foo1()), 42)
337 self.assertEqual(int(Foo2()), 42)
338 self.assertEqual(int(Foo3()), 0)
339 self.assertEqual(int(Foo4()), 42)
340 self.assertRaises(TypeError, int, Foo5())
341
342 class Classic:
343 pass
344 for base in (object, Classic):
345 class IntOverridesTrunc(base):
346 def __int__(self):
347 return 42
348 def __trunc__(self):
349 return -12
350 self.assertEqual(int(IntOverridesTrunc()), 42)
351
352 class JustTrunc(base):
353 def __trunc__(self):
354 return 42
355 self.assertEqual(int(JustTrunc()), 42)
356
Mark Dickinsonc9734482013-04-13 17:44:44 +0100357 class ExceptionalTrunc(base):
358 def __trunc__(self):
359 1 / 0
360 with self.assertRaises(ZeroDivisionError):
361 int(ExceptionalTrunc())
362
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000363 for trunc_result_base in (object, Classic):
364 class Integral(trunc_result_base):
365 def __int__(self):
366 return 42
367
368 class TruncReturnsNonInt(base):
369 def __trunc__(self):
370 return Integral()
371 self.assertEqual(int(TruncReturnsNonInt()), 42)
372
373 class NonIntegral(trunc_result_base):
374 def __trunc__(self):
375 # Check that we avoid infinite recursion.
376 return NonIntegral()
377
378 class TruncReturnsNonIntegral(base):
379 def __trunc__(self):
380 return NonIntegral()
381 try:
382 int(TruncReturnsNonIntegral())
383 except TypeError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000384 self.assertEqual(str(e),
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000385 "__trunc__ returned non-Integral"
386 " (type NonIntegral)")
387 else:
388 self.fail("Failed to raise TypeError with %s" %
389 ((base, trunc_result_base),))
390
Mark Dickinson7c95bb32012-09-27 19:38:59 +0100391 # Regression test for bugs.python.org/issue16060.
392 class BadInt(trunc_result_base):
393 def __int__(self):
394 return 42.0
395
396 class TruncReturnsBadInt(base):
397 def __trunc__(self):
398 return BadInt()
399
400 with self.assertRaises(TypeError):
401 int(TruncReturnsBadInt())
402
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000403 def test_error_message(self):
404 testlist = ('\xbd', '123\xbd', ' 123 456 ')
405 for s in testlist:
406 try:
407 int(s)
408 except ValueError as e:
409 self.assertIn(s.strip(), e.args[0])
410 else:
411 self.fail("Expected int(%r) to raise a ValueError", s)
412
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000413def test_main():
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200414 support.run_unittest(IntTestCases)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000415
416if __name__ == "__main__":
417 test_main()