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