mirror of
https://github.com/python/cpython.git
synced 2025-10-24 02:13:49 +00:00
svn+ssh://pythondev@svn.python.org/python/branches/py3k
................
r80936 | benjamin.peterson | 2010-05-07 14:10:11 -0500 (Fri, 07 May 2010) | 76 lines
Merged revisions 80934 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
................
r80934 | benjamin.peterson | 2010-05-07 13:58:23 -0500 (Fri, 07 May 2010) | 69 lines
Merged revisions 79911,79916-79917,80018,80418,80572-80573,80635-80639,80668,80922 via svnmerge from
svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3
........
r79911 | benjamin.peterson | 2010-04-09 15:38:53 -0500 (Fri, 09 Apr 2010) | 1 line
use absolute import
........
r79916 | benjamin.peterson | 2010-04-09 16:05:21 -0500 (Fri, 09 Apr 2010) | 1 line
generalize detection of __future__ imports and attach them to the tree
........
r79917 | benjamin.peterson | 2010-04-09 16:11:44 -0500 (Fri, 09 Apr 2010) | 1 line
don't try to 'fix' relative imports when absolute_import is enabled #8858
........
r80018 | benjamin.peterson | 2010-04-12 16:12:12 -0500 (Mon, 12 Apr 2010) | 4 lines
prevent diffs from being mangled is multiprocess mode #6409
Patch by George Boutsioukis.
........
r80418 | benjamin.peterson | 2010-04-23 16:00:03 -0500 (Fri, 23 Apr 2010) | 1 line
remove unhelpful description
........
r80572 | benjamin.peterson | 2010-04-27 20:33:54 -0500 (Tue, 27 Apr 2010) | 1 line
use unicode literals
........
r80573 | jeffrey.yasskin | 2010-04-27 23:08:27 -0500 (Tue, 27 Apr 2010) | 6 lines
Don't transform imports that are already relative. 2to3 turned
from . import refactor
into
from .. import refactor
which broke the transformation of 2to3 itself.
........
r80635 | benjamin.peterson | 2010-04-29 16:02:23 -0500 (Thu, 29 Apr 2010) | 1 line
remove imports
........
r80636 | benjamin.peterson | 2010-04-29 16:02:41 -0500 (Thu, 29 Apr 2010) | 1 line
unicode literal
........
r80637 | benjamin.peterson | 2010-04-29 16:03:42 -0500 (Thu, 29 Apr 2010) | 1 line
must pass a string to Number
........
r80638 | benjamin.peterson | 2010-04-29 16:05:34 -0500 (Thu, 29 Apr 2010) | 1 line
unicode literals
........
r80639 | benjamin.peterson | 2010-04-29 16:06:09 -0500 (Thu, 29 Apr 2010) | 1 line
pass string to Number
........
r80668 | jeffrey.yasskin | 2010-04-30 18:02:47 -0500 (Fri, 30 Apr 2010) | 4 lines
Make 2to3 run under Python 2.5 so that the benchmark suite at
http://hg.python.org/benchmarks/ can use it and still run on implementations
that haven't gotten to 2.6 yet. Fixes issue 8566.
........
r80922 | benjamin.peterson | 2010-05-07 11:06:25 -0500 (Fri, 07 May 2010) | 1 line
prevent xrange transformation from wrapping range calls it produces in list
........
................
................
171 lines
5.3 KiB
Python
171 lines
5.3 KiB
Python
"""Fixer for function definitions with tuple parameters.
|
|
|
|
def func(((a, b), c), d):
|
|
...
|
|
|
|
->
|
|
|
|
def func(x, d):
|
|
((a, b), c) = x
|
|
...
|
|
|
|
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
|
|
|
|
# Local imports
|
|
from .. import pytree
|
|
from ..pgen2 import token
|
|
from .. import fixer_base
|
|
from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms
|
|
|
|
def is_docstring(stmt):
|
|
return isinstance(stmt, pytree.Node) and \
|
|
stmt.children[0].type == token.STRING
|
|
|
|
class FixTupleParams(fixer_base.BaseFix):
|
|
PATTERN = """
|
|
funcdef< 'def' any parameters< '(' args=any ')' >
|
|
['->' any] ':' suite=any+ >
|
|
|
|
|
lambda=
|
|
lambdef< 'lambda' args=vfpdef< '(' inner=any ')' >
|
|
':' body=any
|
|
>
|
|
"""
|
|
|
|
def transform(self, node, results):
|
|
if "lambda" in results:
|
|
return self.transform_lambda(node, results)
|
|
|
|
new_lines = []
|
|
suite = results["suite"]
|
|
args = results["args"]
|
|
# This crap is so "def foo(...): x = 5; y = 7" is handled correctly.
|
|
# TODO(cwinter): suite-cleanup
|
|
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.prefix = ""
|
|
stmt = Assign(arg, n.clone())
|
|
if add_prefix:
|
|
n.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
|
|
|
|
# This isn't strictly necessary, but it plays nicely with other fixers.
|
|
# TODO(cwinter) get rid of this when children becomes a smart list
|
|
for line in new_lines:
|
|
line.parent = suite[0]
|
|
|
|
# TODO(cwinter) suite-cleanup
|
|
after = start
|
|
if start == 0:
|
|
new_lines[0].prefix = " "
|
|
elif is_docstring(suite[0].children[start]):
|
|
new_lines[0].prefix = indent
|
|
after = start + 1
|
|
|
|
for line in new_lines:
|
|
line.parent = suite[0]
|
|
suite[0].children[after:after] = new_lines
|
|
for i in range(after+1, after+len(new_lines)+1):
|
|
suite[0].children[i].prefix = indent
|
|
suite[0].changed()
|
|
|
|
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.prefix = " "
|
|
args.replace(inner)
|
|
return
|
|
|
|
params = find_params(args)
|
|
to_index = map_to_index(params)
|
|
tup_name = self.new_name(tuple_name(params))
|
|
|
|
new_param = Name(tup_name, prefix=" ")
|
|
args.replace(new_param.clone())
|
|
for n in body.post_order():
|
|
if n.type == token.NAME and n.value in to_index:
|
|
subscripts = [c.clone() for c in to_index[n.value]]
|
|
new = pytree.Node(syms.power,
|
|
[new_param.clone()] + subscripts)
|
|
new.prefix = n.prefix
|
|
n.replace(new)
|
|
|
|
|
|
### 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])
|
|
elif node.type == token.NAME:
|
|
return node.value
|
|
return [find_params(c) for c in node.children if c.type != token.COMMA]
|
|
|
|
def map_to_index(param_list, prefix=[], d=None):
|
|
if d is None:
|
|
d = {}
|
|
for i, obj in enumerate(param_list):
|
|
trailer = [Subscript(Number(str(i)))]
|
|
if isinstance(obj, list):
|
|
map_to_index(obj, trailer, d=d)
|
|
else:
|
|
d[obj] = prefix + trailer
|
|
return d
|
|
|
|
def tuple_name(param_list):
|
|
l = []
|
|
for obj in param_list:
|
|
if isinstance(obj, list):
|
|
l.append(tuple_name(obj))
|
|
else:
|
|
l.append(obj)
|
|
return "_".join(l)
|