diff -r 06589e81fd56 Doc/library/dis.rst --- a/Doc/library/dis.rst Tue Jul 08 09:41:57 2014 -0500 +++ b/Doc/library/dis.rst Wed Jul 09 23:26:48 2014 +0200 @@ -48,8 +48,8 @@ .. class:: Bytecode(x, *, first_line=None, current_offset=None) - Analyse the bytecode corresponding to a function, method, string of - source code, or a code object (as returned by :func:`compile`). + Analyse the bytecode corresponding to a function, generator, method, + string of source code, or a code object (as returned by :func:`compile`). This is a convenience wrapper around many of the functions listed below, most notably :func:`get_instructions`, as iterating over a @@ -112,7 +112,7 @@ .. function:: code_info(x) Return a formatted multi-line string with detailed code object information - for the supplied function, method, source code string or code object. + for the supplied function, generator, method, source code string or code object. Note that the exact contents of code info strings are highly implementation dependent and they may change arbitrarily across Python VMs or Python @@ -139,11 +139,11 @@ .. function:: dis(x=None, *, file=None) Disassemble the *x* object. *x* can denote either a module, a class, a - method, a function, a code object, a string of source code or a byte sequence - of raw bytecode. For a module, it disassembles all functions. For a class, - it disassembles all methods. For a code object or sequence of raw bytecode, - it prints one line per bytecode instruction. Strings are first compiled to - code objects with the :func:`compile` built-in function before being + method, a function, a generator, a code object, a string of source code or + a byte sequence of raw bytecode. For a module, it disassembles all functions. + For a class, it disassembles all methods. For a code object or sequence of + raw bytecode, it prints one line per bytecode instruction. Strings are first + compiled to code objects with the :func:`compile` built-in function before being disassembled. If no object is provided, this function disassembles the last traceback. diff -r 06589e81fd56 Lib/dis.py --- a/Lib/dis.py Tue Jul 08 09:41:57 2014 -0500 +++ b/Lib/dis.py Wed Jul 09 23:26:48 2014 +0200 @@ -41,6 +41,8 @@ x = x.__func__ if hasattr(x, '__code__'): # Function x = x.__code__ + if hasattr(x, 'gi_code'): # Generator + x = x.gi_code if hasattr(x, '__dict__'): # Class or module items = sorted(x.__dict__.items()) for name, x1 in items: @@ -104,6 +106,8 @@ x = x.__func__ if hasattr(x, '__code__'): # Function x = x.__code__ + if hasattr(x, 'gi_code'): # Generator + x = x.gi_code if isinstance(x, str): # Source code x = _try_compile(x, "") if hasattr(x, 'co_code'): # Code object diff -r 06589e81fd56 Lib/test/test_dis.py --- a/Lib/test/test_dis.py Tue Jul 08 09:41:57 2014 -0500 +++ b/Lib/test/test_dis.py Wed Jul 09 23:26:48 2014 +0200 @@ -229,6 +229,9 @@ TRACEBACK_CODE.co_firstlineno + 4, TRACEBACK_CODE.co_firstlineno + 5) +def _g(x): + yield x + class DisTests(unittest.TestCase): def get_disassembly(self, func, lasti=-1, wrapper=True): @@ -314,6 +317,11 @@ method_bytecode = _C(1).__init__.__code__.co_code self.do_disassembly_test(method_bytecode, dis_c_instance_method_bytes) + def test_disassemble_generator(self): + gen_func_disas = self.get_disassembly(_g) # Disassemble generator function + gen_disas = self.get_disassembly(_g(1)) # Disassemble generator itself + self.assertEqual(gen_disas, gen_func_disas) + def test_dis_none(self): try: del sys.last_traceback