[Python-checkins] r53382 - in sandbox/trunk/2to3: example.py fixes/basefix.py fixes/fix_except.py pgen2/parse.py refactor.py

guido.van.rossum python-checkins at python.org
Thu Jan 11 20:02:09 CET 2007


Author: guido.van.rossum
Date: Thu Jan 11 20:02:08 2007
New Revision: 53382

Modified:
   sandbox/trunk/2to3/example.py
   sandbox/trunk/2to3/fixes/basefix.py
   sandbox/trunk/2to3/fixes/fix_except.py
   sandbox/trunk/2to3/pgen2/parse.py
   sandbox/trunk/2to3/refactor.py
Log:
Collin Winter's improvements to fix_except.py.
I changed new_name() slightly, and got rid of a spurious 'o' in a docstring.


Modified: sandbox/trunk/2to3/example.py
==============================================================================
--- sandbox/trunk/2to3/example.py	(original)
+++ sandbox/trunk/2to3/example.py	Thu Jan 11 20:02:08 2007
@@ -162,7 +162,9 @@
 def except_examples():
     try:
         pass
-    except Exception, e:
+    except Exception, (f, e):
+        pass
+    except ImportError, e:
         pass
     #
     try:
@@ -170,8 +172,6 @@
     except (RuntimeError, ImportError), e:
         pass
     #
-    # These should not be touched
-    #
     try:
         pass
     except Exception, (a, b):
@@ -192,6 +192,13 @@
     except Exception, a().foo:
         pass
     #
+    # These should not be touched:
+    #
+    try:
+        pass
+    except:
+        pass
+    #
     try:
         pass
     except Exception:
@@ -199,7 +206,8 @@
     #
     try:
         pass
-    except (RuntimeError, ImportError):
+    except (Exception, SystemExit):
         pass
     
+    
 # This is the last line.

Modified: sandbox/trunk/2to3/fixes/basefix.py
==============================================================================
--- sandbox/trunk/2to3/fixes/basefix.py	(original)
+++ sandbox/trunk/2to3/fixes/basefix.py	Thu Jan 11 20:02:08 2007
@@ -5,11 +5,14 @@
 
 # Python imports
 import logging
+import itertools
 
 # Local imports
 import patcomp
 import pygram
 
+# For new_name()
+numbers = itertools.count(1)
 
 class BaseFix(object):
 
@@ -26,13 +29,14 @@
     options = None  # Options object passed to initializer
     filename = None # The filename (set by set_filename)
     logger = None   # A logger (set by set_filename)
+    used_names = set() # A set of all used NAMEs
 
     # Shortcut for access to Python grammar symbols
     syms = pygram.python_symbols
 
     def __init__(self, options):
         """Initializer.  Subclass may override.
-o
+
         The argument is an optparse.Values instance which can be used
         to inspect the command line options.
         """
@@ -80,3 +84,10 @@
     def parenthesize(self, node):
         """Wrapper around pygram.parenthesize()."""
         return pygram.parenthesize(node)
+
+    def new_name(self, template="xxx_todo_changeme"):
+        name = template
+        while name in self.used_names:
+            name = template + str(numbers.next())
+        self.used_names.add(name)
+        return name

Modified: sandbox/trunk/2to3/fixes/fix_except.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_except.py	(original)
+++ sandbox/trunk/2to3/fixes/fix_except.py	Thu Jan 11 20:02:08 2007
@@ -2,6 +2,7 @@
 
 # Python imports
 import token
+import pprint
 
 # Local imports
 import pytree
@@ -13,11 +14,27 @@
             return
         node = node.children[0]
     return node.lineno
+    
+def find_excepts(nodes):
+    for i in range(len(nodes)):
+        n = nodes[i]
+        if isinstance(n, pytree.Node):
+            if n.children[0].value == 'except':
+                yield (n, nodes[i+2])
+
+as_leaf = pytree.Leaf(token.NAME, "as")
+as_leaf.set_prefix(" ")
+
+ass_leaf = pytree.Leaf(token.EQUAL, "=")
+ass_leaf.set_prefix(" ")
 
 class FixExcept(basefix.BaseFix):
 
     PATTERN = """
-    except_clause< 'except' a=any ',' b=any >
+    try_stmt< 'try' ':' suite
+                  cleanup=((except_clause ':' suite)+ ['else' ':' suite]
+                                                      ['finally' ':' suite]
+	                       | 'finally' ':' suite) >
     """
     
     def transform(self, node):
@@ -25,27 +42,38 @@
         results = self.match(node)
         assert results
         
-        a = results["a"].clone()
-        b = results["b"].clone()
-        
-        if b.type != token.NAME:
-            lineno = get_lineno(node)
-            self.logger.warning("At line %s, unable to transform: %s" %
-                                                                (lineno, node))
-            return node
-        
-        as_leaf = pytree.Leaf(token.NAME, "as")
-        as_leaf.set_prefix(" ")
-        
-        # Python 2 excepts could take the form except E,V: (no space)
-        # That doesn't work for the new version
-        if not b.get_prefix():
-            b.set_prefix(" ")
+        try_cleanup = [ch.clone() for ch in results['cleanup']]
+        for except_clause, e_suite in find_excepts(try_cleanup):
+            if len(except_clause.children) == 4:
+                (E, comma, N) = except_clause.children[1:4]
+                comma.replace(as_leaf.clone())
+                if str(N).strip()[0] == '(':
+                    # We're dealing with a tuple
+                    lineno = get_lineno(N)
+                    msg = "At line %d, exception unpacking is going away"
+                    self.logger.warning(msg % lineno)
+                elif N.type != token.NAME:
+                    # Generate a new N for the except clause
+                    new_N = pytree.Leaf(token.NAME, self.new_name())
+                    new_N.set_prefix(" ")
+                    target = N.clone()
+                    target.set_prefix("")
+                    N.replace(new_N)
+                    
+                    # Insert "old_N = new_N" as the first statement in
+                    #  the except body
+                    suite_stmts = list(e_suite.children)
+                    for i, stmt in enumerate(suite_stmts):
+                        if isinstance(stmt, pytree.Node):
+                            break
+                    assign = pytree.Node(syms.atom,
+                                         [target,
+                                          ass_leaf.clone(),
+                                          new_N.clone()])
+                    
+                    assign.parent = e_suite                      
+                    suite_stmts = suite_stmts[:i] + [assign] + suite_stmts
+                    e_suite.children = tuple(suite_stmts)
         
-        new = pytree.Node(syms.except_clause,
-                          [pytree.Leaf(token.NAME, "except"),
-                           pytree.Node(syms.test, [a]),
-                           as_leaf,
-                           pytree.Node(syms.test, [b])])
-        new.set_prefix(node.get_prefix())
-        return new
+        children = [c.clone() for c in node.children[:3]] + try_cleanup
+        return pytree.Node(node.type, children)

Modified: sandbox/trunk/2to3/pgen2/parse.py
==============================================================================
--- sandbox/trunk/2to3/pgen2/parse.py	(original)
+++ sandbox/trunk/2to3/pgen2/parse.py	Thu Jan 11 20:02:08 2007
@@ -108,6 +108,7 @@
         stackentry = (self.grammar.dfas[start], 0, newnode)
         self.stack = [stackentry]
         self.rootnode = None
+        self.used_names = set() # Aliased to self.rootnode.used_names in pop()
 
     def addtoken(self, type, value, context):
         """Add a token; return True iff this is the end of the program."""
@@ -160,6 +161,8 @@
     def classify(self, type, value, context):
         """Turn a token into a label.  (Internal)"""
         if type == token.NAME:
+            # Keep a listing of all used names
+            self.used_names.add(value)
             # Check for reserved words
             ilabel = self.grammar.keywords.get(value)
             if ilabel is not None:
@@ -195,3 +198,4 @@
                 node[-1].append(newnode)
             else:
                 self.rootnode = newnode
+                self.rootnode.used_names = self.used_names

Modified: sandbox/trunk/2to3/refactor.py
==============================================================================
--- sandbox/trunk/2to3/refactor.py	(original)
+++ sandbox/trunk/2to3/refactor.py	Thu Jan 11 20:02:08 2007
@@ -195,6 +195,7 @@
         """Refactors a parse tree."""
         for fixer in self.fixers:
             fixer.set_filename(filename)
+            fixer.used_names = tree.used_names
         changes = 0
         for node in tree.post_order():
             for fixer in self.fixers:


More information about the Python-checkins mailing list