Home | History | Annotate | Download | only in test
      1 import math
      2 import unittest
      3 import sys
      4 import _ast
      5 from test import test_support
      6 from test import script_helper
      7 import os
      8 import tempfile
      9 import textwrap
     10 
     11 class TestSpecifics(unittest.TestCase):
     12 
     13     def test_no_ending_newline(self):
     14         compile("hi", "<test>", "exec")
     15         compile("hi\r", "<test>", "exec")
     16 
     17     def test_empty(self):
     18         compile("", "<test>", "exec")
     19 
     20     def test_other_newlines(self):
     21         compile("\r\n", "<test>", "exec")
     22         compile("\r", "<test>", "exec")
     23         compile("hi\r\nstuff\r\ndef f():\n    pass\r", "<test>", "exec")
     24         compile("this_is\rreally_old_mac\rdef f():\n    pass", "<test>", "exec")
     25 
     26     def test_debug_assignment(self):
     27         # catch assignments to __debug__
     28         self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single')
     29         import __builtin__
     30         prev = __builtin__.__debug__
     31         setattr(__builtin__, '__debug__', 'sure')
     32         setattr(__builtin__, '__debug__', prev)
     33 
     34     def test_argument_handling(self):
     35         # detect duplicate positional and keyword arguments
     36         self.assertRaises(SyntaxError, eval, 'lambda a,a:0')
     37         self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0')
     38         self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0')
     39         try:
     40             exec 'def f(a, a): pass'
     41             self.fail("duplicate arguments")
     42         except SyntaxError:
     43             pass
     44         try:
     45             exec 'def f(a = 0, a = 1): pass'
     46             self.fail("duplicate keyword arguments")
     47         except SyntaxError:
     48             pass
     49         try:
     50             exec 'def f(a): global a; a = 1'
     51             self.fail("variable is global and local")
     52         except SyntaxError:
     53             pass
     54 
     55     def test_syntax_error(self):
     56         self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec")
     57 
     58     def test_none_keyword_arg(self):
     59         self.assertRaises(SyntaxError, compile, "f(None=1)", "<string>", "exec")
     60 
     61     def test_duplicate_global_local(self):
     62         try:
     63             exec 'def f(a): global a; a = 1'
     64             self.fail("variable is global and local")
     65         except SyntaxError:
     66             pass
     67 
     68     def test_exec_functional_style(self):
     69         # Exec'ing a tuple of length 2 works.
     70         g = {'b': 2}
     71         exec("a = b + 1", g)
     72         self.assertEqual(g['a'], 3)
     73 
     74         # As does exec'ing a tuple of length 3.
     75         l = {'b': 3}
     76         g = {'b': 5, 'c': 7}
     77         exec("a = b + c", g, l)
     78         self.assertNotIn('a', g)
     79         self.assertEqual(l['a'], 10)
     80 
     81         # Tuples not of length 2 or 3 are invalid.
     82         with self.assertRaises(TypeError):
     83             exec("a = b + 1",)
     84 
     85         with self.assertRaises(TypeError):
     86             exec("a = b + 1", {}, {}, {})
     87 
     88         # Can't mix and match the two calling forms.
     89         g = {'a': 3, 'b': 4}
     90         l = {}
     91         with self.assertRaises(TypeError):
     92             exec("a = b + 1", g) in g
     93         with self.assertRaises(TypeError):
     94             exec("a = b + 1", g, l) in g, l
     95 
     96     def test_nested_qualified_exec(self):
     97         # Can use qualified exec in nested functions.
     98         code = ["""
     99 def g():
    100     def f():
    101         if True:
    102             exec "" in {}, {}
    103         """, """
    104 def g():
    105     def f():
    106         if True:
    107             exec("", {}, {})
    108         """, """
    109 def g():
    110     def f():
    111         if True:
    112             exec("", {})
    113         """]
    114         for c in code:
    115             compile(c, "<code>", "exec")
    116 
    117     def test_exec_with_general_mapping_for_locals(self):
    118 
    119         class M:
    120             "Test mapping interface versus possible calls from eval()."
    121             def __getitem__(self, key):
    122                 if key == 'a':
    123                     return 12
    124                 raise KeyError
    125             def __setitem__(self, key, value):
    126                 self.results = (key, value)
    127             def keys(self):
    128                 return list('xyz')
    129 
    130         m = M()
    131         g = globals()
    132         exec 'z = a' in g, m
    133         self.assertEqual(m.results, ('z', 12))
    134         try:
    135             exec 'z = b' in g, m
    136         except NameError:
    137             pass
    138         else:
    139             self.fail('Did not detect a KeyError')
    140         exec 'z = dir()' in g, m
    141         self.assertEqual(m.results, ('z', list('xyz')))
    142         exec 'z = globals()' in g, m
    143         self.assertEqual(m.results, ('z', g))
    144         exec 'z = locals()' in g, m
    145         self.assertEqual(m.results, ('z', m))
    146         try:
    147             exec 'z = b' in m
    148         except TypeError:
    149             pass
    150         else:
    151             self.fail('Did not validate globals as a real dict')
    152 
    153         class A:
    154             "Non-mapping"
    155             pass
    156         m = A()
    157         try:
    158             exec 'z = a' in g, m
    159         except TypeError:
    160             pass
    161         else:
    162             self.fail('Did not validate locals as a mapping')
    163 
    164         # Verify that dict subclasses work as well
    165         class D(dict):
    166             def __getitem__(self, key):
    167                 if key == 'a':
    168                     return 12
    169                 return dict.__getitem__(self, key)
    170         d = D()
    171         exec 'z = a' in g, d
    172         self.assertEqual(d['z'], 12)
    173 
    174     def test_extended_arg(self):
    175         longexpr = 'x = x or ' + '-x' * 2500
    176         code = '''
    177 def f(x):
    178     %s
    179     %s
    180     %s
    181     %s
    182     %s
    183     %s
    184     %s
    185     %s
    186     %s
    187     %s
    188     # the expressions above have no effect, x == argument
    189     while x:
    190         x -= 1
    191         # EXTENDED_ARG/JUMP_ABSOLUTE here
    192     return x
    193 ''' % ((longexpr,)*10)
    194         exec code
    195         self.assertEqual(f(5), 0)
    196 
    197     def test_complex_args(self):
    198 
    199         with test_support.check_py3k_warnings(
    200                 ("tuple parameter unpacking has been removed", SyntaxWarning)):
    201             exec textwrap.dedent('''
    202         def comp_args((a, b)):
    203             return a,b
    204         self.assertEqual(comp_args((1, 2)), (1, 2))
    205 
    206         def comp_args((a, b)=(3, 4)):
    207             return a, b
    208         self.assertEqual(comp_args((1, 2)), (1, 2))
    209         self.assertEqual(comp_args(), (3, 4))
    210 
    211         def comp_args(a, (b, c)):
    212             return a, b, c
    213         self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
    214 
    215         def comp_args(a=2, (b, c)=(3, 4)):
    216             return a, b, c
    217         self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
    218         self.assertEqual(comp_args(), (2, 3, 4))
    219         ''')
    220 
    221     def test_argument_order(self):
    222         try:
    223             exec 'def f(a=1, (b, c)): pass'
    224             self.fail("non-default args after default")
    225         except SyntaxError:
    226             pass
    227 
    228     def test_float_literals(self):
    229         # testing bad float literals
    230         self.assertRaises(SyntaxError, eval, "2e")
    231         self.assertRaises(SyntaxError, eval, "2.0e+")
    232         self.assertRaises(SyntaxError, eval, "1e-")
    233         self.assertRaises(SyntaxError, eval, "3-4e/21")
    234 
    235     def test_indentation(self):
    236         # testing compile() of indented block w/o trailing newline"
    237         s = """
    238 if 1:
    239     if 2:
    240         pass"""
    241         compile(s, "<string>", "exec")
    242 
    243     # This test is probably specific to CPython and may not generalize
    244     # to other implementations.  We are trying to ensure that when
    245     # the first line of code starts after 256, correct line numbers
    246     # in tracebacks are still produced.
    247     def test_leading_newlines(self):
    248         s256 = "".join(["\n"] * 256 + ["spam"])
    249         co = compile(s256, 'fn', 'exec')
    250         self.assertEqual(co.co_firstlineno, 257)
    251         self.assertEqual(co.co_lnotab, '')
    252 
    253     def test_literals_with_leading_zeroes(self):
    254         for arg in ["077787", "0xj", "0x.", "0e",  "090000000000000",
    255                     "080000000000000", "000000000000009", "000000000000008",
    256                     "0b42", "0BADCAFE", "0o123456789", "0b1.1", "0o4.2",
    257                     "0b101j2", "0o153j2", "0b100e1", "0o777e1", "0o8", "0o78"]:
    258             self.assertRaises(SyntaxError, eval, arg)
    259 
    260         self.assertEqual(eval("0777"), 511)
    261         self.assertEqual(eval("0777L"), 511)
    262         self.assertEqual(eval("000777"), 511)
    263         self.assertEqual(eval("0xff"), 255)
    264         self.assertEqual(eval("0xffL"), 255)
    265         self.assertEqual(eval("0XfF"), 255)
    266         self.assertEqual(eval("0777."), 777)
    267         self.assertEqual(eval("0777.0"), 777)
    268         self.assertEqual(eval("000000000000000000000000000000000000000000000000000777e0"), 777)
    269         self.assertEqual(eval("0777e1"), 7770)
    270         self.assertEqual(eval("0e0"), 0)
    271         self.assertEqual(eval("0000E-012"), 0)
    272         self.assertEqual(eval("09.5"), 9.5)
    273         self.assertEqual(eval("0777j"), 777j)
    274         self.assertEqual(eval("00j"), 0j)
    275         self.assertEqual(eval("00.0"), 0)
    276         self.assertEqual(eval("0e3"), 0)
    277         self.assertEqual(eval("090000000000000."), 90000000000000.)
    278         self.assertEqual(eval("090000000000000.0000000000000000000000"), 90000000000000.)
    279         self.assertEqual(eval("090000000000000e0"), 90000000000000.)
    280         self.assertEqual(eval("090000000000000e-0"), 90000000000000.)
    281         self.assertEqual(eval("090000000000000j"), 90000000000000j)
    282         self.assertEqual(eval("000000000000007"), 7)
    283         self.assertEqual(eval("000000000000008."), 8.)
    284         self.assertEqual(eval("000000000000009."), 9.)
    285         self.assertEqual(eval("0b101010"), 42)
    286         self.assertEqual(eval("-0b000000000010"), -2)
    287         self.assertEqual(eval("0o777"), 511)
    288         self.assertEqual(eval("-0o0000010"), -8)
    289         self.assertEqual(eval("020000000000.0"), 20000000000.0)
    290         self.assertEqual(eval("037777777777e0"), 37777777777.0)
    291         self.assertEqual(eval("01000000000000000000000.0"),
    292                          1000000000000000000000.0)
    293 
    294     def test_unary_minus(self):
    295         # Verify treatment of unary minus on negative numbers SF bug #660455
    296         if sys.maxint == 2147483647:
    297             # 32-bit machine
    298             all_one_bits = '0xffffffff'
    299             self.assertEqual(eval(all_one_bits), 4294967295L)
    300             self.assertEqual(eval("-" + all_one_bits), -4294967295L)
    301         elif sys.maxint == 9223372036854775807:
    302             # 64-bit machine
    303             all_one_bits = '0xffffffffffffffff'
    304             self.assertEqual(eval(all_one_bits), 18446744073709551615L)
    305             self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L)
    306         else:
    307             self.fail("How many bits *does* this machine have???")
    308         # Verify treatment of constant folding on -(sys.maxint+1)
    309         # i.e. -2147483648 on 32 bit platforms.  Should return int, not long.
    310         self.assertIsInstance(eval("%s" % (-sys.maxint - 1)), int)
    311         self.assertIsInstance(eval("%s" % (-sys.maxint - 2)), long)
    312 
    313     if sys.maxint == 9223372036854775807:
    314         def test_32_63_bit_values(self):
    315             a = +4294967296  # 1 << 32
    316             b = -4294967296  # 1 << 32
    317             c = +281474976710656  # 1 << 48
    318             d = -281474976710656  # 1 << 48
    319             e = +4611686018427387904  # 1 << 62
    320             f = -4611686018427387904  # 1 << 62
    321             g = +9223372036854775807  # 1 << 63 - 1
    322             h = -9223372036854775807  # 1 << 63 - 1
    323 
    324             for variable in self.test_32_63_bit_values.func_code.co_consts:
    325                 if variable is not None:
    326                     self.assertIsInstance(variable, int)
    327 
    328     def test_sequence_unpacking_error(self):
    329         # Verify sequence packing/unpacking with "or".  SF bug #757818
    330         i,j = (1, -1) or (-1, 1)
    331         self.assertEqual(i, 1)
    332         self.assertEqual(j, -1)
    333 
    334     def test_none_assignment(self):
    335         stmts = [
    336             'None = 0',
    337             'None += 0',
    338             '__builtins__.None = 0',
    339             'def None(): pass',
    340             'class None: pass',
    341             '(a, None) = 0, 0',
    342             'for None in range(10): pass',
    343             'def f(None): pass',
    344             'import None',
    345             'import x as None',
    346             'from x import None',
    347             'from x import y as None'
    348         ]
    349         for stmt in stmts:
    350             stmt += "\n"
    351             self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
    352             self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
    353         # This is ok.
    354         compile("from None import x", "tmp", "exec")
    355         compile("from x import None as y", "tmp", "exec")
    356         compile("import None as x", "tmp", "exec")
    357 
    358     def test_import(self):
    359         succeed = [
    360             'import sys',
    361             'import os, sys',
    362             'import os as bar',
    363             'import os.path as bar',
    364             'from __future__ import nested_scopes, generators',
    365             'from __future__ import (nested_scopes,\ngenerators)',
    366             'from __future__ import (nested_scopes,\ngenerators,)',
    367             'from sys import stdin, stderr, stdout',
    368             'from sys import (stdin, stderr,\nstdout)',
    369             'from sys import (stdin, stderr,\nstdout,)',
    370             'from sys import (stdin\n, stderr, stdout)',
    371             'from sys import (stdin\n, stderr, stdout,)',
    372             'from sys import stdin as si, stdout as so, stderr as se',
    373             'from sys import (stdin as si, stdout as so, stderr as se)',
    374             'from sys import (stdin as si, stdout as so, stderr as se,)',
    375             ]
    376         fail = [
    377             'import (os, sys)',
    378             'import (os), (sys)',
    379             'import ((os), (sys))',
    380             'import (sys',
    381             'import sys)',
    382             'import (os,)',
    383             'import os As bar',
    384             'import os.path a bar',
    385             'from sys import stdin As stdout',
    386             'from sys import stdin a stdout',
    387             'from (sys) import stdin',
    388             'from __future__ import (nested_scopes',
    389             'from __future__ import nested_scopes)',
    390             'from __future__ import nested_scopes,\ngenerators',
    391             'from sys import (stdin',
    392             'from sys import stdin)',
    393             'from sys import stdin, stdout,\nstderr',
    394             'from sys import stdin si',
    395             'from sys import stdin,'
    396             'from sys import (*)',
    397             'from sys import (stdin,, stdout, stderr)',
    398             'from sys import (stdin, stdout),',
    399             ]
    400         for stmt in succeed:
    401             compile(stmt, 'tmp', 'exec')
    402         for stmt in fail:
    403             self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
    404 
    405     def test_for_distinct_code_objects(self):
    406         # SF bug 1048870
    407         def f():
    408             f1 = lambda x=1: x
    409             f2 = lambda x=2: x
    410             return f1, f2
    411         f1, f2 = f()
    412         self.assertNotEqual(id(f1.func_code), id(f2.func_code))
    413 
    414     def test_lambda_doc(self):
    415         l = lambda: "foo"
    416         self.assertIsNone(l.__doc__)
    417 
    418     @test_support.requires_unicode
    419     def test_encoding(self):
    420         code = b'# -*- coding: badencoding -*-\npass\n'
    421         self.assertRaises(SyntaxError, compile, code, 'tmp', 'exec')
    422         code = u"# -*- coding: utf-8 -*-\npass\n"
    423         self.assertRaises(SyntaxError, compile, code, "tmp", "exec")
    424         code = 'u"\xc2\xa4"\n'
    425         self.assertEqual(eval(code), u'\xc2\xa4')
    426         code = u'u"\xc2\xa4"\n'
    427         self.assertEqual(eval(code), u'\xc2\xa4')
    428         code = '# -*- coding: latin1 -*-\nu"\xc2\xa4"\n'
    429         self.assertEqual(eval(code), u'\xc2\xa4')
    430         code = '# -*- coding: utf-8 -*-\nu"\xc2\xa4"\n'
    431         self.assertEqual(eval(code), u'\xa4')
    432         code = '# -*- coding: iso8859-15 -*-\nu"\xc2\xa4"\n'
    433         self.assertEqual(eval(code), test_support.u(r'\xc2\u20ac'))
    434         code = 'u"""\\\n# -*- coding: utf-8 -*-\n\xc2\xa4"""\n'
    435         self.assertEqual(eval(code), u'# -*- coding: utf-8 -*-\n\xc2\xa4')
    436 
    437     def test_subscripts(self):
    438         # SF bug 1448804
    439         # Class to make testing subscript results easy
    440         class str_map(object):
    441             def __init__(self):
    442                 self.data = {}
    443             def __getitem__(self, key):
    444                 return self.data[str(key)]
    445             def __setitem__(self, key, value):
    446                 self.data[str(key)] = value
    447             def __delitem__(self, key):
    448                 del self.data[str(key)]
    449             def __contains__(self, key):
    450                 return str(key) in self.data
    451         d = str_map()
    452         # Index
    453         d[1] = 1
    454         self.assertEqual(d[1], 1)
    455         d[1] += 1
    456         self.assertEqual(d[1], 2)
    457         del d[1]
    458         self.assertNotIn(1, d)
    459         # Tuple of indices
    460         d[1, 1] = 1
    461         self.assertEqual(d[1, 1], 1)
    462         d[1, 1] += 1
    463         self.assertEqual(d[1, 1], 2)
    464         del d[1, 1]
    465         self.assertNotIn((1, 1), d)
    466         # Simple slice
    467         d[1:2] = 1
    468         self.assertEqual(d[1:2], 1)
    469         d[1:2] += 1
    470         self.assertEqual(d[1:2], 2)
    471         del d[1:2]
    472         self.assertNotIn(slice(1, 2), d)
    473         # Tuple of simple slices
    474         d[1:2, 1:2] = 1
    475         self.assertEqual(d[1:2, 1:2], 1)
    476         d[1:2, 1:2] += 1
    477         self.assertEqual(d[1:2, 1:2], 2)
    478         del d[1:2, 1:2]
    479         self.assertNotIn((slice(1, 2), slice(1, 2)), d)
    480         # Extended slice
    481         d[1:2:3] = 1
    482         self.assertEqual(d[1:2:3], 1)
    483         d[1:2:3] += 1
    484         self.assertEqual(d[1:2:3], 2)
    485         del d[1:2:3]
    486         self.assertNotIn(slice(1, 2, 3), d)
    487         # Tuple of extended slices
    488         d[1:2:3, 1:2:3] = 1
    489         self.assertEqual(d[1:2:3, 1:2:3], 1)
    490         d[1:2:3, 1:2:3] += 1
    491         self.assertEqual(d[1:2:3, 1:2:3], 2)
    492         del d[1:2:3, 1:2:3]
    493         self.assertNotIn((slice(1, 2, 3), slice(1, 2, 3)), d)
    494         # Ellipsis
    495         d[...] = 1
    496         self.assertEqual(d[...], 1)
    497         d[...] += 1
    498         self.assertEqual(d[...], 2)
    499         del d[...]
    500         self.assertNotIn(Ellipsis, d)
    501         # Tuple of Ellipses
    502         d[..., ...] = 1
    503         self.assertEqual(d[..., ...], 1)
    504         d[..., ...] += 1
    505         self.assertEqual(d[..., ...], 2)
    506         del d[..., ...]
    507         self.assertNotIn((Ellipsis, Ellipsis), d)
    508 
    509     def test_mangling(self):
    510         class A:
    511             def f():
    512                 __mangled = 1
    513                 __not_mangled__ = 2
    514                 import __mangled_mod
    515                 import __package__.module
    516 
    517         self.assertIn("_A__mangled", A.f.func_code.co_varnames)
    518         self.assertIn("__not_mangled__", A.f.func_code.co_varnames)
    519         self.assertIn("_A__mangled_mod", A.f.func_code.co_varnames)
    520         self.assertIn("__package__", A.f.func_code.co_varnames)
    521 
    522     def test_compile_ast(self):
    523         fname = __file__
    524         if fname.lower().endswith(('pyc', 'pyo')):
    525             fname = fname[:-1]
    526         with open(fname, 'r') as f:
    527             fcontents = f.read()
    528         sample_code = [
    529             ['<assign>', 'x = 5'],
    530             ['<print1>', 'print 1'],
    531             ['<printv>', 'print v'],
    532             ['<printTrue>', 'print True'],
    533             ['<printList>', 'print []'],
    534             ['<ifblock>', """if True:\n    pass\n"""],
    535             ['<forblock>', """for n in [1, 2, 3]:\n    print n\n"""],
    536             ['<deffunc>', """def foo():\n    pass\nfoo()\n"""],
    537             [fname, fcontents],
    538         ]
    539 
    540         for fname, code in sample_code:
    541             co1 = compile(code, '%s1' % fname, 'exec')
    542             ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST)
    543             self.assertTrue(type(ast) == _ast.Module)
    544             co2 = compile(ast, '%s3' % fname, 'exec')
    545             self.assertEqual(co1, co2)
    546             # the code object's filename comes from the second compilation step
    547             self.assertEqual(co2.co_filename, '%s3' % fname)
    548 
    549         # raise exception when node type doesn't match with compile mode
    550         co1 = compile('print 1', '<string>', 'exec', _ast.PyCF_ONLY_AST)
    551         self.assertRaises(TypeError, compile, co1, '<ast>', 'eval')
    552 
    553         # raise exception when node type is no start node
    554         self.assertRaises(TypeError, compile, _ast.If(), '<ast>', 'exec')
    555 
    556         # raise exception when node has invalid children
    557         ast = _ast.Module()
    558         ast.body = [_ast.BoolOp()]
    559         self.assertRaises(TypeError, compile, ast, '<ast>', 'exec')
    560 
    561     def test_yet_more_evil_still_undecodable(self):
    562         # Issue #25388
    563         src = b"#\x00\n#\xfd\n"
    564         tmpd = tempfile.mkdtemp()
    565         try:
    566             fn = os.path.join(tmpd, "bad.py")
    567             with open(fn, "wb") as fp:
    568                 fp.write(src)
    569             rc, out, err = script_helper.assert_python_failure(fn)
    570         finally:
    571             test_support.rmtree(tmpd)
    572         self.assertIn(b"Non-ASCII", err)
    573 
    574     def test_null_terminated(self):
    575         # The source code is null-terminated internally, but bytes-like
    576         # objects are accepted, which could be not terminated.
    577         with self.assertRaisesRegexp(TypeError, "without null bytes"):
    578             compile(u"123\x00", "<dummy>", "eval")
    579         with test_support.check_py3k_warnings():
    580             with self.assertRaisesRegexp(TypeError, "without null bytes"):
    581                 compile(buffer("123\x00"), "<dummy>", "eval")
    582             code = compile(buffer("123\x00", 1, 2), "<dummy>", "eval")
    583             self.assertEqual(eval(code), 23)
    584             code = compile(buffer("1234", 1, 2), "<dummy>", "eval")
    585             self.assertEqual(eval(code), 23)
    586             code = compile(buffer("$23$", 1, 2), "<dummy>", "eval")
    587             self.assertEqual(eval(code), 23)
    588 
    589 class TestStackSize(unittest.TestCase):
    590     # These tests check that the computed stack size for a code object
    591     # stays within reasonable bounds (see issue #21523 for an example
    592     # dysfunction).
    593     N = 100
    594 
    595     def check_stack_size(self, code):
    596         # To assert that the alleged stack size is not O(N), we
    597         # check that it is smaller than log(N).
    598         if isinstance(code, str):
    599             code = compile(code, "<foo>", "single")
    600         max_size = math.ceil(math.log(len(code.co_code)))
    601         self.assertLessEqual(code.co_stacksize, max_size)
    602 
    603     def test_and(self):
    604         self.check_stack_size("x and " * self.N + "x")
    605 
    606     def test_or(self):
    607         self.check_stack_size("x or " * self.N + "x")
    608 
    609     def test_and_or(self):
    610         self.check_stack_size("x and x or " * self.N + "x")
    611 
    612     def test_chained_comparison(self):
    613         self.check_stack_size("x < " * self.N + "x")
    614 
    615     def test_if_else(self):
    616         self.check_stack_size("x if x else " * self.N + "x")
    617 
    618     def test_binop(self):
    619         self.check_stack_size("x + " * self.N + "x")
    620 
    621     def test_func_and(self):
    622         code = "def f(x):\n"
    623         code += "   x and x\n" * self.N
    624         self.check_stack_size(code)
    625 
    626     def check_constant(self, func, expected):
    627         for const in func.__code__.co_consts:
    628             if repr(const) == repr(expected):
    629                 break
    630         else:
    631             self.fail("unable to find constant %r in %r"
    632                       % (expected, func.__code__.co_consts))
    633 
    634     # Merging equal constants is not a strict requirement for the Python
    635     # semantics, it's a more an implementation detail.
    636     @test_support.cpython_only
    637     def test_merge_constants(self):
    638         # Issue #25843: compile() must merge constants which are equal
    639         # and have the same type.
    640 
    641         def check_same_constant(const):
    642             ns = {}
    643             code = "f1, f2 = lambda: %r, lambda: %r" % (const, const)
    644             exec(code, ns)
    645             f1 = ns['f1']
    646             f2 = ns['f2']
    647             self.assertIs(f1.__code__, f2.__code__)
    648             self.check_constant(f1, const)
    649             self.assertEqual(repr(f1()), repr(const))
    650 
    651         check_same_constant(None)
    652         check_same_constant(0)
    653         check_same_constant(0.0)
    654         check_same_constant(b'abc')
    655         check_same_constant('abc')
    656 
    657     def test_dont_merge_constants(self):
    658         # Issue #25843: compile() must not merge constants which are equal
    659         # but have a different type.
    660 
    661         def check_different_constants(const1, const2):
    662             ns = {}
    663             exec("f1, f2 = lambda: %r, lambda: %r" % (const1, const2), ns)
    664             f1 = ns['f1']
    665             f2 = ns['f2']
    666             self.assertIsNot(f1.__code__, f2.__code__)
    667             self.check_constant(f1, const1)
    668             self.check_constant(f2, const2)
    669             self.assertEqual(repr(f1()), repr(const1))
    670             self.assertEqual(repr(f2()), repr(const2))
    671 
    672         check_different_constants(0, 0.0)
    673         check_different_constants(+0.0, -0.0)
    674         check_different_constants((0,), (0.0,))
    675 
    676         # check_different_constants() cannot be used because repr(-0j) is
    677         # '(-0-0j)', but when '(-0-0j)' is evaluated to 0j: we loose the sign.
    678         f1, f2 = lambda: +0.0j, lambda: -0.0j
    679         self.assertIsNot(f1.__code__, f2.__code__)
    680         self.check_constant(f1, +0.0j)
    681         self.check_constant(f2, -0.0j)
    682         self.assertEqual(repr(f1()), repr(+0.0j))
    683         self.assertEqual(repr(f2()), repr(-0.0j))
    684 
    685 
    686 def test_main():
    687     test_support.run_unittest(__name__)
    688 
    689 if __name__ == "__main__":
    690     unittest.main()
    691