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