fix_apply.py revision 5e37baea8007cb64b65a180e4d6c80de292a8a4a
15e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis# Copyright 2006 Google, Inc. All Rights Reserved.
25e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis# Licensed to PSF under a Contributor Agreement.
35e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis
45e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis"""Fixer for apply().
55e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis
65e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. LöwisThis converts apply(func, v, k) into (func)(*v, **k)."""
75e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis
85e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis# Local imports
95e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom .. import pytree
105e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom ..pgen2 import token
115e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom . import basefix
125e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom .util import Call, Comma
135e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis
145e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisclass FixApply(basefix.BaseFix):
155e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis
165e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis    PATTERN = """
175e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis    power< 'apply'
185e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        trailer<
195e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            '('
205e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            arglist<
215e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis                (not argument<NAME '=' any>) func=any ','
225e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis                (not argument<NAME '=' any>) args=any [','
235e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis                (not argument<NAME '=' any>) kwds=any] [',']
245e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            >
255e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            ')'
265e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        >
275e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis    >
285e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis    """
295e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis
305e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis    def transform(self, node, results):
315e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        syms = self.syms
325e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        assert results
335e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        func = results["func"]
345e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        args = results["args"]
355e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        kwds = results.get("kwds")
365e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        prefix = node.get_prefix()
375e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        func = func.clone()
385e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        if (func.type not in (token.NAME, syms.atom) and
395e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            (func.type != syms.power or
405e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis             func.children[-2].type == token.DOUBLESTAR)):
415e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            # Need to parenthesize
425e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            func = self.parenthesize(func)
435e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        func.set_prefix("")
445e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        args = args.clone()
455e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        args.set_prefix("")
465e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        if kwds is not None:
475e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            kwds = kwds.clone()
485e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            kwds.set_prefix("")
495e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        l_newargs = [pytree.Leaf(token.STAR, "*"), args]
505e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        if kwds is not None:
515e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            l_newargs.extend([Comma(),
525e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis                              pytree.Leaf(token.DOUBLESTAR, "**"),
535e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis                              kwds])
545e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis            l_newargs[-2].set_prefix(" ") # that's the ** token
555e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t)
565e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        # can be translated into f(x, y, *t) instead of f(*(x, y) + t)
575e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        #new = pytree.Node(syms.power, (func, ArgList(l_newargs)))
585e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis        return Call(func, l_newargs, prefix=prefix)
59