Home | History | Annotate | Download | only in test
      1 # Minimal tests for dis module
      2 
      3 from test.support import captured_stdout
      4 from test.bytecode_helper import BytecodeTestCase
      5 import unittest
      6 import sys
      7 import dis
      8 import io
      9 import re
     10 import types
     11 import contextlib
     12 
     13 def get_tb():
     14     def _error():
     15         try:
     16             1 / 0
     17         except Exception as e:
     18             tb = e.__traceback__
     19         return tb
     20 
     21     tb = _error()
     22     while tb.tb_next:
     23         tb = tb.tb_next
     24     return tb
     25 
     26 TRACEBACK_CODE = get_tb().tb_frame.f_code
     27 
     28 class _C:
     29     def __init__(self, x):
     30         self.x = x == 1
     31 
     32     @staticmethod
     33     def sm(x):
     34         x = x == 1
     35 
     36     @classmethod
     37     def cm(cls, x):
     38         cls.x = x == 1
     39 
     40 dis_c_instance_method = """\
     41 %3d           0 LOAD_FAST                1 (x)
     42               2 LOAD_CONST               1 (1)
     43               4 COMPARE_OP               2 (==)
     44               6 LOAD_FAST                0 (self)
     45               8 STORE_ATTR               0 (x)
     46              10 LOAD_CONST               0 (None)
     47              12 RETURN_VALUE
     48 """ % (_C.__init__.__code__.co_firstlineno + 1,)
     49 
     50 dis_c_instance_method_bytes = """\
     51           0 LOAD_FAST                1 (1)
     52           2 LOAD_CONST               1 (1)
     53           4 COMPARE_OP               2 (==)
     54           6 LOAD_FAST                0 (0)
     55           8 STORE_ATTR               0 (0)
     56          10 LOAD_CONST               0 (0)
     57          12 RETURN_VALUE
     58 """
     59 
     60 dis_c_class_method = """\
     61 %3d           0 LOAD_FAST                1 (x)
     62               2 LOAD_CONST               1 (1)
     63               4 COMPARE_OP               2 (==)
     64               6 LOAD_FAST                0 (cls)
     65               8 STORE_ATTR               0 (x)
     66              10 LOAD_CONST               0 (None)
     67              12 RETURN_VALUE
     68 """ % (_C.cm.__code__.co_firstlineno + 2,)
     69 
     70 dis_c_static_method = """\
     71 %3d           0 LOAD_FAST                0 (x)
     72               2 LOAD_CONST               1 (1)
     73               4 COMPARE_OP               2 (==)
     74               6 STORE_FAST               0 (x)
     75               8 LOAD_CONST               0 (None)
     76              10 RETURN_VALUE
     77 """ % (_C.sm.__code__.co_firstlineno + 2,)
     78 
     79 # Class disassembling info has an extra newline at end.
     80 dis_c = """\
     81 Disassembly of %s:
     82 %s
     83 Disassembly of %s:
     84 %s
     85 Disassembly of %s:
     86 %s
     87 """ % (_C.__init__.__name__, dis_c_instance_method,
     88        _C.cm.__name__, dis_c_class_method,
     89        _C.sm.__name__, dis_c_static_method)
     90 
     91 def _f(a):
     92     print(a)
     93     return 1
     94 
     95 dis_f = """\
     96 %3d           0 LOAD_GLOBAL              0 (print)
     97               2 LOAD_FAST                0 (a)
     98               4 CALL_FUNCTION            1
     99               6 POP_TOP
    100 
    101 %3d           8 LOAD_CONST               1 (1)
    102              10 RETURN_VALUE
    103 """ % (_f.__code__.co_firstlineno + 1,
    104        _f.__code__.co_firstlineno + 2)
    105 
    106 
    107 dis_f_co_code = """\
    108           0 LOAD_GLOBAL              0 (0)
    109           2 LOAD_FAST                0 (0)
    110           4 CALL_FUNCTION            1
    111           6 POP_TOP
    112           8 LOAD_CONST               1 (1)
    113          10 RETURN_VALUE
    114 """
    115 
    116 
    117 def bug708901():
    118     for res in range(1,
    119                      10):
    120         pass
    121 
    122 dis_bug708901 = """\
    123 %3d           0 SETUP_LOOP              18 (to 20)
    124               2 LOAD_GLOBAL              0 (range)
    125               4 LOAD_CONST               1 (1)
    126 
    127 %3d           6 LOAD_CONST               2 (10)
    128               8 CALL_FUNCTION            2
    129              10 GET_ITER
    130         >>   12 FOR_ITER                 4 (to 18)
    131              14 STORE_FAST               0 (res)
    132 
    133 %3d          16 JUMP_ABSOLUTE           12
    134         >>   18 POP_BLOCK
    135         >>   20 LOAD_CONST               0 (None)
    136              22 RETURN_VALUE
    137 """ % (bug708901.__code__.co_firstlineno + 1,
    138        bug708901.__code__.co_firstlineno + 2,
    139        bug708901.__code__.co_firstlineno + 3)
    140 
    141 
    142 def bug1333982(x=[]):
    143     assert 0, ([s for s in x] +
    144               1)
    145     pass
    146 
    147 dis_bug1333982 = """\
    148 %3d           0 LOAD_CONST               1 (0)
    149               2 POP_JUMP_IF_TRUE        26
    150               4 LOAD_GLOBAL              0 (AssertionError)
    151               6 LOAD_CONST               2 (<code object <listcomp> at 0x..., file "%s", line %d>)
    152               8 LOAD_CONST               3 ('bug1333982.<locals>.<listcomp>')
    153              10 MAKE_FUNCTION            0
    154              12 LOAD_FAST                0 (x)
    155              14 GET_ITER
    156              16 CALL_FUNCTION            1
    157 
    158 %3d          18 LOAD_CONST               4 (1)
    159              20 BINARY_ADD
    160              22 CALL_FUNCTION            1
    161              24 RAISE_VARARGS            1
    162 
    163 %3d     >>   26 LOAD_CONST               0 (None)
    164              28 RETURN_VALUE
    165 """ % (bug1333982.__code__.co_firstlineno + 1,
    166        __file__,
    167        bug1333982.__code__.co_firstlineno + 1,
    168        bug1333982.__code__.co_firstlineno + 2,
    169        bug1333982.__code__.co_firstlineno + 3)
    170 
    171 _BIG_LINENO_FORMAT = """\
    172 %3d           0 LOAD_GLOBAL              0 (spam)
    173               2 POP_TOP
    174               4 LOAD_CONST               0 (None)
    175               6 RETURN_VALUE
    176 """
    177 
    178 _BIG_LINENO_FORMAT2 = """\
    179 %4d           0 LOAD_GLOBAL              0 (spam)
    180                2 POP_TOP
    181                4 LOAD_CONST               0 (None)
    182                6 RETURN_VALUE
    183 """
    184 
    185 dis_module_expected_results = """\
    186 Disassembly of f:
    187   4           0 LOAD_CONST               0 (None)
    188               2 RETURN_VALUE
    189 
    190 Disassembly of g:
    191   5           0 LOAD_CONST               0 (None)
    192               2 RETURN_VALUE
    193 
    194 """
    195 
    196 expr_str = "x + 1"
    197 
    198 dis_expr_str = """\
    199   1           0 LOAD_NAME                0 (x)
    200               2 LOAD_CONST               0 (1)
    201               4 BINARY_ADD
    202               6 RETURN_VALUE
    203 """
    204 
    205 simple_stmt_str = "x = x + 1"
    206 
    207 dis_simple_stmt_str = """\
    208   1           0 LOAD_NAME                0 (x)
    209               2 LOAD_CONST               0 (1)
    210               4 BINARY_ADD
    211               6 STORE_NAME               0 (x)
    212               8 LOAD_CONST               1 (None)
    213              10 RETURN_VALUE
    214 """
    215 
    216 annot_stmt_str = """\
    217 
    218 x: int = 1
    219 y: fun(1)
    220 lst[fun(0)]: int = 1
    221 """
    222 # leading newline is for a reason (tests lineno)
    223 
    224 dis_annot_stmt_str = """\
    225   2           0 SETUP_ANNOTATIONS
    226               2 LOAD_CONST               0 (1)
    227               4 STORE_NAME               0 (x)
    228               6 LOAD_NAME                1 (int)
    229               8 LOAD_NAME                2 (__annotations__)
    230              10 LOAD_CONST               1 ('x')
    231              12 STORE_SUBSCR
    232 
    233   3          14 LOAD_NAME                3 (fun)
    234              16 LOAD_CONST               0 (1)
    235              18 CALL_FUNCTION            1
    236              20 LOAD_NAME                2 (__annotations__)
    237              22 LOAD_CONST               2 ('y')
    238              24 STORE_SUBSCR
    239 
    240   4          26 LOAD_CONST               0 (1)
    241              28 LOAD_NAME                4 (lst)
    242              30 LOAD_NAME                3 (fun)
    243              32 LOAD_CONST               3 (0)
    244              34 CALL_FUNCTION            1
    245              36 STORE_SUBSCR
    246              38 LOAD_NAME                1 (int)
    247              40 POP_TOP
    248              42 LOAD_CONST               4 (None)
    249              44 RETURN_VALUE
    250 """
    251 
    252 compound_stmt_str = """\
    253 x = 0
    254 while 1:
    255     x += 1"""
    256 # Trailing newline has been deliberately omitted
    257 
    258 dis_compound_stmt_str = """\
    259   1           0 LOAD_CONST               0 (0)
    260               2 STORE_NAME               0 (x)
    261 
    262   2           4 SETUP_LOOP              12 (to 18)
    263 
    264   3     >>    6 LOAD_NAME                0 (x)
    265               8 LOAD_CONST               1 (1)
    266              10 INPLACE_ADD
    267              12 STORE_NAME               0 (x)
    268              14 JUMP_ABSOLUTE            6
    269              16 POP_BLOCK
    270         >>   18 LOAD_CONST               2 (None)
    271              20 RETURN_VALUE
    272 """
    273 
    274 dis_traceback = """\
    275 %3d           0 SETUP_EXCEPT            12 (to 14)
    276 
    277 %3d           2 LOAD_CONST               1 (1)
    278               4 LOAD_CONST               2 (0)
    279     -->       6 BINARY_TRUE_DIVIDE
    280               8 POP_TOP
    281              10 POP_BLOCK
    282              12 JUMP_FORWARD            40 (to 54)
    283 
    284 %3d     >>   14 DUP_TOP
    285              16 LOAD_GLOBAL              0 (Exception)
    286              18 COMPARE_OP              10 (exception match)
    287              20 POP_JUMP_IF_FALSE       52
    288              22 POP_TOP
    289              24 STORE_FAST               0 (e)
    290              26 POP_TOP
    291              28 SETUP_FINALLY           10 (to 40)
    292 
    293 %3d          30 LOAD_FAST                0 (e)
    294              32 LOAD_ATTR                1 (__traceback__)
    295              34 STORE_FAST               1 (tb)
    296              36 POP_BLOCK
    297              38 LOAD_CONST               0 (None)
    298         >>   40 LOAD_CONST               0 (None)
    299              42 STORE_FAST               0 (e)
    300              44 DELETE_FAST              0 (e)
    301              46 END_FINALLY
    302              48 POP_EXCEPT
    303              50 JUMP_FORWARD             2 (to 54)
    304         >>   52 END_FINALLY
    305 
    306 %3d     >>   54 LOAD_FAST                1 (tb)
    307              56 RETURN_VALUE
    308 """ % (TRACEBACK_CODE.co_firstlineno + 1,
    309        TRACEBACK_CODE.co_firstlineno + 2,
    310        TRACEBACK_CODE.co_firstlineno + 3,
    311        TRACEBACK_CODE.co_firstlineno + 4,
    312        TRACEBACK_CODE.co_firstlineno + 5)
    313 
    314 def _fstring(a, b, c, d):
    315     return f'{a} {b:4} {c!r} {d!r:4}'
    316 
    317 dis_fstring = """\
    318 %3d           0 LOAD_FAST                0 (a)
    319               2 FORMAT_VALUE             0
    320               4 LOAD_CONST               1 (' ')
    321               6 LOAD_FAST                1 (b)
    322               8 LOAD_CONST               2 ('4')
    323              10 FORMAT_VALUE             4 (with format)
    324              12 LOAD_CONST               1 (' ')
    325              14 LOAD_FAST                2 (c)
    326              16 FORMAT_VALUE             2 (repr)
    327              18 LOAD_CONST               1 (' ')
    328              20 LOAD_FAST                3 (d)
    329              22 LOAD_CONST               2 ('4')
    330              24 FORMAT_VALUE             6 (repr, with format)
    331              26 BUILD_STRING             7
    332              28 RETURN_VALUE
    333 """ % (_fstring.__code__.co_firstlineno + 1,)
    334 
    335 def _g(x):
    336     yield x
    337 
    338 async def _ag(x):
    339     yield x
    340 
    341 async def _co(x):
    342     async for item in _ag(x):
    343         pass
    344 
    345 def _h(y):
    346     def foo(x):
    347         '''funcdoc'''
    348         return [x + z for z in y]
    349     return foo
    350 
    351 dis_nested_0 = """\
    352 %3d           0 LOAD_CLOSURE             0 (y)
    353               2 BUILD_TUPLE              1
    354               4 LOAD_CONST               1 (<code object foo at 0x..., file "%s", line %d>)
    355               6 LOAD_CONST               2 ('_h.<locals>.foo')
    356               8 MAKE_FUNCTION            8
    357              10 STORE_FAST               1 (foo)
    358 
    359 %3d          12 LOAD_FAST                1 (foo)
    360              14 RETURN_VALUE
    361 """ % (_h.__code__.co_firstlineno + 1,
    362        __file__,
    363        _h.__code__.co_firstlineno + 1,
    364        _h.__code__.co_firstlineno + 4,
    365 )
    366 
    367 dis_nested_1 = """%s
    368 Disassembly of <code object foo at 0x..., file "%s", line %d>:
    369 %3d           0 LOAD_CLOSURE             0 (x)
    370               2 BUILD_TUPLE              1
    371               4 LOAD_CONST               1 (<code object <listcomp> at 0x..., file "%s", line %d>)
    372               6 LOAD_CONST               2 ('_h.<locals>.foo.<locals>.<listcomp>')
    373               8 MAKE_FUNCTION            8
    374              10 LOAD_DEREF               1 (y)
    375              12 GET_ITER
    376              14 CALL_FUNCTION            1
    377              16 RETURN_VALUE
    378 """ % (dis_nested_0,
    379        __file__,
    380        _h.__code__.co_firstlineno + 1,
    381        _h.__code__.co_firstlineno + 3,
    382        __file__,
    383        _h.__code__.co_firstlineno + 3,
    384 )
    385 
    386 dis_nested_2 = """%s
    387 Disassembly of <code object <listcomp> at 0x..., file "%s", line %d>:
    388 %3d           0 BUILD_LIST               0
    389               2 LOAD_FAST                0 (.0)
    390         >>    4 FOR_ITER                12 (to 18)
    391               6 STORE_FAST               1 (z)
    392               8 LOAD_DEREF               0 (x)
    393              10 LOAD_FAST                1 (z)
    394              12 BINARY_ADD
    395              14 LIST_APPEND              2
    396              16 JUMP_ABSOLUTE            4
    397         >>   18 RETURN_VALUE
    398 """ % (dis_nested_1,
    399        __file__,
    400        _h.__code__.co_firstlineno + 3,
    401        _h.__code__.co_firstlineno + 3,
    402 )
    403 
    404 
    405 class DisTests(unittest.TestCase):
    406 
    407     maxDiff = None
    408 
    409     def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs):
    410         # We want to test the default printing behaviour, not the file arg
    411         output = io.StringIO()
    412         with contextlib.redirect_stdout(output):
    413             if wrapper:
    414                 dis.dis(func, **kwargs)
    415             else:
    416                 dis.disassemble(func, lasti, **kwargs)
    417         return output.getvalue()
    418 
    419     def get_disassemble_as_string(self, func, lasti=-1):
    420         return self.get_disassembly(func, lasti, False)
    421 
    422     def strip_addresses(self, text):
    423         return re.sub(r'\b0x[0-9A-Fa-f]+\b', '0x...', text)
    424 
    425     def do_disassembly_test(self, func, expected):
    426         got = self.get_disassembly(func, depth=0)
    427         if got != expected:
    428             got = self.strip_addresses(got)
    429         self.assertEqual(got, expected)
    430 
    431     def test_opmap(self):
    432         self.assertEqual(dis.opmap["NOP"], 9)
    433         self.assertIn(dis.opmap["LOAD_CONST"], dis.hasconst)
    434         self.assertIn(dis.opmap["STORE_NAME"], dis.hasname)
    435 
    436     def test_opname(self):
    437         self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
    438 
    439     def test_boundaries(self):
    440         self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
    441         self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
    442 
    443     def test_widths(self):
    444         for opcode, opname in enumerate(dis.opname):
    445             if opname in ('BUILD_MAP_UNPACK_WITH_CALL',
    446                           'BUILD_TUPLE_UNPACK_WITH_CALL'):
    447                 continue
    448             with self.subTest(opname=opname):
    449                 width = dis._OPNAME_WIDTH
    450                 if opcode < dis.HAVE_ARGUMENT:
    451                     width += 1 + dis._OPARG_WIDTH
    452                 self.assertLessEqual(len(opname), width)
    453 
    454     def test_dis(self):
    455         self.do_disassembly_test(_f, dis_f)
    456 
    457     def test_bug_708901(self):
    458         self.do_disassembly_test(bug708901, dis_bug708901)
    459 
    460     def test_bug_1333982(self):
    461         # This one is checking bytecodes generated for an `assert` statement,
    462         # so fails if the tests are run with -O.  Skip this test then.
    463         if not __debug__:
    464             self.skipTest('need asserts, run without -O')
    465 
    466         self.do_disassembly_test(bug1333982, dis_bug1333982)
    467 
    468     def test_big_linenos(self):
    469         def func(count):
    470             namespace = {}
    471             func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
    472             exec(func, namespace)
    473             return namespace['foo']
    474 
    475         # Test all small ranges
    476         for i in range(1, 300):
    477             expected = _BIG_LINENO_FORMAT % (i + 2)
    478             self.do_disassembly_test(func(i), expected)
    479 
    480         # Test some larger ranges too
    481         for i in range(300, 1000, 10):
    482             expected = _BIG_LINENO_FORMAT % (i + 2)
    483             self.do_disassembly_test(func(i), expected)
    484 
    485         for i in range(1000, 5000, 10):
    486             expected = _BIG_LINENO_FORMAT2 % (i + 2)
    487             self.do_disassembly_test(func(i), expected)
    488 
    489         from test import dis_module
    490         self.do_disassembly_test(dis_module, dis_module_expected_results)
    491 
    492     def test_big_offsets(self):
    493         def func(count):
    494             namespace = {}
    495             func = "def foo(x):\n " + ";".join(["x = x + 1"] * count) + "\n return x"
    496             exec(func, namespace)
    497             return namespace['foo']
    498 
    499         def expected(count, w):
    500             s = ['''\
    501            %*d LOAD_FAST                0 (x)
    502            %*d LOAD_CONST               1 (1)
    503            %*d BINARY_ADD
    504            %*d STORE_FAST               0 (x)
    505 ''' % (w, 8*i, w, 8*i + 2, w, 8*i + 4, w, 8*i + 6)
    506                  for i in range(count)]
    507             s += ['''\
    508 
    509   3        %*d LOAD_FAST                0 (x)
    510            %*d RETURN_VALUE
    511 ''' % (w, 8*count, w, 8*count + 2)]
    512             s[0] = '  2' + s[0][3:]
    513             return ''.join(s)
    514 
    515         for i in range(1, 5):
    516             self.do_disassembly_test(func(i), expected(i, 4))
    517         self.do_disassembly_test(func(1249), expected(1249, 4))
    518         self.do_disassembly_test(func(1250), expected(1250, 5))
    519 
    520     def test_disassemble_str(self):
    521         self.do_disassembly_test(expr_str, dis_expr_str)
    522         self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str)
    523         self.do_disassembly_test(annot_stmt_str, dis_annot_stmt_str)
    524         self.do_disassembly_test(compound_stmt_str, dis_compound_stmt_str)
    525 
    526     def test_disassemble_bytes(self):
    527         self.do_disassembly_test(_f.__code__.co_code, dis_f_co_code)
    528 
    529     def test_disassemble_class(self):
    530         self.do_disassembly_test(_C, dis_c)
    531 
    532     def test_disassemble_instance_method(self):
    533         self.do_disassembly_test(_C(1).__init__, dis_c_instance_method)
    534 
    535     def test_disassemble_instance_method_bytes(self):
    536         method_bytecode = _C(1).__init__.__code__.co_code
    537         self.do_disassembly_test(method_bytecode, dis_c_instance_method_bytes)
    538 
    539     def test_disassemble_static_method(self):
    540         self.do_disassembly_test(_C.sm, dis_c_static_method)
    541 
    542     def test_disassemble_class_method(self):
    543         self.do_disassembly_test(_C.cm, dis_c_class_method)
    544 
    545     def test_disassemble_generator(self):
    546         gen_func_disas = self.get_disassembly(_g)  # Generator function
    547         gen_disas = self.get_disassembly(_g(1))  # Generator iterator
    548         self.assertEqual(gen_disas, gen_func_disas)
    549 
    550     def test_disassemble_async_generator(self):
    551         agen_func_disas = self.get_disassembly(_ag)  # Async generator function
    552         agen_disas = self.get_disassembly(_ag(1))  # Async generator iterator
    553         self.assertEqual(agen_disas, agen_func_disas)
    554 
    555     def test_disassemble_coroutine(self):
    556         coro_func_disas = self.get_disassembly(_co)  # Coroutine function
    557         coro = _co(1)  # Coroutine object
    558         coro.close()  # Avoid a RuntimeWarning (never awaited)
    559         coro_disas = self.get_disassembly(coro)
    560         self.assertEqual(coro_disas, coro_func_disas)
    561 
    562     def test_disassemble_fstring(self):
    563         self.do_disassembly_test(_fstring, dis_fstring)
    564 
    565     def test_dis_none(self):
    566         try:
    567             del sys.last_traceback
    568         except AttributeError:
    569             pass
    570         self.assertRaises(RuntimeError, dis.dis, None)
    571 
    572     def test_dis_traceback(self):
    573         try:
    574             del sys.last_traceback
    575         except AttributeError:
    576             pass
    577 
    578         try:
    579             1/0
    580         except Exception as e:
    581             tb = e.__traceback__
    582             sys.last_traceback = tb
    583 
    584         tb_dis = self.get_disassemble_as_string(tb.tb_frame.f_code, tb.tb_lasti)
    585         self.do_disassembly_test(None, tb_dis)
    586 
    587     def test_dis_object(self):
    588         self.assertRaises(TypeError, dis.dis, object())
    589 
    590     def test_disassemble_recursive(self):
    591         def check(expected, **kwargs):
    592             dis = self.get_disassembly(_h, **kwargs)
    593             dis = self.strip_addresses(dis)
    594             self.assertEqual(dis, expected)
    595 
    596         check(dis_nested_0, depth=0)
    597         check(dis_nested_1, depth=1)
    598         check(dis_nested_2, depth=2)
    599         check(dis_nested_2, depth=3)
    600         check(dis_nested_2, depth=None)
    601         check(dis_nested_2)
    602 
    603 
    604 class DisWithFileTests(DisTests):
    605 
    606     # Run the tests again, using the file arg instead of print
    607     def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs):
    608         output = io.StringIO()
    609         if wrapper:
    610             dis.dis(func, file=output, **kwargs)
    611         else:
    612             dis.disassemble(func, lasti, file=output, **kwargs)
    613         return output.getvalue()
    614 
    615 
    616 
    617 code_info_code_info = """\
    618 Name:              code_info
    619 Filename:          (.*)
    620 Argument count:    1
    621 Kw-only arguments: 0
    622 Number of locals:  1
    623 Stack size:        3
    624 Flags:             OPTIMIZED, NEWLOCALS, NOFREE
    625 Constants:
    626    0: %r
    627 Names:
    628    0: _format_code_info
    629    1: _get_code_object
    630 Variable names:
    631    0: x""" % (('Formatted details of methods, functions, or code.',)
    632               if sys.flags.optimize < 2 else (None,))
    633 
    634 @staticmethod
    635 def tricky(x, y, z=True, *args, c, d, e=[], **kwds):
    636     def f(c=c):
    637         print(x, y, z, c, d, e, f)
    638     yield x, y, z, c, d, e, f
    639 
    640 code_info_tricky = """\
    641 Name:              tricky
    642 Filename:          (.*)
    643 Argument count:    3
    644 Kw-only arguments: 3
    645 Number of locals:  8
    646 Stack size:        7
    647 Flags:             OPTIMIZED, NEWLOCALS, VARARGS, VARKEYWORDS, GENERATOR
    648 Constants:
    649    0: None
    650    1: <code object f at (.*), file "(.*)", line (.*)>
    651    2: 'tricky.<locals>.f'
    652 Variable names:
    653    0: x
    654    1: y
    655    2: z
    656    3: c
    657    4: d
    658    5: e
    659    6: args
    660    7: kwds
    661 Cell variables:
    662    0: [edfxyz]
    663    1: [edfxyz]
    664    2: [edfxyz]
    665    3: [edfxyz]
    666    4: [edfxyz]
    667    5: [edfxyz]"""
    668 # NOTE: the order of the cell variables above depends on dictionary order!
    669 
    670 co_tricky_nested_f = tricky.__func__.__code__.co_consts[1]
    671 
    672 code_info_tricky_nested_f = """\
    673 Name:              f
    674 Filename:          (.*)
    675 Argument count:    1
    676 Kw-only arguments: 0
    677 Number of locals:  1
    678 Stack size:        8
    679 Flags:             OPTIMIZED, NEWLOCALS, NESTED
    680 Constants:
    681    0: None
    682 Names:
    683    0: print
    684 Variable names:
    685    0: c
    686 Free variables:
    687    0: [edfxyz]
    688    1: [edfxyz]
    689    2: [edfxyz]
    690    3: [edfxyz]
    691    4: [edfxyz]
    692    5: [edfxyz]"""
    693 
    694 code_info_expr_str = """\
    695 Name:              <module>
    696 Filename:          <disassembly>
    697 Argument count:    0
    698 Kw-only arguments: 0
    699 Number of locals:  0
    700 Stack size:        2
    701 Flags:             NOFREE
    702 Constants:
    703    0: 1
    704 Names:
    705    0: x"""
    706 
    707 code_info_simple_stmt_str = """\
    708 Name:              <module>
    709 Filename:          <disassembly>
    710 Argument count:    0
    711 Kw-only arguments: 0
    712 Number of locals:  0
    713 Stack size:        2
    714 Flags:             NOFREE
    715 Constants:
    716    0: 1
    717    1: None
    718 Names:
    719    0: x"""
    720 
    721 code_info_compound_stmt_str = """\
    722 Name:              <module>
    723 Filename:          <disassembly>
    724 Argument count:    0
    725 Kw-only arguments: 0
    726 Number of locals:  0
    727 Stack size:        2
    728 Flags:             NOFREE
    729 Constants:
    730    0: 0
    731    1: 1
    732    2: None
    733 Names:
    734    0: x"""
    735 
    736 
    737 async def async_def():
    738     await 1
    739     async for a in b: pass
    740     async with c as d: pass
    741 
    742 code_info_async_def = """\
    743 Name:              async_def
    744 Filename:          (.*)
    745 Argument count:    0
    746 Kw-only arguments: 0
    747 Number of locals:  2
    748 Stack size:        10
    749 Flags:             OPTIMIZED, NEWLOCALS, NOFREE, COROUTINE
    750 Constants:
    751    0: None
    752    1: 1"""
    753 
    754 class CodeInfoTests(unittest.TestCase):
    755     test_pairs = [
    756       (dis.code_info, code_info_code_info),
    757       (tricky, code_info_tricky),
    758       (co_tricky_nested_f, code_info_tricky_nested_f),
    759       (expr_str, code_info_expr_str),
    760       (simple_stmt_str, code_info_simple_stmt_str),
    761       (compound_stmt_str, code_info_compound_stmt_str),
    762       (async_def, code_info_async_def)
    763     ]
    764 
    765     def test_code_info(self):
    766         self.maxDiff = 1000
    767         for x, expected in self.test_pairs:
    768             self.assertRegex(dis.code_info(x), expected)
    769 
    770     def test_show_code(self):
    771         self.maxDiff = 1000
    772         for x, expected in self.test_pairs:
    773             with captured_stdout() as output:
    774                 dis.show_code(x)
    775             self.assertRegex(output.getvalue(), expected+"\n")
    776             output = io.StringIO()
    777             dis.show_code(x, file=output)
    778             self.assertRegex(output.getvalue(), expected)
    779 
    780     def test_code_info_object(self):
    781         self.assertRaises(TypeError, dis.code_info, object())
    782 
    783     def test_pretty_flags_no_flags(self):
    784         self.assertEqual(dis.pretty_flags(0), '0x0')
    785 
    786 
    787 # Fodder for instruction introspection tests
    788 #   Editing any of these may require recalculating the expected output
    789 def outer(a=1, b=2):
    790     def f(c=3, d=4):
    791         def inner(e=5, f=6):
    792             print(a, b, c, d, e, f)
    793         print(a, b, c, d)
    794         return inner
    795     print(a, b, '', 1, [], {}, "Hello world!")
    796     return f
    797 
    798 def jumpy():
    799     # This won't actually run (but that's OK, we only disassemble it)
    800     for i in range(10):
    801         print(i)
    802         if i < 4:
    803             continue
    804         if i > 6:
    805             break
    806     else:
    807         print("I can haz else clause?")
    808     while i:
    809         print(i)
    810         i -= 1
    811         if i > 6:
    812             continue
    813         if i < 4:
    814             break
    815     else:
    816         print("Who let lolcatz into this test suite?")
    817     try:
    818         1 / 0
    819     except ZeroDivisionError:
    820         print("Here we go, here we go, here we go...")
    821     else:
    822         with i as dodgy:
    823             print("Never reach this")
    824     finally:
    825         print("OK, now we're done")
    826 
    827 # End fodder for opinfo generation tests
    828 expected_outer_line = 1
    829 _line_offset = outer.__code__.co_firstlineno - 1
    830 code_object_f = outer.__code__.co_consts[3]
    831 expected_f_line = code_object_f.co_firstlineno - _line_offset
    832 code_object_inner = code_object_f.co_consts[3]
    833 expected_inner_line = code_object_inner.co_firstlineno - _line_offset
    834 expected_jumpy_line = 1
    835 
    836 # The following lines are useful to regenerate the expected results after
    837 # either the fodder is modified or the bytecode generation changes
    838 # After regeneration, update the references to code_object_f and
    839 # code_object_inner before rerunning the tests
    840 
    841 #_instructions = dis.get_instructions(outer, first_line=expected_outer_line)
    842 #print('expected_opinfo_outer = [\n  ',
    843       #',\n  '.join(map(str, _instructions)), ',\n]', sep='')
    844 #_instructions = dis.get_instructions(outer(), first_line=expected_f_line)
    845 #print('expected_opinfo_f = [\n  ',
    846       #',\n  '.join(map(str, _instructions)), ',\n]', sep='')
    847 #_instructions = dis.get_instructions(outer()(), first_line=expected_inner_line)
    848 #print('expected_opinfo_inner = [\n  ',
    849       #',\n  '.join(map(str, _instructions)), ',\n]', sep='')
    850 #_instructions = dis.get_instructions(jumpy, first_line=expected_jumpy_line)
    851 #print('expected_opinfo_jumpy = [\n  ',
    852       #',\n  '.join(map(str, _instructions)), ',\n]', sep='')
    853 
    854 
    855 Instruction = dis.Instruction
    856 expected_opinfo_outer = [
    857   Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False),
    858   Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
    859   Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
    860   Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False),
    861   Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False),
    862   Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False),
    863   Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=12, starts_line=None, is_jump_target=False),
    864   Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=14, starts_line=None, is_jump_target=False),
    865   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=16, starts_line=7, is_jump_target=False),
    866   Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False),
    867   Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False),
    868   Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False),
    869   Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False),
    870   Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False),
    871   Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False),
    872   Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False),
    873   Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='', offset=32, starts_line=None, is_jump_target=False),
    874   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False),
    875   Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=36, starts_line=8, is_jump_target=False),
    876   Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False),
    877 ]
    878 
    879 expected_opinfo_f = [
    880   Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False),
    881   Instruction(opname='LOAD_CLOSURE', opcode=135, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
    882   Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
    883   Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
    884   Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
    885   Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False),
    886   Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False),
    887   Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False),
    888   Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=16, starts_line=None, is_jump_target=False),
    889   Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=18, starts_line=None, is_jump_target=False),
    890   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=5, is_jump_target=False),
    891   Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='a', argrepr='a', offset=22, starts_line=None, is_jump_target=False),
    892   Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
    893   Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='c', argrepr='c', offset=26, starts_line=None, is_jump_target=False),
    894   Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='d', argrepr='d', offset=28, starts_line=None, is_jump_target=False),
    895   Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='', offset=30, starts_line=None, is_jump_target=False),
    896   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False),
    897   Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=34, starts_line=6, is_jump_target=False),
    898   Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False),
    899 ]
    900 
    901 expected_opinfo_inner = [
    902   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=0, starts_line=4, is_jump_target=False),
    903   Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
    904   Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
    905   Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
    906   Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
    907   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=10, starts_line=None, is_jump_target=False),
    908   Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=12, starts_line=None, is_jump_target=False),
    909   Instruction(opname='CALL_FUNCTION', opcode=131, arg=6, argval=6, argrepr='', offset=14, starts_line=None, is_jump_target=False),
    910   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=16, starts_line=None, is_jump_target=False),
    911   Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=18, starts_line=None, is_jump_target=False),
    912   Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False),
    913 ]
    914 
    915 expected_opinfo_jumpy = [
    916   Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=54, argrepr='to 54', offset=0, starts_line=3, is_jump_target=False),
    917   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=2, starts_line=None, is_jump_target=False),
    918   Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=4, starts_line=None, is_jump_target=False),
    919   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=6, starts_line=None, is_jump_target=False),
    920   Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=8, starts_line=None, is_jump_target=False),
    921   Instruction(opname='FOR_ITER', opcode=93, arg=32, argval=44, argrepr='to 44', offset=10, starts_line=None, is_jump_target=True),
    922   Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=12, starts_line=None, is_jump_target=False),
    923   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=14, starts_line=4, is_jump_target=False),
    924   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=16, starts_line=None, is_jump_target=False),
    925   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=18, starts_line=None, is_jump_target=False),
    926   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False),
    927   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=22, starts_line=5, is_jump_target=False),
    928   Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=24, starts_line=None, is_jump_target=False),
    929   Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=26, starts_line=None, is_jump_target=False),
    930   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=32, argval=32, argrepr='', offset=28, starts_line=None, is_jump_target=False),
    931   Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=10, argval=10, argrepr='', offset=30, starts_line=6, is_jump_target=False),
    932   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=32, starts_line=7, is_jump_target=True),
    933   Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=34, starts_line=None, is_jump_target=False),
    934   Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=36, starts_line=None, is_jump_target=False),
    935   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=10, argval=10, argrepr='', offset=38, starts_line=None, is_jump_target=False),
    936   Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=40, starts_line=8, is_jump_target=False),
    937   Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=10, argval=10, argrepr='', offset=42, starts_line=None, is_jump_target=False),
    938   Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=44, starts_line=None, is_jump_target=True),
    939   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=46, starts_line=10, is_jump_target=False),
    940   Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=48, starts_line=None, is_jump_target=False),
    941   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=50, starts_line=None, is_jump_target=False),
    942   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False),
    943   Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=108, argrepr='to 108', offset=54, starts_line=11, is_jump_target=True),
    944   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=56, starts_line=None, is_jump_target=True),
    945   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=98, argval=98, argrepr='', offset=58, starts_line=None, is_jump_target=False),
    946   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=60, starts_line=12, is_jump_target=False),
    947   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=62, starts_line=None, is_jump_target=False),
    948   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=64, starts_line=None, is_jump_target=False),
    949   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False),
    950   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=68, starts_line=13, is_jump_target=False),
    951   Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=70, starts_line=None, is_jump_target=False),
    952   Instruction(opname='INPLACE_SUBTRACT', opcode=56, arg=None, argval=None, argrepr='', offset=72, starts_line=None, is_jump_target=False),
    953   Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=74, starts_line=None, is_jump_target=False),
    954   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=76, starts_line=14, is_jump_target=False),
    955   Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=78, starts_line=None, is_jump_target=False),
    956   Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=80, starts_line=None, is_jump_target=False),
    957   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=86, argval=86, argrepr='', offset=82, starts_line=None, is_jump_target=False),
    958   Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=56, argval=56, argrepr='', offset=84, starts_line=15, is_jump_target=False),
    959   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=86, starts_line=16, is_jump_target=True),
    960   Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=88, starts_line=None, is_jump_target=False),
    961   Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=90, starts_line=None, is_jump_target=False),
    962   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=56, argval=56, argrepr='', offset=92, starts_line=None, is_jump_target=False),
    963   Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=94, starts_line=17, is_jump_target=False),
    964   Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=56, argval=56, argrepr='', offset=96, starts_line=None, is_jump_target=False),
    965   Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=98, starts_line=None, is_jump_target=True),
    966   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=100, starts_line=19, is_jump_target=False),
    967   Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=102, starts_line=None, is_jump_target=False),
    968   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=104, starts_line=None, is_jump_target=False),
    969   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=106, starts_line=None, is_jump_target=False),
    970   Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=180, argrepr='to 180', offset=108, starts_line=20, is_jump_target=True),
    971   Instruction(opname='SETUP_EXCEPT', opcode=121, arg=12, argval=124, argrepr='to 124', offset=110, starts_line=None, is_jump_target=False),
    972   Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=112, starts_line=21, is_jump_target=False),
    973   Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=114, starts_line=None, is_jump_target=False),
    974   Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False),
    975   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=118, starts_line=None, is_jump_target=False),
    976   Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=120, starts_line=None, is_jump_target=False),
    977   Instruction(opname='JUMP_FORWARD', opcode=110, arg=28, argval=152, argrepr='to 152', offset=122, starts_line=None, is_jump_target=False),
    978   Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=124, starts_line=22, is_jump_target=True),
    979   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=126, starts_line=None, is_jump_target=False),
    980   Instruction(opname='COMPARE_OP', opcode=107, arg=10, argval='exception match', argrepr='exception match', offset=128, starts_line=None, is_jump_target=False),
    981   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=150, argval=150, argrepr='', offset=130, starts_line=None, is_jump_target=False),
    982   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=132, starts_line=None, is_jump_target=False),
    983   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=134, starts_line=None, is_jump_target=False),
    984   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=136, starts_line=None, is_jump_target=False),
    985   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=138, starts_line=23, is_jump_target=False),
    986   Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=140, starts_line=None, is_jump_target=False),
    987   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=142, starts_line=None, is_jump_target=False),
    988   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=False),
    989   Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=146, starts_line=None, is_jump_target=False),
    990   Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=176, argrepr='to 176', offset=148, starts_line=None, is_jump_target=False),
    991   Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=150, starts_line=None, is_jump_target=True),
    992   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, starts_line=25, is_jump_target=True),
    993   Instruction(opname='SETUP_WITH', opcode=143, arg=14, argval=170, argrepr='to 170', offset=154, starts_line=None, is_jump_target=False),
    994   Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=156, starts_line=None, is_jump_target=False),
    995   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=158, starts_line=26, is_jump_target=False),
    996   Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=160, starts_line=None, is_jump_target=False),
    997   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=162, starts_line=None, is_jump_target=False),
    998   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False),
    999   Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False),
   1000   Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=168, starts_line=None, is_jump_target=False),
   1001   Instruction(opname='WITH_CLEANUP_START', opcode=81, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=True),
   1002   Instruction(opname='WITH_CLEANUP_FINISH', opcode=82, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False),
   1003   Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=174, starts_line=None, is_jump_target=False),
   1004   Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=176, starts_line=None, is_jump_target=True),
   1005   Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=178, starts_line=None, is_jump_target=False),
   1006   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=180, starts_line=28, is_jump_target=True),
   1007   Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=182, starts_line=None, is_jump_target=False),
   1008   Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=184, starts_line=None, is_jump_target=False),
   1009   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False),
   1010   Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False),
   1011   Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=190, starts_line=None, is_jump_target=False),
   1012   Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False),
   1013 ]
   1014 
   1015 # One last piece of inspect fodder to check the default line number handling
   1016 def simple(): pass
   1017 expected_opinfo_simple = [
   1018   Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=0, starts_line=simple.__code__.co_firstlineno, is_jump_target=False),
   1019   Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=2, starts_line=None, is_jump_target=False)
   1020 ]
   1021 
   1022 
   1023 class InstructionTests(BytecodeTestCase):
   1024 
   1025     def test_default_first_line(self):
   1026         actual = dis.get_instructions(simple)
   1027         self.assertEqual(list(actual), expected_opinfo_simple)
   1028 
   1029     def test_first_line_set_to_None(self):
   1030         actual = dis.get_instructions(simple, first_line=None)
   1031         self.assertEqual(list(actual), expected_opinfo_simple)
   1032 
   1033     def test_outer(self):
   1034         actual = dis.get_instructions(outer, first_line=expected_outer_line)
   1035         self.assertEqual(list(actual), expected_opinfo_outer)
   1036 
   1037     def test_nested(self):
   1038         with captured_stdout():
   1039             f = outer()
   1040         actual = dis.get_instructions(f, first_line=expected_f_line)
   1041         self.assertEqual(list(actual), expected_opinfo_f)
   1042 
   1043     def test_doubly_nested(self):
   1044         with captured_stdout():
   1045             inner = outer()()
   1046         actual = dis.get_instructions(inner, first_line=expected_inner_line)
   1047         self.assertEqual(list(actual), expected_opinfo_inner)
   1048 
   1049     def test_jumpy(self):
   1050         actual = dis.get_instructions(jumpy, first_line=expected_jumpy_line)
   1051         self.assertEqual(list(actual), expected_opinfo_jumpy)
   1052 
   1053 # get_instructions has its own tests above, so can rely on it to validate
   1054 # the object oriented API
   1055 class BytecodeTests(unittest.TestCase):
   1056     def test_instantiation(self):
   1057         # Test with function, method, code string and code object
   1058         for obj in [_f, _C(1).__init__, "a=1", _f.__code__]:
   1059             with self.subTest(obj=obj):
   1060                 b = dis.Bytecode(obj)
   1061                 self.assertIsInstance(b.codeobj, types.CodeType)
   1062 
   1063         self.assertRaises(TypeError, dis.Bytecode, object())
   1064 
   1065     def test_iteration(self):
   1066         for obj in [_f, _C(1).__init__, "a=1", _f.__code__]:
   1067             with self.subTest(obj=obj):
   1068                 via_object = list(dis.Bytecode(obj))
   1069                 via_generator = list(dis.get_instructions(obj))
   1070                 self.assertEqual(via_object, via_generator)
   1071 
   1072     def test_explicit_first_line(self):
   1073         actual = dis.Bytecode(outer, first_line=expected_outer_line)
   1074         self.assertEqual(list(actual), expected_opinfo_outer)
   1075 
   1076     def test_source_line_in_disassembly(self):
   1077         # Use the line in the source code
   1078         actual = dis.Bytecode(simple).dis()
   1079         actual = actual.strip().partition(" ")[0]  # extract the line no
   1080         expected = str(simple.__code__.co_firstlineno)
   1081         self.assertEqual(actual, expected)
   1082         # Use an explicit first line number
   1083         actual = dis.Bytecode(simple, first_line=350).dis()
   1084         actual = actual.strip().partition(" ")[0]  # extract the line no
   1085         self.assertEqual(actual, "350")
   1086 
   1087     def test_info(self):
   1088         self.maxDiff = 1000
   1089         for x, expected in CodeInfoTests.test_pairs:
   1090             b = dis.Bytecode(x)
   1091             self.assertRegex(b.info(), expected)
   1092 
   1093     def test_disassembled(self):
   1094         actual = dis.Bytecode(_f).dis()
   1095         self.assertEqual(actual, dis_f)
   1096 
   1097     def test_from_traceback(self):
   1098         tb = get_tb()
   1099         b = dis.Bytecode.from_traceback(tb)
   1100         while tb.tb_next: tb = tb.tb_next
   1101 
   1102         self.assertEqual(b.current_offset, tb.tb_lasti)
   1103 
   1104     def test_from_traceback_dis(self):
   1105         tb = get_tb()
   1106         b = dis.Bytecode.from_traceback(tb)
   1107         self.assertEqual(b.dis(), dis_traceback)
   1108 
   1109 if __name__ == "__main__":
   1110     unittest.main()
   1111