fixer_util.py revision 4eb5fa56e4b84a3a76ddc9487f19764dfab52a7f
1ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis"""Utility functions, node construction macros, etc."""
2ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis# Author: Collin Winter
3ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
44eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Petersonfrom itertools import islice
54eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson
6ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis# Local imports
7df6dc8f10770f92db68c69d87abe7c89774d128cBenjamin Petersonfrom .pgen2 import token
8df6dc8f10770f92db68c69d87abe7c89774d128cBenjamin Petersonfrom .pytree import Leaf, Node
9df6dc8f10770f92db68c69d87abe7c89774d128cBenjamin Petersonfrom .pygram import python_symbols as syms
10df6dc8f10770f92db68c69d87abe7c89774d128cBenjamin Petersonfrom . import patcomp
11ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
12ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
13ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
14ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis### Common node-construction "macros"
15ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
16ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
17ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef KeywordArg(keyword, value):
18ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Node(syms.argument,
194eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson                [keyword, Leaf(token.EQUAL, "="), value])
20ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
21ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef LParen():
22ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.LPAR, "(")
23ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
24ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef RParen():
25ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.RPAR, ")")
26ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
27ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Assign(target, source):
28ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """Build an assignment statement"""
29ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    if not isinstance(target, list):
30ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        target = [target]
31ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    if not isinstance(source, list):
322c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson        source.prefix = " "
33ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        source = [source]
34ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
35ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Node(syms.atom,
36ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                target + [Leaf(token.EQUAL, "=", prefix=" ")] + source)
37ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
38ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Name(name, prefix=None):
39ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """Return a NAME leaf"""
40ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.NAME, name, prefix=prefix)
41ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
42ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Attr(obj, attr):
43ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A node tuple for obj.attr"""
44ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return [obj, Node(syms.trailer, [Dot(), attr])]
45ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
46ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Comma():
47ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A comma leaf"""
48ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.COMMA, ",")
49ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
50ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Dot():
51ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A period (.) leaf"""
52ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.DOT, ".")
53ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
54ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef ArgList(args, lparen=LParen(), rparen=RParen()):
55ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A parenthesised argument list, used by Call()"""
56cf60382420f849881c3e1e9d691d9da2d4e95bc7Benjamin Peterson    node = Node(syms.trailer, [lparen.clone(), rparen.clone()])
57cf60382420f849881c3e1e9d691d9da2d4e95bc7Benjamin Peterson    if args:
58cf60382420f849881c3e1e9d691d9da2d4e95bc7Benjamin Peterson        node.insert_child(1, Node(syms.arglist, args))
59cf60382420f849881c3e1e9d691d9da2d4e95bc7Benjamin Peterson    return node
60ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
61cf60382420f849881c3e1e9d691d9da2d4e95bc7Benjamin Petersondef Call(func_name, args=None, prefix=None):
62ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A function call"""
63ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    node = Node(syms.power, [func_name, ArgList(args)])
64ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    if prefix is not None:
652c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson        node.prefix = prefix
66ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return node
67ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
68ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Newline():
69ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A newline literal"""
70ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.NEWLINE, "\n")
71ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
72ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef BlankLine():
73ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A blank line"""
74ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.NEWLINE, "")
75ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
76ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Number(n, prefix=None):
77ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.NUMBER, n, prefix=prefix)
78ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
79ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef Subscript(index_node):
80ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A numeric or string subscript"""
814eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson    return Node(syms.trailer, [Leaf(token.LBRACE, "["),
82ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                               index_node,
834eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson                               Leaf(token.RBRACE, "]")])
84ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
85ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef String(string, prefix=None):
86ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A string leaf"""
87ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Leaf(token.STRING, string, prefix=prefix)
88ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
89ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef ListComp(xp, fp, it, test=None):
90ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """A list comprehension of the form [xp for fp in it if test].
91ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
92ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    If test is None, the "if test" part is omitted.
93ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """
942c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson    xp.prefix = ""
952c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson    fp.prefix = " "
962c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson    it.prefix = " "
97ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    for_leaf = Leaf(token.NAME, "for")
982c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson    for_leaf.prefix = " "
99ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    in_leaf = Leaf(token.NAME, "in")
1002c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson    in_leaf.prefix = " "
101ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    inner_args = [for_leaf, fp, in_leaf, it]
102ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    if test:
1032c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson        test.prefix = " "
104ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        if_leaf = Leaf(token.NAME, "if")
1052c3ac6b8757f8fc1dacf6aeaa9a9518d8729d52bBenjamin Peterson        if_leaf.prefix = " "
106ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        inner_args.append(Node(syms.comp_if, [if_leaf, test]))
107ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)])
108ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return Node(syms.atom,
109ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                       [Leaf(token.LBRACE, "["),
110ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                        inner,
111ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                        Leaf(token.RBRACE, "]")])
112ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
113a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwisdef FromImport(package_name, name_leafs):
114a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis    """ Return an import statement in the form:
115a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis        from package import name_leafs"""
116a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis    # XXX: May not handle dotted imports properly (eg, package_name='foo.bar')
117d613bb4c292635ead23b30af0c9bb83abc81d2beBenjamin Peterson    #assert package_name == '.' or '.' not in package_name, "FromImport has "\
118d613bb4c292635ead23b30af0c9bb83abc81d2beBenjamin Peterson    #       "not been tested with dotted package names -- use at your own "\
119d613bb4c292635ead23b30af0c9bb83abc81d2beBenjamin Peterson    #       "peril!"
120a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis
121a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis    for leaf in name_leafs:
122a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis        # Pull the leaves out of their old tree
123a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis        leaf.remove()
124a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis
1254eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson    children = [Leaf(token.NAME, "from"),
126a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis                Leaf(token.NAME, package_name, prefix=" "),
1274eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson                Leaf(token.NAME, "import", prefix=" "),
128a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis                Node(syms.import_as_names, name_leafs)]
129a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis    imp = Node(syms.import_from, children)
130a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis    return imp
131a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis
132a675ef1141e2533bd5596222d0a64b6a3f74d2d0Martin v. Löwis
133ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
134ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis### Determine whether a node represents a given literal
135ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
136ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
137ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef is_tuple(node):
138ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """Does the node represent a tuple literal?"""
139ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    if isinstance(node, Node) and node.children == [LParen(), RParen()]:
140ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        return True
141ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return (isinstance(node, Node)
142ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and len(node.children) == 3
143ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and isinstance(node.children[0], Leaf)
144ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and isinstance(node.children[1], Node)
145ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and isinstance(node.children[2], Leaf)
146ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and node.children[0].value == "("
147ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and node.children[2].value == ")")
148ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
149ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef is_list(node):
150ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """Does the node represent a list literal?"""
151ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return (isinstance(node, Node)
152ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and len(node.children) > 1
153ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and isinstance(node.children[0], Leaf)
154ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and isinstance(node.children[-1], Leaf)
155ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and node.children[0].value == "["
156ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            and node.children[-1].value == "]")
157ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
158ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
159ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
160ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis### Misc
161ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
162ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
1630b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Petersondef parenthesize(node):
1640b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    return Node(syms.atom, [LParen(), node, RParen()])
1650b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
1663de92bf155a1fff6e48b32c5d5f0071f6669ebf0Martin v. Löwis
1673de92bf155a1fff6e48b32c5d5f0071f6669ebf0Martin v. Löwisconsuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum",
1683de92bf155a1fff6e48b32c5d5f0071f6669ebf0Martin v. Löwis                       "min", "max"])
1693de92bf155a1fff6e48b32c5d5f0071f6669ebf0Martin v. Löwis
170ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef attr_chain(obj, attr):
171ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """Follow an attribute chain.
172f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis
173ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    If you have a chain of objects where a.foo -> b, b.foo-> c, etc,
174ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    use this to iterate over all objects in the chain. Iteration is
175ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    terminated by getattr(x, attr) is None.
176f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis
177ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    Args:
178ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        obj: the starting object
179ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        attr: the name of the chaining attribute
180f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis
181ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    Yields:
182ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        Each successive object in the chain.
183ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """
184ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    next = getattr(obj, attr)
185ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    while next:
186ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        yield next
187ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        next = getattr(next, attr)
188ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
189f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwisp0 = """for_stmt< 'for' any 'in' node=any ':' any* >
190f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        | comp_for< 'for' any 'in' node=any any* >
191f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis     """
192f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwisp1 = """
193f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwispower<
194f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' |
195f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis      'any' | 'all' | (any* trailer< '.' 'join' >) )
196f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    trailer< '(' node=any ')' >
197f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    any*
198f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis>
199f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis"""
200f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwisp2 = """
201f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwispower<
202f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    'sorted'
203f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    trailer< '(' arglist<node=any any*> ')' >
204f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    any*
205f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis>
206f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis"""
207f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwispats_built = False
208f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwisdef in_special_context(node):
209f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    """ Returns true if node is in an environment where all that is required
210f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        of it is being itterable (ie, it doesn't matter if it returns a list
211f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        or an itterator).
212f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        See test_map_nochange in test_fixers.py for some examples and tests.
213f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        """
214f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    global p0, p1, p2, pats_built
215f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    if not pats_built:
216f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        p1 = patcomp.compile_pattern(p1)
217f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        p0 = patcomp.compile_pattern(p0)
218f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        p2 = patcomp.compile_pattern(p2)
219f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        pats_built = True
220f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    patterns = [p0, p1, p2]
221f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    for pattern, parent in zip(patterns, attr_chain(node, "parent")):
222f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        results = {}
223f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis        if pattern.match(parent, results) and results["node"] is node:
224f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis            return True
225f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis    return False
226f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis
2278bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Petersondef is_probably_builtin(node):
2288bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    """
2298bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    Check that something isn't an attribute or function name etc.
2308bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    """
231608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson    prev = node.prev_sibling
2328bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    if prev is not None and prev.type == token.DOT:
2338bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson        # Attribute lookup.
2348bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson        return False
2358bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    parent = node.parent
2368bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    if parent.type in (syms.funcdef, syms.classdef):
2378bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson        return False
2388bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    if parent.type == syms.expr_stmt and parent.children[0] is node:
2398bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson        # Assignment.
2408bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson        return False
2418bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    if parent.type == syms.parameters or \
2428bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson            (parent.type == syms.typedargslist and (
2438bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson            (prev is not None and prev.type == token.COMMA) or
2448bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson            parent.children[0] is node
2458bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson            )):
2468bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson        # The name of an argument.
2478bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson        return False
2488bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson    return True
2498bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson
2504eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Petersondef find_indentation(node):
2514eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson    """Find the indentation of *node*."""
2524eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson    while node is not None:
2534eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson        if node.type == syms.suite and len(node.children) > 2:
2544eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson            indent = node.children[1]
2554eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson            if indent.type == token.INDENT:
2564eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson                return indent.value
2574eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson        node = node.parent
2584eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson    return ""
2594eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson
260ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
261ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis### The following functions are to find bindings in a suite
262ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis###########################################################
263ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
264ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef make_suite(node):
265ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    if node.type == syms.suite:
266ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        return node
267ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    node = node.clone()
268ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    parent, node.parent = node.parent, None
269ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    suite = Node(syms.suite, [node])
270ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    suite.parent = parent
271ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return suite
272ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
2730b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Petersondef find_root(node):
2740b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    """Find the top level namespace."""
275ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    # Scamper up to the top level namespace
276ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    while node.type != syms.file_input:
277ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        assert node.parent, "Tree is insane! root found before "\
278ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                           "file_input node was found."
279ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        node = node.parent
2800b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    return node
281ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
2820b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Petersondef does_tree_import(package, name, node):
2830b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    """ Returns true if name is imported from package at the
2840b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        top level of the tree which node belongs to.
2850b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        To cover the case of an import like 'import foo', use
2860b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        None for the package and 'foo' for the name. """
2870b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    binding = find_binding(name, find_root(node), package)
288ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return bool(binding)
289ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
2900b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Petersondef is_import(node):
2910b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    """Returns true if the node is an import statement."""
2920b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    return node.type in (syms.import_name, syms.import_from)
2930b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
2940b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Petersondef touch_import(package, name, node):
2950b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    """ Works like `does_tree_import` but adds an import statement
2960b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        if it was not imported. """
2970b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    def is_import_stmt(node):
2980b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        return node.type == syms.simple_stmt and node.children and \
2990b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson               is_import(node.children[0])
3000b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
3010b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    root = find_root(node)
3020b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
3030b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    if does_tree_import(package, name, root):
3040b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        return
3050b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
3060b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    # figure out where to insert the new import.  First try to find
3070b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    # the first import and then skip to the last one.
3080b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    insert_pos = offset = 0
3090b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    for idx, node in enumerate(root.children):
3100b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        if not is_import_stmt(node):
3110b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson            continue
3120b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        for offset, node2 in enumerate(root.children[idx:]):
3130b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson            if not is_import_stmt(node2):
3140b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson                break
3150b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        insert_pos = idx + offset
3160b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        break
3170b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
3180b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    # if there are no imports where we can insert, find the docstring.
3190b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    # if that also fails, we stick to the beginning of the file
3200b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    if insert_pos == 0:
3210b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        for idx, node in enumerate(root.children):
3220b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson            if node.type == syms.simple_stmt and node.children and \
3230b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson               node.children[0].type == token.STRING:
3240b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson                insert_pos = idx + 1
3250b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson                break
3260b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
3270b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    if package is None:
3280b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        import_ = Node(syms.import_name, [
3294eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson            Leaf(token.NAME, "import"),
3304eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson            Leaf(token.NAME, name, prefix=" ")
3310b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson        ])
3320b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    else:
3334eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson        import_ = FromImport(package, [Leaf(token.NAME, name, prefix=" ")])
3340b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
3350b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    children = [import_, Newline()]
3360b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson    root.insert_child(insert_pos, Node(syms.simple_stmt, children))
3370b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
3380b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson
339ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis_def_syms = set([syms.classdef, syms.funcdef])
340ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef find_binding(name, node, package=None):
341ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """ Returns the node which binds variable name, otherwise None.
342ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        If optional argument package is supplied, only imports will
343ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        be returned.
344ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        See test cases for examples."""
345ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    for child in node.children:
346ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        ret = None
347ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        if child.type == syms.for_stmt:
348ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            if _find(name, child.children[1]):
349ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                return child
350ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            n = find_binding(name, make_suite(child.children[-1]), package)
351ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            if n: ret = n
352ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif child.type in (syms.if_stmt, syms.while_stmt):
353ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            n = find_binding(name, make_suite(child.children[-1]), package)
354ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            if n: ret = n
355ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif child.type == syms.try_stmt:
356ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            n = find_binding(name, make_suite(child.children[2]), package)
357ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            if n:
358ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                ret = n
359ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            else:
360ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                for i, kid in enumerate(child.children[3:]):
361ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                    if kid.type == token.COLON and kid.value == ":":
362ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                        # i+3 is the colon, i+4 is the suite
363ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                        n = find_binding(name, make_suite(child.children[i+4]), package)
364ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                        if n: ret = n
365ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif child.type in _def_syms and child.children[1].value == name:
366ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            ret = child
367ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif _is_import_binding(child, name, package):
368ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            ret = child
369ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif child.type == syms.simple_stmt:
370ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            ret = find_binding(name, child, package)
371ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif child.type == syms.expr_stmt:
372f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis            if _find(name, child.children[0]):
373f733c60d9aea123a46cd41dbe4dedee7aa2f20f3Martin v. Löwis                ret = child
374ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
375ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        if ret:
376ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            if not package:
377ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                return ret
3780b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson            if is_import(ret):
379ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                return ret
380ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return None
381ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
382ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis_block_syms = set([syms.funcdef, syms.classdef, syms.trailer])
383ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef _find(name, node):
384ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    nodes = [node]
385ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    while nodes:
386ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        node = nodes.pop()
387ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        if node.type > 256 and node.type not in _block_syms:
388ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            nodes.extend(node.children)
389ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif node.type == token.NAME and node.value == name:
390ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            return node
391ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return None
392ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
393ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwisdef _is_import_binding(node, name, package=None):
394ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    """ Will reuturn node if node will import name, or node
395ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        will import * from package.  None is returned otherwise.
396ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        See test cases for examples. """
397ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis
398ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    if node.type == syms.import_name and not package:
399ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        imp = node.children[1]
400ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        if imp.type == syms.dotted_as_names:
401ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            for child in imp.children:
402ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                if child.type == syms.dotted_as_name:
403ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                    if child.children[2].value == name:
404ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                        return node
405ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                elif child.type == token.NAME and child.value == name:
406ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                    return node
407ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif imp.type == syms.dotted_as_name:
408ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            last = imp.children[-1]
409ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            if last.type == token.NAME and last.value == name:
410ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                return node
411ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif imp.type == token.NAME and imp.value == name:
412ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            return node
413ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    elif node.type == syms.import_from:
414df6dc8f10770f92db68c69d87abe7c89774d128cBenjamin Peterson        # str(...) is used to make life easier here, because
415ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        # from a.b import parses to ['import', ['a', '.', 'b'], ...]
4168a5f8ca33b56db9af973d1f34a9b3df5271b56c0Martin v. Löwis        if package and str(node.children[1]).strip() != package:
417ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            return None
418ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        n = node.children[3]
4194eb5fa56e4b84a3a76ddc9487f19764dfab52a7fBenjamin Peterson        if package and _find("as", n):
420ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            # See test_from_import_as for explanation
421ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            return None
422ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif n.type == syms.import_as_names and _find(name, n):
423ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            return node
424ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif n.type == syms.import_as_name:
425ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            child = n.children[2]
426ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            if child.type == token.NAME and child.value == name:
427ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis                return node
428ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif n.type == token.NAME and n.value == name:
429ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            return node
430ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis        elif package and n.type == token.STAR:
431ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis            return node
432ef04c44e29a8276a484f58d03a75a2dec516302dMartin v. Löwis    return None
433