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