blob: c489510537ebcd4b1c2176af813dfaabc66cf0ab [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
231 def test_non_numeric_input_types(self):
232 # Test possible non-numeric types for the argument x, including
233 # subclasses of the explicitly documented accepted types.
234 class CustomStr(str): pass
235 class CustomBytes(bytes): pass
236 class CustomByteArray(bytearray): pass
237
238 values = [b'100',
239 bytearray(b'100'),
240 CustomStr('100'),
241 CustomBytes(b'100'),
242 CustomByteArray(b'100')]
243
244 for x in values:
245 msg = 'x has type %s' % type(x).__name__
Serhiy Storchakaa29159b2012-12-28 00:34:57 +0200246 self.assertEqual(int(x), 100, msg=msg)
247 self.assertEqual(int(x, 2), 4, msg=msg)
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200248
249 def test_string_float(self):
250 self.assertRaises(ValueError, int, '1.2')
251
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000252 def test_intconversion(self):
253 # Test __int__()
254 class ClassicMissingMethods:
255 pass
256 self.assertRaises(TypeError, int, ClassicMissingMethods())
257
258 class MissingMethods(object):
259 pass
260 self.assertRaises(TypeError, int, MissingMethods())
261
262 class Foo0:
263 def __int__(self):
264 return 42
265
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000266 self.assertEqual(int(Foo0()), 42)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000267
268 class Classic:
269 pass
270 for base in (object, Classic):
271 class IntOverridesTrunc(base):
272 def __int__(self):
273 return 42
274 def __trunc__(self):
275 return -12
276 self.assertEqual(int(IntOverridesTrunc()), 42)
277
278 class JustTrunc(base):
279 def __trunc__(self):
280 return 42
281 self.assertEqual(int(JustTrunc()), 42)
282
Mark Dickinsonc9734482013-04-13 17:44:44 +0100283 class ExceptionalTrunc(base):
284 def __trunc__(self):
285 1 / 0
286 with self.assertRaises(ZeroDivisionError):
287 int(ExceptionalTrunc())
288
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000289 for trunc_result_base in (object, Classic):
290 class Integral(trunc_result_base):
291 def __int__(self):
292 return 42
293
294 class TruncReturnsNonInt(base):
295 def __trunc__(self):
296 return Integral()
297 self.assertEqual(int(TruncReturnsNonInt()), 42)
298
299 class NonIntegral(trunc_result_base):
300 def __trunc__(self):
301 # Check that we avoid infinite recursion.
302 return NonIntegral()
303
304 class TruncReturnsNonIntegral(base):
305 def __trunc__(self):
306 return NonIntegral()
307 try:
308 int(TruncReturnsNonIntegral())
309 except TypeError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000310 self.assertEqual(str(e),
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000311 "__trunc__ returned non-Integral"
312 " (type NonIntegral)")
313 else:
314 self.fail("Failed to raise TypeError with %s" %
315 ((base, trunc_result_base),))
316
Mark Dickinson7c95bb32012-09-27 19:38:59 +0100317 # Regression test for bugs.python.org/issue16060.
318 class BadInt(trunc_result_base):
319 def __int__(self):
320 return 42.0
321
322 class TruncReturnsBadInt(base):
323 def __trunc__(self):
324 return BadInt()
325
326 with self.assertRaises(TypeError):
327 int(TruncReturnsBadInt())
328
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200329 def test_int_subclass_with_int(self):
330 class MyInt(int):
331 def __int__(self):
332 return 42
333
334 class BadInt(int):
335 def __int__(self):
336 return 42.0
337
338 my_int = MyInt(7)
339 self.assertEqual(my_int, 7)
340 self.assertEqual(int(my_int), 42)
341
342 self.assertRaises(TypeError, int, BadInt())
343
344 def test_int_returns_int_subclass(self):
345 class BadInt:
346 def __int__(self):
347 return True
348
349 class BadInt2(int):
350 def __int__(self):
351 return True
352
353 class TruncReturnsBadInt:
354 def __trunc__(self):
355 return BadInt()
356
357 class TruncReturnsIntSubclass:
358 def __trunc__(self):
359 return True
360
361 bad_int = BadInt()
Serhiy Storchakac836a282013-12-14 21:07:09 +0200362 n = int(bad_int)
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200363 self.assertEqual(n, 1)
364
365 bad_int = BadInt2()
Serhiy Storchakac836a282013-12-14 21:07:09 +0200366 n = int(bad_int)
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200367 self.assertEqual(n, 1)
368
369 bad_int = TruncReturnsBadInt()
Serhiy Storchakac836a282013-12-14 21:07:09 +0200370 n = int(bad_int)
Serhiy Storchaka31a65542013-12-11 21:07:54 +0200371 self.assertEqual(n, 1)
372
373 good_int = TruncReturnsIntSubclass()
374 n = int(good_int)
375 self.assertEqual(n, 1)
376
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000377 def test_error_message(self):
Serhiy Storchakaf6d0aee2013-08-03 20:55:06 +0300378 def check(s, base=None):
379 with self.assertRaises(ValueError,
380 msg="int(%r, %r)" % (s, base)) as cm:
381 if base is None:
382 int(s)
383 else:
384 int(s, base)
385 self.assertEqual(cm.exception.args[0],
386 "invalid literal for int() with base %d: %r" %
387 (10 if base is None else base, s))
388
389 check('\xbd')
390 check('123\xbd')
391 check(' 123 456 ')
392
393 check('123\x00')
394 # SF bug 1545497: embedded NULs were not detected with explicit base
395 check('123\x00', 10)
396 check('123\x00 245', 20)
397 check('123\x00 245', 16)
398 check('123\x00245', 20)
399 check('123\x00245', 16)
400 # byte string with embedded NUL
401 check(b'123\x00')
402 check(b'123\x00', 10)
403 # non-UTF-8 byte string
404 check(b'123\xbd')
405 check(b'123\xbd', 10)
406 # lone surrogate in Unicode string
407 check('123\ud800')
408 check('123\ud800', 10)
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000409
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000410def test_main():
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200411 support.run_unittest(IntTestCases)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000412
413if __name__ == "__main__":
414 test_main()