summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2014-07-25 13:02:56 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2014-07-25 13:02:56 (GMT)
commitefd5df9e5267fd337cde95b0dec319ea59187bf4 (patch)
treeaa20c9a774303b891ac047721b8e036e94988578
parentd0d64cfb59dda1b82e4ec05160f20316be75760d (diff)
downloadcpython-efd5df9e5267fd337cde95b0dec319ea59187bf4.zip
cpython-efd5df9e5267fd337cde95b0dec319ea59187bf4.tar.gz
cpython-efd5df9e5267fd337cde95b0dec319ea59187bf4.tar.bz2
Issue #21947: handle generator-iterator objects in dis
Patch by Clement Rouault.
-rw-r--r--Doc/library/dis.rst16
-rw-r--r--Lib/dis.py8
-rw-r--r--Lib/test/test_dis.py8
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
5 files changed, 26 insertions, 10 deletions
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index fbabe35..8653da7 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -48,8 +48,8 @@ compiled code.
.. 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 @@ object isn't useful:
.. 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 @@ object isn't useful:
.. 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 --git a/Lib/dis.py b/Lib/dis.py
index 81cbe7f..d215bc5 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -29,7 +29,7 @@ def _try_compile(source, name):
return c
def dis(x=None, *, file=None):
- """Disassemble classes, methods, functions, or code.
+ """Disassemble classes, methods, functions, generators, or code.
With no argument, disassemble the last traceback.
@@ -41,6 +41,8 @@ def dis(x=None, *, file=None):
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:
@@ -99,11 +101,13 @@ def pretty_flags(flags):
return ", ".join(names)
def _get_code_object(x):
- """Helper to handle methods, functions, strings and raw code objects"""
+ """Helper to handle methods, functions, generators, strings and raw code objects"""
if hasattr(x, '__func__'): # Method
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, "<disassembly>")
if hasattr(x, 'co_code'): # Code object
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index d1229fb..f04f12c 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -229,6 +229,9 @@ dis_traceback = """\
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 @@ class DisTests(unittest.TestCase):
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
diff --git a/Misc/ACKS b/Misc/ACKS
index d9fed8a..4a68015 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1145,6 +1145,7 @@ Guido van Rossum
Just van Rossum
Hugo van Rossum
Saskia van Rossum
+Clement Rouault
Donald Wallace Rouse II
Liam Routt
Todd Rovito
diff --git a/Misc/NEWS b/Misc/NEWS
index 515978a..3f49d9c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -108,6 +108,9 @@ Core and Builtins
Library
-------
+- Issue #21947: The dis module can now disassemble generator-iterator
+ objects based on their gi_code attribute. Patch by Clement Rouault.
+
- Issue #16133: The asynchat.async_chat.handle_read() method now ignores
BlockingIOError exceptions.