[Python-checkins] r58055 - in sandbox/trunk/2to3: fixes/fix_tuple_params.py tests/test_fixers.py

collin.winter python-checkins at python.org
Sat Sep 8 23:02:43 CEST 2007


Author: collin.winter
Date: Sat Sep  8 23:02:43 2007
New Revision: 58055

Modified:
   sandbox/trunk/2to3/fixes/fix_tuple_params.py
   sandbox/trunk/2to3/tests/test_fixers.py
Log:
Make fix_tuple_params handle unnecessary parens around lambda parameters; this fixes issue #1107.

Modified: sandbox/trunk/2to3/fixes/fix_tuple_params.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_tuple_params.py	(original)
+++ sandbox/trunk/2to3/fixes/fix_tuple_params.py	Sat Sep  8 23:02:43 2007
@@ -12,6 +12,9 @@
 It will also support lambdas:
   
     lambda (x, y): x + y -> lambda t: t[0] + t[1]
+
+    # The parens are a syntax error in Python 3
+    lambda (x): x + y -> lambda x: x + y
 """
 # Author: Collin Winter
 
@@ -30,7 +33,11 @@
               funcdef< 'def' any parameters< '(' args=any ')' >
                        ['->' any] ':' suite=any+ >
               |
-              lambda=lambdef< 'lambda' args=vfpdef< '(' vfplist< any+ > ')' > ':' body=any >"""
+              lambda=
+              lambdef< 'lambda' args=vfpdef< '(' inner=any ')' >
+                       ':' body=any
+              >
+              """
 
     def transform(self, node, results):
         if "lambda" in results:
@@ -97,6 +104,14 @@
     def transform_lambda(self, node, results):
         args = results["args"]
         body = results["body"]
+        inner = simplify_args(results["inner"])
+
+        # Replace lambda ((((x)))): x  with lambda x: x
+        if inner.type == token.NAME:
+            inner = inner.clone()
+            inner.set_prefix(args.get_prefix())
+            args.replace(inner)
+            return
 
         params = find_params(args)
         to_index = map_to_index(params)
@@ -116,6 +131,17 @@
 
 ### Helper functions for transform_lambda()
 
+def simplify_args(node):
+    if node.type in (syms.vfplist, token.NAME):
+        return node
+    elif node.type == syms.vfpdef:
+        # These look like vfpdef< '(' x ')' > where x is NAME
+        # or another vfpdef instance (leading to recursion).
+        while node.type == syms.vfpdef:
+            node = node.children[1]
+        return node
+    raise RuntimeError("Received unexpected node %s" % node)
+
 def find_params(node):
     if node.type == syms.vfpdef:
         return find_params(node.children[1])

Modified: sandbox/trunk/2to3/tests/test_fixers.py
==============================================================================
--- sandbox/trunk/2to3/tests/test_fixers.py	(original)
+++ sandbox/trunk/2to3/tests/test_fixers.py	Sat Sep  8 23:02:43 2007
@@ -1531,20 +1531,33 @@
         s = """lambda x: x + 5"""
         self.unchanged(s)
 
-        # Note the parens around x
-        s = """lambda (x): x + 5"""
-        self.unchanged(s)
+    def test_lambda_parens_single_arg(self):
+        b = """lambda (x): x + 5"""
+        a = """lambda x: x + 5"""
+        self.check(b, a)
+
+        b = """lambda ((((x)))): x + 5"""
+        a = """lambda x: x + 5"""
+        self.check(b, a)
 
     def test_lambda_simple(self):
         b = """lambda (x, y): x + f(y)"""
         a = """lambda x_y: x_y[0] + f(x_y[1])"""
         self.check(b, a)
 
+        b = """lambda (((x, y))): x + f(y)"""
+        a = """lambda x_y: x_y[0] + f(x_y[1])"""
+        self.check(b, a)
+
     def test_lambda_one_tuple(self):
         b = """lambda (x,): x + f(x)"""
         a = """lambda x1: x1[0] + f(x1[0])"""
         self.check(b, a)
 
+        b = """lambda (((x,))): x + f(x)"""
+        a = """lambda x1: x1[0] + f(x1[0])"""
+        self.check(b, a)
+
     def test_lambda_simple_multi_use(self):
         b = """lambda (x, y): x + x + f(x) + x"""
         a = """lambda x_y: x_y[0] + x_y[0] + f(x_y[0]) + x_y[0]"""
@@ -1560,6 +1573,10 @@
         a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]"""
         self.check(b, a)
 
+        b = """lambda (((x, (y, z)))): x + y + z"""
+        a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]"""
+        self.check(b, a)
+
     def test_lambda_nested_multi_use(self):
         b = """lambda (x, (y, z)): x + y + f(y)"""
         a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + f(x_y_z[1][0])"""


More information about the Python-checkins mailing list