test_int.py revision 6f70fe804690bbfea9caefe1ba01029aa1abf0eb
1import sys
2
3import unittest
4from test import test_support
5from test.test_support import run_unittest, have_unicode
6import math
7
8L = [
9        ('0', 0),
10        ('1', 1),
11        ('9', 9),
12        ('10', 10),
13        ('99', 99),
14        ('100', 100),
15        ('314', 314),
16        (' 314', 314),
17        ('314 ', 314),
18        ('  \t\t  314  \t\t  ', 314),
19        (repr(sys.maxint), sys.maxint),
20        ('  1x', ValueError),
21        ('  1  ', 1),
22        ('  1\02  ', ValueError),
23        ('', ValueError),
24        (' ', ValueError),
25        ('  \t\t  ', ValueError)
26]
27if have_unicode:
28    L += [
29        (unicode('0'), 0),
30        (unicode('1'), 1),
31        (unicode('9'), 9),
32        (unicode('10'), 10),
33        (unicode('99'), 99),
34        (unicode('100'), 100),
35        (unicode('314'), 314),
36        (unicode(' 314'), 314),
37        (unicode('\u0663\u0661\u0664 ','raw-unicode-escape'), 314),
38        (unicode('  \t\t  314  \t\t  '), 314),
39        (unicode('  1x'), ValueError),
40        (unicode('  1  '), 1),
41        (unicode('  1\02  '), ValueError),
42        (unicode(''), ValueError),
43        (unicode(' '), ValueError),
44        (unicode('  \t\t  '), ValueError),
45        (unichr(0x200), ValueError),
46]
47
48class IntLongCommonTests(object):
49
50    """Mixin of test cases to share between both test_int and test_long."""
51
52    # Change to int or long in the TestCase subclass.
53    ntype = None
54
55    def test_no_args(self):
56        self.assertEqual(self.ntype(), 0)
57
58    def test_keyword_args(self):
59        # Test invoking constructor using keyword arguments.
60        self.assertEqual(self.ntype(x=1.2), 1)
61        self.assertEqual(self.ntype('100', base=2), 4)
62        self.assertEqual(self.ntype(x='100', base=2), 4)
63
64class IntTestCases(IntLongCommonTests, unittest.TestCase):
65
66    ntype = int
67
68    def test_basic(self):
69        self.assertEqual(int(314), 314)
70        self.assertEqual(int(3.14), 3)
71        self.assertEqual(int(314L), 314)
72        # Check that conversion from float truncates towards zero
73        self.assertEqual(int(-3.14), -3)
74        self.assertEqual(int(3.9), 3)
75        self.assertEqual(int(-3.9), -3)
76        self.assertEqual(int(3.5), 3)
77        self.assertEqual(int(-3.5), -3)
78        # Different base:
79        self.assertEqual(int("10",16), 16L)
80        if have_unicode:
81            self.assertEqual(int(unicode("10"),16), 16L)
82        # Test conversion from strings and various anomalies
83        for s, v in L:
84            for sign in "", "+", "-":
85                for prefix in "", " ", "\t", "  \t\t  ":
86                    ss = prefix + sign + s
87                    vv = v
88                    if sign == "-" and v is not ValueError:
89                        vv = -v
90                    try:
91                        self.assertEqual(int(ss), vv)
92                    except v:
93                        pass
94
95        s = repr(-1-sys.maxint)
96        x = int(s)
97        self.assertEqual(x+1, -sys.maxint)
98        self.assertIsInstance(x, int)
99        # should return long
100        self.assertEqual(int(s[1:]), sys.maxint+1)
101
102        # should return long
103        x = int(1e100)
104        self.assertIsInstance(x, long)
105        x = int(-1e100)
106        self.assertIsInstance(x, long)
107
108
109        # SF bug 434186:  0x80000000/2 != 0x80000000>>1.
110        # Worked by accident in Windows release build, but failed in debug build.
111        # Failed in all Linux builds.
112        x = -1-sys.maxint
113        self.assertEqual(x >> 1, x//2)
114
115        self.assertRaises(ValueError, int, '123\0')
116        self.assertRaises(ValueError, int, '53', 40)
117
118        # SF bug 1545497: embedded NULs were not detected with
119        # explicit base
120        self.assertRaises(ValueError, int, '123\0', 10)
121        self.assertRaises(ValueError, int, '123\x00 245', 20)
122
123        x = int('1' * 600)
124        self.assertIsInstance(x, long)
125
126        if have_unicode:
127            x = int(unichr(0x661) * 600)
128            self.assertIsInstance(x, long)
129
130        self.assertRaises(TypeError, int, 1, 12)
131
132        self.assertEqual(int('0123', 0), 83)
133        self.assertEqual(int('0x123', 16), 291)
134
135        # Bug 1679: "0x" is not a valid hex literal
136        self.assertRaises(ValueError, int, "0x", 16)
137        self.assertRaises(ValueError, int, "0x", 0)
138
139        self.assertRaises(ValueError, int, "0o", 8)
140        self.assertRaises(ValueError, int, "0o", 0)
141
142        self.assertRaises(ValueError, int, "0b", 2)
143        self.assertRaises(ValueError, int, "0b", 0)
144
145
146        # SF bug 1334662: int(string, base) wrong answers
147        # Various representations of 2**32 evaluated to 0
148        # rather than 2**32 in previous versions
149
150        self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296L)
151        self.assertEqual(int('102002022201221111211', 3), 4294967296L)
152        self.assertEqual(int('10000000000000000', 4), 4294967296L)
153        self.assertEqual(int('32244002423141', 5), 4294967296L)
154        self.assertEqual(int('1550104015504', 6), 4294967296L)
155        self.assertEqual(int('211301422354', 7), 4294967296L)
156        self.assertEqual(int('40000000000', 8), 4294967296L)
157        self.assertEqual(int('12068657454', 9), 4294967296L)
158        self.assertEqual(int('4294967296', 10), 4294967296L)
159        self.assertEqual(int('1904440554', 11), 4294967296L)
160        self.assertEqual(int('9ba461594', 12), 4294967296L)
161        self.assertEqual(int('535a79889', 13), 4294967296L)
162        self.assertEqual(int('2ca5b7464', 14), 4294967296L)
163        self.assertEqual(int('1a20dcd81', 15), 4294967296L)
164        self.assertEqual(int('100000000', 16), 4294967296L)
165        self.assertEqual(int('a7ffda91', 17), 4294967296L)
166        self.assertEqual(int('704he7g4', 18), 4294967296L)
167        self.assertEqual(int('4f5aff66', 19), 4294967296L)
168        self.assertEqual(int('3723ai4g', 20), 4294967296L)
169        self.assertEqual(int('281d55i4', 21), 4294967296L)
170        self.assertEqual(int('1fj8b184', 22), 4294967296L)
171        self.assertEqual(int('1606k7ic', 23), 4294967296L)
172        self.assertEqual(int('mb994ag', 24), 4294967296L)
173        self.assertEqual(int('hek2mgl', 25), 4294967296L)
174        self.assertEqual(int('dnchbnm', 26), 4294967296L)
175        self.assertEqual(int('b28jpdm', 27), 4294967296L)
176        self.assertEqual(int('8pfgih4', 28), 4294967296L)
177        self.assertEqual(int('76beigg', 29), 4294967296L)
178        self.assertEqual(int('5qmcpqg', 30), 4294967296L)
179        self.assertEqual(int('4q0jto4', 31), 4294967296L)
180        self.assertEqual(int('4000000', 32), 4294967296L)
181        self.assertEqual(int('3aokq94', 33), 4294967296L)
182        self.assertEqual(int('2qhxjli', 34), 4294967296L)
183        self.assertEqual(int('2br45qb', 35), 4294967296L)
184        self.assertEqual(int('1z141z4', 36), 4294967296L)
185
186        # tests with base 0
187        # this fails on 3.0, but in 2.x the old octal syntax is allowed
188        self.assertEqual(int(' 0123  ', 0), 83)
189        self.assertEqual(int(' 0123  ', 0), 83)
190        self.assertEqual(int('000', 0), 0)
191        self.assertEqual(int('0o123', 0), 83)
192        self.assertEqual(int('0x123', 0), 291)
193        self.assertEqual(int('0b100', 0), 4)
194        self.assertEqual(int(' 0O123   ', 0), 83)
195        self.assertEqual(int(' 0X123  ', 0), 291)
196        self.assertEqual(int(' 0B100 ', 0), 4)
197        self.assertEqual(int('0', 0), 0)
198        self.assertEqual(int('+0', 0), 0)
199        self.assertEqual(int('-0', 0), 0)
200        self.assertEqual(int('00', 0), 0)
201        self.assertRaises(ValueError, int, '08', 0)
202        self.assertRaises(ValueError, int, '-012395', 0)
203
204        # without base still base 10
205        self.assertEqual(int('0123'), 123)
206        self.assertEqual(int('0123', 10), 123)
207
208        # tests with prefix and base != 0
209        self.assertEqual(int('0x123', 16), 291)
210        self.assertEqual(int('0o123', 8), 83)
211        self.assertEqual(int('0b100', 2), 4)
212        self.assertEqual(int('0X123', 16), 291)
213        self.assertEqual(int('0O123', 8), 83)
214        self.assertEqual(int('0B100', 2), 4)
215
216        # the code has special checks for the first character after the
217        #  type prefix
218        self.assertRaises(ValueError, int, '0b2', 2)
219        self.assertRaises(ValueError, int, '0b02', 2)
220        self.assertRaises(ValueError, int, '0B2', 2)
221        self.assertRaises(ValueError, int, '0B02', 2)
222        self.assertRaises(ValueError, int, '0o8', 8)
223        self.assertRaises(ValueError, int, '0o08', 8)
224        self.assertRaises(ValueError, int, '0O8', 8)
225        self.assertRaises(ValueError, int, '0O08', 8)
226        self.assertRaises(ValueError, int, '0xg', 16)
227        self.assertRaises(ValueError, int, '0x0g', 16)
228        self.assertRaises(ValueError, int, '0Xg', 16)
229        self.assertRaises(ValueError, int, '0X0g', 16)
230
231        # SF bug 1334662: int(string, base) wrong answers
232        # Checks for proper evaluation of 2**32 + 1
233        self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297L)
234        self.assertEqual(int('102002022201221111212', 3), 4294967297L)
235        self.assertEqual(int('10000000000000001', 4), 4294967297L)
236        self.assertEqual(int('32244002423142', 5), 4294967297L)
237        self.assertEqual(int('1550104015505', 6), 4294967297L)
238        self.assertEqual(int('211301422355', 7), 4294967297L)
239        self.assertEqual(int('40000000001', 8), 4294967297L)
240        self.assertEqual(int('12068657455', 9), 4294967297L)
241        self.assertEqual(int('4294967297', 10), 4294967297L)
242        self.assertEqual(int('1904440555', 11), 4294967297L)
243        self.assertEqual(int('9ba461595', 12), 4294967297L)
244        self.assertEqual(int('535a7988a', 13), 4294967297L)
245        self.assertEqual(int('2ca5b7465', 14), 4294967297L)
246        self.assertEqual(int('1a20dcd82', 15), 4294967297L)
247        self.assertEqual(int('100000001', 16), 4294967297L)
248        self.assertEqual(int('a7ffda92', 17), 4294967297L)
249        self.assertEqual(int('704he7g5', 18), 4294967297L)
250        self.assertEqual(int('4f5aff67', 19), 4294967297L)
251        self.assertEqual(int('3723ai4h', 20), 4294967297L)
252        self.assertEqual(int('281d55i5', 21), 4294967297L)
253        self.assertEqual(int('1fj8b185', 22), 4294967297L)
254        self.assertEqual(int('1606k7id', 23), 4294967297L)
255        self.assertEqual(int('mb994ah', 24), 4294967297L)
256        self.assertEqual(int('hek2mgm', 25), 4294967297L)
257        self.assertEqual(int('dnchbnn', 26), 4294967297L)
258        self.assertEqual(int('b28jpdn', 27), 4294967297L)
259        self.assertEqual(int('8pfgih5', 28), 4294967297L)
260        self.assertEqual(int('76beigh', 29), 4294967297L)
261        self.assertEqual(int('5qmcpqh', 30), 4294967297L)
262        self.assertEqual(int('4q0jto5', 31), 4294967297L)
263        self.assertEqual(int('4000001', 32), 4294967297L)
264        self.assertEqual(int('3aokq95', 33), 4294967297L)
265        self.assertEqual(int('2qhxjlj', 34), 4294967297L)
266        self.assertEqual(int('2br45qc', 35), 4294967297L)
267        self.assertEqual(int('1z141z5', 36), 4294967297L)
268
269    def test_bit_length(self):
270        tiny = 1e-10
271        for x in xrange(-65000, 65000):
272            k = x.bit_length()
273            # Check equivalence with Python version
274            self.assertEqual(k, len(bin(x).lstrip('-0b')))
275            # Behaviour as specified in the docs
276            if x != 0:
277                self.assertTrue(2**(k-1) <= abs(x) < 2**k)
278            else:
279                self.assertEqual(k, 0)
280            # Alternative definition: x.bit_length() == 1 + floor(log_2(x))
281            if x != 0:
282                # When x is an exact power of 2, numeric errors can
283                # cause floor(log(x)/log(2)) to be one too small; for
284                # small x this can be fixed by adding a small quantity
285                # to the quotient before taking the floor.
286                self.assertEqual(k, 1 + math.floor(
287                        math.log(abs(x))/math.log(2) + tiny))
288
289        self.assertEqual((0).bit_length(), 0)
290        self.assertEqual((1).bit_length(), 1)
291        self.assertEqual((-1).bit_length(), 1)
292        self.assertEqual((2).bit_length(), 2)
293        self.assertEqual((-2).bit_length(), 2)
294        for i in [2, 3, 15, 16, 17, 31, 32, 33, 63, 64]:
295            a = 2**i
296            self.assertEqual((a-1).bit_length(), i)
297            self.assertEqual((1-a).bit_length(), i)
298            self.assertEqual((a).bit_length(), i+1)
299            self.assertEqual((-a).bit_length(), i+1)
300            self.assertEqual((a+1).bit_length(), i+1)
301            self.assertEqual((-a-1).bit_length(), i+1)
302
303    @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
304                         "test requires IEEE 754 doubles")
305    def test_float_conversion(self):
306        # values exactly representable as floats
307        exact_values = [-2, -1, 0, 1, 2, 2**52, 2**53-1, 2**53, 2**53+2,
308                         2**53+4, 2**54-4, 2**54-2, 2**63, -2**63, 2**64,
309                         -2**64, 10**20, 10**21, 10**22]
310        for value in exact_values:
311            self.assertEqual(int(float(int(value))), value)
312
313        # test round-half-to-even
314        self.assertEqual(int(float(2**53+1)), 2**53)
315        self.assertEqual(int(float(2**53+2)), 2**53+2)
316        self.assertEqual(int(float(2**53+3)), 2**53+4)
317        self.assertEqual(int(float(2**53+5)), 2**53+4)
318        self.assertEqual(int(float(2**53+6)), 2**53+6)
319        self.assertEqual(int(float(2**53+7)), 2**53+8)
320
321        self.assertEqual(int(float(-2**53-1)), -2**53)
322        self.assertEqual(int(float(-2**53-2)), -2**53-2)
323        self.assertEqual(int(float(-2**53-3)), -2**53-4)
324        self.assertEqual(int(float(-2**53-5)), -2**53-4)
325        self.assertEqual(int(float(-2**53-6)), -2**53-6)
326        self.assertEqual(int(float(-2**53-7)), -2**53-8)
327
328        self.assertEqual(int(float(2**54-2)), 2**54-2)
329        self.assertEqual(int(float(2**54-1)), 2**54)
330        self.assertEqual(int(float(2**54+2)), 2**54)
331        self.assertEqual(int(float(2**54+3)), 2**54+4)
332        self.assertEqual(int(float(2**54+5)), 2**54+4)
333        self.assertEqual(int(float(2**54+6)), 2**54+8)
334        self.assertEqual(int(float(2**54+10)), 2**54+8)
335        self.assertEqual(int(float(2**54+11)), 2**54+12)
336
337    def test_valid_non_numeric_input_types_for_x(self):
338        # Test possible valid non-numeric types for x, including subclasses
339        # of the allowed built-in types.
340        class CustomStr(str): pass
341        values = ['100', CustomStr('100')]
342
343        if have_unicode:
344            class CustomUnicode(unicode): pass
345            values += [unicode('100'), CustomUnicode(unicode('100'))]
346
347        for x in values:
348            msg = 'x has value %s and type %s' % (x, type(x).__name__)
349            try:
350                self.assertEquals(int(x), 100, msg=msg)
351                self.assertEquals(int(x, 2), 4, msg=msg)
352            except TypeError, err:
353                raise AssertionError('For %s got TypeError: %s' %
354                                     (type(x).__name__, err))
355
356    def test_error_on_string_float_for_x(self):
357        self.assertRaises(ValueError, int, '1.2')
358
359    def test_error_on_bytearray_for_x(self):
360        self.assertRaises(TypeError, int, bytearray('100'), 2)
361
362    def test_error_on_invalid_int_bases(self):
363        for base in [-1, 1, 1000]:
364            self.assertRaises(ValueError, int, '100', base)
365
366    def test_error_on_string_base(self):
367        self.assertRaises(TypeError, int, 100, base='foo')
368        # Include the following because in contrast CPython raises no error
369        # for bad integer bases when x is not given.
370        self.assertRaises(TypeError, int, base='foo')
371
372    # For example, PyPy 1.9.0 raised TypeError for these cases because it
373    # expects x to be a string if base is given.
374    @test_support.cpython_only
375    def test_int_base_without_x_returns_0(self):
376        self.assertEquals(int(base=6), 0)
377        # Even invalid bases don't raise an exception.
378        self.assertEquals(int(base=1), 0)
379        self.assertEquals(int(base=1000), 0)
380
381    def test_intconversion(self):
382        # Test __int__()
383        class ClassicMissingMethods:
384            pass
385        self.assertRaises(AttributeError, int, ClassicMissingMethods())
386
387        class MissingMethods(object):
388            pass
389        self.assertRaises(TypeError, int, MissingMethods())
390
391        class Foo0:
392            def __int__(self):
393                return 42
394
395        class Foo1(object):
396            def __int__(self):
397                return 42
398
399        class Foo2(int):
400            def __int__(self):
401                return 42
402
403        class Foo3(int):
404            def __int__(self):
405                return self
406
407        class Foo4(int):
408            def __int__(self):
409                return 42L
410
411        class Foo5(int):
412            def __int__(self):
413                return 42.
414
415        self.assertEqual(int(Foo0()), 42)
416        self.assertEqual(int(Foo1()), 42)
417        self.assertEqual(int(Foo2()), 42)
418        self.assertEqual(int(Foo3()), 0)
419        self.assertEqual(int(Foo4()), 42L)
420        self.assertRaises(TypeError, int, Foo5())
421
422        class Classic:
423            pass
424        for base in (object, Classic):
425            class IntOverridesTrunc(base):
426                def __int__(self):
427                    return 42
428                def __trunc__(self):
429                    return -12
430            self.assertEqual(int(IntOverridesTrunc()), 42)
431
432            class JustTrunc(base):
433                def __trunc__(self):
434                    return 42
435            self.assertEqual(int(JustTrunc()), 42)
436
437            for trunc_result_base in (object, Classic):
438                class Integral(trunc_result_base):
439                    def __int__(self):
440                        return 42
441
442                class TruncReturnsNonInt(base):
443                    def __trunc__(self):
444                        return Integral()
445                self.assertEqual(int(TruncReturnsNonInt()), 42)
446
447                class NonIntegral(trunc_result_base):
448                    def __trunc__(self):
449                        # Check that we avoid infinite recursion.
450                        return NonIntegral()
451
452                class TruncReturnsNonIntegral(base):
453                    def __trunc__(self):
454                        return NonIntegral()
455                try:
456                    int(TruncReturnsNonIntegral())
457                except TypeError as e:
458                    self.assertEqual(str(e),
459                                      "__trunc__ returned non-Integral"
460                                      " (type NonIntegral)")
461                else:
462                    self.fail("Failed to raise TypeError with %s" %
463                              ((base, trunc_result_base),))
464
465def test_main():
466    run_unittest(IntTestCases)
467
468if __name__ == "__main__":
469    test_main()
470