[Python-checkins] r54104 - in sandbox/trunk/2to3: fixes/fix_arg_tuples.py tests/test_fixers.py
collin.winter
python-checkins at python.org
Sat Mar 3 05:03:51 CET 2007
Author: collin.winter
Date: Sat Mar 3 05:03:44 2007
New Revision: 54104
Added:
sandbox/trunk/2to3/fixes/fix_arg_tuples.py (contents, props changed)
Modified:
sandbox/trunk/2to3/tests/test_fixers.py
Log:
Add a fixer for tuple parameters (per PEP 3113).
Added: sandbox/trunk/2to3/fixes/fix_arg_tuples.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/2to3/fixes/fix_arg_tuples.py Sat Mar 3 05:03:44 2007
@@ -0,0 +1,86 @@
+"""Fixer for function definitions with tuple parameters.
+
+def func(((a, b), c), d):
+ ...
+
+ ->
+
+def func(x, d):
+ ((a, b), c) = x
+ ...
+"""
+# Author: Collin Winter
+
+# Local imports
+import pytree
+from pgen2 import token
+from fixes import basefix
+from fixes.macros import Assign, Name, Newline
+
+def is_docstring(stmt):
+ return isinstance(stmt, pytree.Node) and \
+ stmt.children[0].type == token.STRING
+
+class FixArgTuples(basefix.BaseFix):
+ PATTERN = """funcdef< 'def' any parameters< '(' args=any ')' >
+ ['->' any] ':' suite=any+ >"""
+
+ def transform(self, node):
+ syms = self.syms
+ results = self.match(node)
+ assert results
+
+ new_lines = []
+ suite = results["suite"]
+ args = results["args"]
+ # This crap is so "def foo(...): x = 5; y = 7" is handled correctly.
+ if suite[0].children[1].type == token.INDENT:
+ start = 2
+ indent = suite[0].children[1].value
+ end = Newline()
+ else:
+ start = 0
+ indent = "; "
+ end = pytree.Leaf(token.INDENT, "")
+
+ # We need access to self for new_name(), and making this a method
+ # doesn't feel right. Closing over self and new_lines makes the
+ # code below cleaner.
+ def handle_tuple(tuple_arg, add_prefix=False):
+ n = Name(self.new_name())
+ arg = tuple_arg.clone()
+ arg.set_prefix("")
+ stmt = Assign(arg, n.clone())
+ if add_prefix:
+ n.set_prefix(" ")
+ tuple_arg.replace(n)
+ new_lines.append(pytree.Node(syms.simple_stmt, [stmt, end.clone()]))
+
+ if args.type == syms.tfpdef:
+ handle_tuple(args)
+ elif args.type == syms.typedargslist:
+ for i, arg in enumerate(args.children):
+ if arg.type == syms.tfpdef:
+ # Without add_prefix, the emitted code is correct,
+ # just ugly.
+ handle_tuple(arg, add_prefix=(i > 0))
+
+ if not new_lines:
+ return node
+
+ # This isn't strictly necessary, but it plays nicely with other fixers.
+ for line in new_lines:
+ line.parent = suite[0]
+
+ after = start
+ if start == 0:
+ new_lines[0].set_prefix(" ")
+ elif is_docstring(suite[0].children[start]):
+ new_lines[0].set_prefix(indent)
+ after = start + 1
+
+ children = list(suite[0].children)
+ children[after:after] = new_lines
+ for i in range(after+1, after+len(new_lines)+1):
+ children[i].set_prefix(indent)
+ suite[0].children = tuple(children)
Modified: sandbox/trunk/2to3/tests/test_fixers.py
==============================================================================
--- sandbox/trunk/2to3/tests/test_fixers.py (original)
+++ sandbox/trunk/2to3/tests/test_fixers.py Sat Mar 3 05:03:44 2007
@@ -496,8 +496,8 @@
def foo():
try:
pass
- except Exception as xxx_todo_changeme:
- (f, e) = xxx_todo_changeme.message
+ except Exception as xxx_todo_changeme12:
+ (f, e) = xxx_todo_changeme12.message
pass
except ImportError as e:
pass"""
@@ -527,8 +527,8 @@
a = """
try:
pass
- except Exception as xxx_todo_changeme1:
- (a, b) = xxx_todo_changeme1.message
+ except Exception as xxx_todo_changeme13:
+ (a, b) = xxx_todo_changeme13.message
pass"""
self.check(b, a)
@@ -542,8 +542,8 @@
a = """
try:
pass
- except Exception as xxx_todo_changeme2:
- d[5] = xxx_todo_changeme2
+ except Exception as xxx_todo_changeme14:
+ d[5] = xxx_todo_changeme14
pass"""
self.check(b, a)
@@ -557,8 +557,8 @@
a = """
try:
pass
- except Exception as xxx_todo_changeme3:
- a.foo = xxx_todo_changeme3
+ except Exception as xxx_todo_changeme15:
+ a.foo = xxx_todo_changeme15
pass"""
self.check(b, a)
@@ -572,8 +572,8 @@
a = """
try:
pass
- except Exception as xxx_todo_changeme4:
- a().foo = xxx_todo_changeme4
+ except Exception as xxx_todo_changeme16:
+ a().foo = xxx_todo_changeme16
pass"""
self.check(b, a)
@@ -1111,6 +1111,123 @@
b = """x = input('prompt')"""
a = """x = eval(input('prompt'))"""
self.check(b, a)
+
+
+class Test_arg_tuples(FixerTestCase):
+ fixer = "arg_tuples"
+
+ def test_unchanged_1(self):
+ s = """def foo(): pass"""
+ self.check(s, s)
+
+ def test_unchanged_2(self):
+ s = """def foo(a, b, c): pass"""
+ self.check(s, s)
+
+ def test_unchanged_3(self):
+ s = """def foo(a=3, b=4, c=5): pass"""
+ self.check(s, s)
+
+ def test_1(self):
+ b = """
+ def foo(((a, b), c)):
+ x = 5"""
+
+ a = """
+ def foo(xxx_todo_changeme):
+ ((a, b), c) = xxx_todo_changeme
+ x = 5"""
+ self.check(b, a)
+
+ def test_2(self):
+ b = """
+ def foo(((a, b), c), d):
+ x = 5"""
+
+ a = """
+ def foo(xxx_todo_changeme1, d):
+ ((a, b), c) = xxx_todo_changeme1
+ x = 5"""
+ self.check(b, a)
+
+ def test_3(self):
+ b = """
+ def foo(((a, b), c), d) -> e:
+ x = 5"""
+
+ a = """
+ def foo(xxx_todo_changeme2, d) -> e:
+ ((a, b), c) = xxx_todo_changeme2
+ x = 5"""
+ self.check(b, a)
+
+ def test_semicolon(self):
+ b = """
+ def foo(((a, b), c)): x = 5; y = 7"""
+
+ a = """
+ def foo(xxx_todo_changeme10): ((a, b), c) = xxx_todo_changeme10; x = 5; y = 7"""
+ self.check(b, a)
+
+ def test_keywords(self):
+ b = """
+ def foo(((a, b), c), d, e=5) -> z:
+ x = 5"""
+
+ a = """
+ def foo(xxx_todo_changeme5, d, e=5) -> z:
+ ((a, b), c) = xxx_todo_changeme5
+ x = 5"""
+ self.check(b, a)
+
+ def test_varargs(self):
+ b = """
+ def foo(((a, b), c), d, *vargs, **kwargs) -> z:
+ x = 5"""
+
+ a = """
+ def foo(xxx_todo_changeme11, d, *vargs, **kwargs) -> z:
+ ((a, b), c) = xxx_todo_changeme11
+ x = 5"""
+ self.check(b, a)
+
+ def test_multi_1(self):
+ b = """
+ def foo(((a, b), c), (d, e, f)) -> z:
+ x = 5"""
+
+ a = """
+ def foo(xxx_todo_changeme6, xxx_todo_changeme7) -> z:
+ ((a, b), c) = xxx_todo_changeme6
+ (d, e, f) = xxx_todo_changeme7
+ x = 5"""
+ self.check(b, a)
+
+ def test_multi_2(self):
+ b = """
+ def foo(x, ((a, b), c), d, (e, f, g), y) -> z:
+ x = 5"""
+
+ a = """
+ def foo(x, xxx_todo_changeme8, d, xxx_todo_changeme9, y) -> z:
+ ((a, b), c) = xxx_todo_changeme8
+ (e, f, g) = xxx_todo_changeme9
+ x = 5"""
+ self.check(b, a)
+
+ def test_docstring(self):
+ b = """
+ def foo(((a, b), c), (d, e, f)) -> z:
+ "foo foo foo foo"
+ x = 5"""
+
+ a = """
+ def foo(xxx_todo_changeme3, xxx_todo_changeme4) -> z:
+ "foo foo foo foo"
+ ((a, b), c) = xxx_todo_changeme3
+ (d, e, f) = xxx_todo_changeme4
+ x = 5"""
+ self.check(b, a)
if __name__ == "__main__":
More information about the Python-checkins
mailing list