Index: py3k/Doc/library/dis.rst =================================================================== --- py3k/Doc/library/dis.rst (revision 79952) +++ py3k/Doc/library/dis.rst (working copy) @@ -34,8 +34,9 @@ Disassemble the *x* object. *x* can denote either a module, a class, a method, a function, or a code object. For a module, it disassembles all functions. For a class, it disassembles all methods. For a single code - sequence, it prints one line per bytecode instruction. If no object is - provided, it disassembles the last traceback. + sequence, it prints one line per bytecode instruction. Strings are first + compiled to code objects with the :func:`compile` built-in function. If no + object is provided, it disassembles the last traceback. .. function:: distb(tb=None) Index: py3k/Lib/test/test_dis.py =================================================================== --- py3k/Lib/test/test_dis.py (revision 79952) +++ py3k/Lib/test/test_dis.py (working copy) @@ -96,7 +96,27 @@ """ +expr_str = "x + 1" +dis_expr_str = """\ + 1 0 LOAD_NAME 0 (x) + 3 LOAD_CONST 0 (1) + 6 BINARY_ADD + 7 RETURN_VALUE +""" + +stmt_str = "x = x + 1" + +dis_stmt_str = """\ + 1 0 LOAD_NAME 0 (x) + 3 LOAD_CONST 0 (1) + 6 BINARY_ADD + 7 STORE_NAME 0 (x) + 10 LOAD_CONST 1 (None) + 13 RETURN_VALUE +""" + + class DisTests(unittest.TestCase): def do_disassembly_test(self, func, expected): s = io.StringIO() @@ -165,6 +185,10 @@ def test_big_linenos(self): from test import dis_module self.do_disassembly_test(dis_module, dis_module_expected_results) + + def test_disassemble_str(self): + self.do_disassembly_test(expr_str, dis_expr_str) + self.do_disassembly_test(stmt_str, dis_stmt_str) def test_main(): run_unittest(DisTests) Index: py3k/Lib/dis.py =================================================================== --- py3k/Lib/dis.py (revision 79952) +++ py3k/Lib/dis.py (working copy) @@ -39,6 +39,8 @@ disassemble(x) elif isinstance(x, (bytes, bytearray)): disassemble_string(x) + elif isinstance(x, str): + disassemble_str(x) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__) @@ -196,6 +198,14 @@ print('(' + cmp_op[oparg] + ')', end=' ') print() +def disassemble_str(source): + """Compile the source string, then disassemble the code object.""" + try: + c = compile(source, '', 'eval') + except SyntaxError: + c = compile(source, '', 'exec') + disassemble(c) + disco = disassemble # XXX For backwards compatibility def findlabels(code):