[Python-checkins] r82471 - in python/branches/py3k: Doc/library/dis.rst Lib/dis.py Lib/test/test_dis.py Misc/ACKS Misc/NEWS

nick.coghlan python-checkins at python.org
Sat Jul 3 09:36:51 CEST 2010


Author: nick.coghlan
Date: Sat Jul  3 09:36:51 2010
New Revision: 82471

Log:
Issue 6507: accept source strings directly in dis.dis(). Original patch by Daniel Urban

Modified:
   python/branches/py3k/Doc/library/dis.rst
   python/branches/py3k/Lib/dis.py
   python/branches/py3k/Lib/test/test_dis.py
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/dis.rst
==============================================================================
--- python/branches/py3k/Doc/library/dis.rst	(original)
+++ python/branches/py3k/Doc/library/dis.rst	Sat Jul  3 09:36:51 2010
@@ -33,10 +33,13 @@
 .. function:: dis(x=None)
 
    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.
+   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 disassembled.  If no object is provided,
+   this function disassembles the last traceback.
 
 
 .. function:: distb(tb=None)

Modified: python/branches/py3k/Lib/dis.py
==============================================================================
--- python/branches/py3k/Lib/dis.py	(original)
+++ python/branches/py3k/Lib/dis.py	Sat Jul  3 09:36:51 2010
@@ -12,6 +12,22 @@
 
 _have_code = (types.MethodType, types.FunctionType, types.CodeType, type)
 
+def _try_compile(source, name):
+    """Attempts to compile the given source, first as an expression and
+       then as a statement if the first approach fails.
+
+       Utility function to accept strings in functions that otherwise
+       expect code objects
+    """
+    # ncoghlan: currently only used by dis(), but plan to add an
+    # equivalent for show_code() as well (but one that returns a
+    # string rather than printing directly to the console)
+    try:
+        c = compile(source, name, 'eval')
+    except SyntaxError:
+        c = compile(source, name, 'exec')
+    return c
+
 def dis(x=None):
     """Disassemble classes, methods, functions, or code.
 
@@ -38,7 +54,9 @@
     elif hasattr(x, 'co_code'):
         disassemble(x)
     elif isinstance(x, (bytes, bytearray)):
-        disassemble_string(x)
+        _disassemble_bytes(x)
+    elif isinstance(x, str):
+        _disassemble_str(x)
     else:
         raise TypeError("don't know how to disassemble %s objects" %
                         type(x).__name__)
@@ -157,7 +175,7 @@
                 print('(' + free[oparg] + ')', end=' ')
         print()
 
-def disassemble_string(code, lasti=-1, varnames=None, names=None,
+def _disassemble_bytes(code, lasti=-1, varnames=None, names=None,
                        constants=None):
     labels = findlabels(code)
     n = len(code)
@@ -196,6 +214,10 @@
                 print('(' + cmp_op[oparg] + ')', end=' ')
         print()
 
+def _disassemble_str(source):
+    """Compile the source string, then disassemble the code object."""
+    disassemble(_try_compile(source, '<dis>'))
+
 disco = disassemble                     # XXX For backwards compatibility
 
 def findlabels(code):

Modified: python/branches/py3k/Lib/test/test_dis.py
==============================================================================
--- python/branches/py3k/Lib/test/test_dis.py	(original)
+++ python/branches/py3k/Lib/test/test_dis.py	Sat Jul  3 09:36:51 2010
@@ -96,6 +96,46 @@
 
 """
 
+expr_str = "x + 1"
+
+dis_expr_str = """\
+  1           0 LOAD_NAME                0 (x)
+              3 LOAD_CONST               0 (1)
+              6 BINARY_ADD
+              7 RETURN_VALUE
+"""
+
+simple_stmt_str = "x = x + 1"
+
+dis_simple_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
+"""
+
+compound_stmt_str = """\
+x = 0
+while 1:
+    x += 1"""
+# Trailing newline has been deliberately omitted
+
+dis_compound_stmt_str = """\
+  1           0 LOAD_CONST               0 (0)
+              3 STORE_NAME               0 (x)
+
+  2           6 SETUP_LOOP              13 (to 22)
+
+  3     >>    9 LOAD_NAME                0 (x)
+             12 LOAD_CONST               1 (1)
+             15 INPLACE_ADD
+             16 STORE_NAME               0 (x)
+             19 JUMP_ABSOLUTE            9
+        >>   22 LOAD_CONST               2 (None)
+             25 RETURN_VALUE
+"""
 
 class DisTests(unittest.TestCase):
     def do_disassembly_test(self, func, expected):
@@ -166,6 +206,11 @@
         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(simple_stmt_str, dis_simple_stmt_str)
+        self.do_disassembly_test(compound_stmt_str, dis_compound_stmt_str)
+
 def test_main():
     run_unittest(DisTests)
 

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Sat Jul  3 09:36:51 2010
@@ -797,6 +797,7 @@
 Eren Türkay
 Lionel Ulmer
 Roger Upole
+Daniel Urban
 Michael Urman
 Hector Urtubia
 Andi Vajda

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Jul  3 09:36:51 2010
@@ -468,6 +468,8 @@
 Library
 -------
 
+- Issue #6507: Accept source strings in dis.dis()
+
 - Issue #7829: Clearly document that the dis module is exposing an
   implementation detail that is not stable between Python VMs or releases.
 


More information about the Python-checkins mailing list