blob: e0406dd4f9d819656480969540f9767838785a1f [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
Martin v. Löwis029656f2008-06-30 04:06:08 +0000103 # Bug #3236: Return small longs from PyLong_FromString
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000104 self.assertTrue(int("10") is 10)
105 self.assertTrue(int("-1") is -1)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000106
107 # SF bug 1334662: int(string, base) wrong answers
108 # Various representations of 2**32 evaluated to 0
109 # rather than 2**32 in previous versions
110
111 self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296)
112 self.assertEqual(int('102002022201221111211', 3), 4294967296)
113 self.assertEqual(int('10000000000000000', 4), 4294967296)
114 self.assertEqual(int('32244002423141', 5), 4294967296)
115 self.assertEqual(int('1550104015504', 6), 4294967296)
116 self.assertEqual(int('211301422354', 7), 4294967296)
117 self.assertEqual(int('40000000000', 8), 4294967296)
118 self.assertEqual(int('12068657454', 9), 4294967296)
119 self.assertEqual(int('4294967296', 10), 4294967296)
120 self.assertEqual(int('1904440554', 11), 4294967296)
121 self.assertEqual(int('9ba461594', 12), 4294967296)
122 self.assertEqual(int('535a79889', 13), 4294967296)
123 self.assertEqual(int('2ca5b7464', 14), 4294967296)
124 self.assertEqual(int('1a20dcd81', 15), 4294967296)
125 self.assertEqual(int('100000000', 16), 4294967296)
126 self.assertEqual(int('a7ffda91', 17), 4294967296)
127 self.assertEqual(int('704he7g4', 18), 4294967296)
128 self.assertEqual(int('4f5aff66', 19), 4294967296)
129 self.assertEqual(int('3723ai4g', 20), 4294967296)
130 self.assertEqual(int('281d55i4', 21), 4294967296)
131 self.assertEqual(int('1fj8b184', 22), 4294967296)
132 self.assertEqual(int('1606k7ic', 23), 4294967296)
133 self.assertEqual(int('mb994ag', 24), 4294967296)
134 self.assertEqual(int('hek2mgl', 25), 4294967296)
135 self.assertEqual(int('dnchbnm', 26), 4294967296)
136 self.assertEqual(int('b28jpdm', 27), 4294967296)
137 self.assertEqual(int('8pfgih4', 28), 4294967296)
138 self.assertEqual(int('76beigg', 29), 4294967296)
139 self.assertEqual(int('5qmcpqg', 30), 4294967296)
140 self.assertEqual(int('4q0jto4', 31), 4294967296)
141 self.assertEqual(int('4000000', 32), 4294967296)
142 self.assertEqual(int('3aokq94', 33), 4294967296)
143 self.assertEqual(int('2qhxjli', 34), 4294967296)
144 self.assertEqual(int('2br45qb', 35), 4294967296)
145 self.assertEqual(int('1z141z4', 36), 4294967296)
146
147 # tests with base 0
148 # this fails on 3.0, but in 2.x the old octal syntax is allowed
149 self.assertEqual(int(' 0o123 ', 0), 83)
150 self.assertEqual(int(' 0o123 ', 0), 83)
151 self.assertEqual(int('000', 0), 0)
152 self.assertEqual(int('0o123', 0), 83)
153 self.assertEqual(int('0x123', 0), 291)
154 self.assertEqual(int('0b100', 0), 4)
155 self.assertEqual(int(' 0O123 ', 0), 83)
156 self.assertEqual(int(' 0X123 ', 0), 291)
157 self.assertEqual(int(' 0B100 ', 0), 4)
158
159 # without base still base 10
160 self.assertEqual(int('0123'), 123)
161 self.assertEqual(int('0123', 10), 123)
162
163 # tests with prefix and base != 0
164 self.assertEqual(int('0x123', 16), 291)
165 self.assertEqual(int('0o123', 8), 83)
166 self.assertEqual(int('0b100', 2), 4)
167 self.assertEqual(int('0X123', 16), 291)
168 self.assertEqual(int('0O123', 8), 83)
169 self.assertEqual(int('0B100', 2), 4)
170
171 # the code has special checks for the first character after the
172 # type prefix
173 self.assertRaises(ValueError, int, '0b2', 2)
174 self.assertRaises(ValueError, int, '0b02', 2)
175 self.assertRaises(ValueError, int, '0B2', 2)
176 self.assertRaises(ValueError, int, '0B02', 2)
177 self.assertRaises(ValueError, int, '0o8', 8)
178 self.assertRaises(ValueError, int, '0o08', 8)
179 self.assertRaises(ValueError, int, '0O8', 8)
180 self.assertRaises(ValueError, int, '0O08', 8)
181 self.assertRaises(ValueError, int, '0xg', 16)
182 self.assertRaises(ValueError, int, '0x0g', 16)
183 self.assertRaises(ValueError, int, '0Xg', 16)
184 self.assertRaises(ValueError, int, '0X0g', 16)
185
186 # SF bug 1334662: int(string, base) wrong answers
187 # Checks for proper evaluation of 2**32 + 1
188 self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297)
189 self.assertEqual(int('102002022201221111212', 3), 4294967297)
190 self.assertEqual(int('10000000000000001', 4), 4294967297)
191 self.assertEqual(int('32244002423142', 5), 4294967297)
192 self.assertEqual(int('1550104015505', 6), 4294967297)
193 self.assertEqual(int('211301422355', 7), 4294967297)
194 self.assertEqual(int('40000000001', 8), 4294967297)
195 self.assertEqual(int('12068657455', 9), 4294967297)
196 self.assertEqual(int('4294967297', 10), 4294967297)
197 self.assertEqual(int('1904440555', 11), 4294967297)
198 self.assertEqual(int('9ba461595', 12), 4294967297)
199 self.assertEqual(int('535a7988a', 13), 4294967297)
200 self.assertEqual(int('2ca5b7465', 14), 4294967297)
201 self.assertEqual(int('1a20dcd82', 15), 4294967297)
202 self.assertEqual(int('100000001', 16), 4294967297)
203 self.assertEqual(int('a7ffda92', 17), 4294967297)
204 self.assertEqual(int('704he7g5', 18), 4294967297)
205 self.assertEqual(int('4f5aff67', 19), 4294967297)
206 self.assertEqual(int('3723ai4h', 20), 4294967297)
207 self.assertEqual(int('281d55i5', 21), 4294967297)
208 self.assertEqual(int('1fj8b185', 22), 4294967297)
209 self.assertEqual(int('1606k7id', 23), 4294967297)
210 self.assertEqual(int('mb994ah', 24), 4294967297)
211 self.assertEqual(int('hek2mgm', 25), 4294967297)
212 self.assertEqual(int('dnchbnn', 26), 4294967297)
213 self.assertEqual(int('b28jpdn', 27), 4294967297)
214 self.assertEqual(int('8pfgih5', 28), 4294967297)
215 self.assertEqual(int('76beigh', 29), 4294967297)
216 self.assertEqual(int('5qmcpqh', 30), 4294967297)
217 self.assertEqual(int('4q0jto5', 31), 4294967297)
218 self.assertEqual(int('4000001', 32), 4294967297)
219 self.assertEqual(int('3aokq95', 33), 4294967297)
220 self.assertEqual(int('2qhxjlj', 34), 4294967297)
221 self.assertEqual(int('2br45qc', 35), 4294967297)
222 self.assertEqual(int('1z141z5', 36), 4294967297)
223
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200224 def test_no_args(self):
225 self.assertEquals(int(), 0)
226
227 def test_keyword_args(self):
228 # Test invoking int() using keyword arguments.
229 self.assertEquals(int(x=1.2), 1)
230 self.assertEquals(int('100', base=2), 4)
231 self.assertEquals(int(x='100', base=2), 4)
232
233 # For example, PyPy 1.9.0 raised TypeError for these cases because it
234 # expects x to be a string if base is given.
235 @support.cpython_only
236 def test_base_arg_with_no_x_arg(self):
237 self.assertEquals(int(base=6), 0)
238 # Even invalid bases don't raise an exception.
239 self.assertEquals(int(base=1), 0)
240 self.assertEquals(int(base=1000), 0)
241 self.assertEquals(int(base='foo'), 0)
242
243 def test_non_numeric_input_types(self):
244 # Test possible non-numeric types for the argument x, including
245 # subclasses of the explicitly documented accepted types.
246 class CustomStr(str): pass
247 class CustomBytes(bytes): pass
248 class CustomByteArray(bytearray): pass
249
250 values = [b'100',
251 bytearray(b'100'),
252 CustomStr('100'),
253 CustomBytes(b'100'),
254 CustomByteArray(b'100')]
255
256 for x in values:
257 msg = 'x has type %s' % type(x).__name__
258 self.assertEquals(int(x), 100, msg=msg)
259 self.assertEquals(int(x, 2), 4, msg=msg)
260
261 def test_string_float(self):
262 self.assertRaises(ValueError, int, '1.2')
263
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000264 def test_intconversion(self):
265 # Test __int__()
266 class ClassicMissingMethods:
267 pass
268 self.assertRaises(TypeError, int, ClassicMissingMethods())
269
270 class MissingMethods(object):
271 pass
272 self.assertRaises(TypeError, int, MissingMethods())
273
274 class Foo0:
275 def __int__(self):
276 return 42
277
278 class Foo1(object):
279 def __int__(self):
280 return 42
281
282 class Foo2(int):
283 def __int__(self):
284 return 42
285
286 class Foo3(int):
287 def __int__(self):
288 return self
289
290 class Foo4(int):
291 def __int__(self):
292 return 42
293
294 class Foo5(int):
295 def __int__(self):
296 return 42.
297
298 self.assertEqual(int(Foo0()), 42)
299 self.assertEqual(int(Foo1()), 42)
300 self.assertEqual(int(Foo2()), 42)
301 self.assertEqual(int(Foo3()), 0)
302 self.assertEqual(int(Foo4()), 42)
303 self.assertRaises(TypeError, int, Foo5())
304
305 class Classic:
306 pass
307 for base in (object, Classic):
308 class IntOverridesTrunc(base):
309 def __int__(self):
310 return 42
311 def __trunc__(self):
312 return -12
313 self.assertEqual(int(IntOverridesTrunc()), 42)
314
315 class JustTrunc(base):
316 def __trunc__(self):
317 return 42
318 self.assertEqual(int(JustTrunc()), 42)
319
320 for trunc_result_base in (object, Classic):
321 class Integral(trunc_result_base):
322 def __int__(self):
323 return 42
324
325 class TruncReturnsNonInt(base):
326 def __trunc__(self):
327 return Integral()
328 self.assertEqual(int(TruncReturnsNonInt()), 42)
329
330 class NonIntegral(trunc_result_base):
331 def __trunc__(self):
332 # Check that we avoid infinite recursion.
333 return NonIntegral()
334
335 class TruncReturnsNonIntegral(base):
336 def __trunc__(self):
337 return NonIntegral()
338 try:
339 int(TruncReturnsNonIntegral())
340 except TypeError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000341 self.assertEqual(str(e),
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000342 "__trunc__ returned non-Integral"
343 " (type NonIntegral)")
344 else:
345 self.fail("Failed to raise TypeError with %s" %
346 ((base, trunc_result_base),))
347
Mark Dickinson7c95bb32012-09-27 19:38:59 +0100348 # Regression test for bugs.python.org/issue16060.
349 class BadInt(trunc_result_base):
350 def __int__(self):
351 return 42.0
352
353 class TruncReturnsBadInt(base):
354 def __trunc__(self):
355 return BadInt()
356
357 with self.assertRaises(TypeError):
358 int(TruncReturnsBadInt())
359
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000360 def test_error_message(self):
361 testlist = ('\xbd', '123\xbd', ' 123 456 ')
362 for s in testlist:
363 try:
364 int(s)
365 except ValueError as e:
366 self.assertIn(s.strip(), e.args[0])
367 else:
368 self.fail("Expected int(%r) to raise a ValueError", s)
369
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000370def test_main():
Andrew Svetlov8e42e8a2012-12-23 12:49:33 +0200371 support.run_unittest(IntTestCases)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000372
373if __name__ == "__main__":
374 test_main()