def transform(self, node, results): head = results["head"] method = results["method"][0] # Extract node for method name tail = results["tail"] syms = self.syms method_name = method.value isiter = method_name.startswith("iter") isview = method_name.startswith("view") if isiter or isview: method_name = method_name[4:] assert method_name in ("keys", "items", "values"), repr(method) head = [n.clone() for n in head] tail = [n.clone() for n in tail] special = not tail and self.in_special_context(node, isiter) args = head + [ pytree.Node(syms.trailer, [Dot(), Name(method_name, prefix=method.prefix)]), results["parens"].clone(), ] new = pytree.Node(syms.power, args) if not (special or isview): new.prefix = "" new = Call(Name("iter" if isiter else "list"), [new]) if tail: new = pytree.Node(syms.power, [new] + tail) new.prefix = node.prefix return new
def transform(self, node, results): assert results base = results.get("base") attr = results.get("attr") name = results.get("name") if base: if self.shadowed_next: attr.replace(Name("__next__", prefix=attr.prefix)) else: base = [n.clone() for n in base] base[0].prefix = "" node.replace(Call(Name("next", prefix=node.prefix), base)) elif name: n = Name("__next__", prefix=name.prefix) name.replace(n) elif attr: # We don't do this transformation if we're assigning to "x.next". # Unfortunately, it doesn't seem possible to do this in PATTERN, # so it's being done here. if is_assign_target(node): head = results["head"] if "".join([str(n) for n in head]).strip() == "__builtin__": self.warning(node, bind_warning) return attr.replace(Name("__next__")) elif "global" in results: self.warning(node, bind_warning) self.shadowed_next = True
def transform(self, node, results): """ Call __builtins__.long() with the value and the base of the value. This works because 0b10 is int("10", 2), 0o10 is int("10", 8), etc. """ val = node.value base_ = base(val) if base_ == 8: assert val.strip().startswith("0o") or val.strip().startswith( "0O"), "Invalid format for octal literal" node.changed() node.value = "".join(("0", val[2:])) elif base_ == 2: assert val.startswith( "0") and val[1] in "bB", "Invalid format for binary literal" # __builtins__.long func_name = Node(syms.power, Attr(Name("__builtins__"), Name("long"))) # ("...", 2) func_args = [ String("".join(('"', val.strip()[2:], '"'))), Comma(), Number(2, prefix=" ") ] new_node = Call(func_name, func_args, node.prefix) return new_node
def transform(self, node, results): if self.should_skip(node): return trailers = [] if "extra_trailers" in results: for t in results["extra_trailers"]: trailers.append(t.clone()) if "filter_lambda" in results: new = ListComp( results.get("fp").clone(), results.get("fp").clone(), results.get("it").clone(), results.get("xp").clone(), ) new = Node(syms.power, [new] + trailers, prefix="") elif "none" in results: new = ListComp(Name("_f"), Name("_f"), results["seq"].clone(), Name("_f")) new = Node(syms.power, [new] + trailers, prefix="") else: if in_special_context(node): return None args = results["args"].clone() new = Node(syms.power, [Name("filter"), args], prefix="") new = Node(syms.power, [Name("list"), ArgList([new])] + trailers) new.prefix = "" new.prefix = node.prefix return new
def fix_dotted_name(self, node, mapping=MAPPING): """ Accepts either a DottedName node or a power node with a trailer. If mapping is given, use it; otherwise use our MAPPING Returns a node that can be in-place replaced by the node given """ if node.type == syms.dotted_name: _name = node.children[0] _attr = node.children[2] elif node.type == syms.power: _name = node.children[0] _attr = node.children[1].children[1] name = _name.value attr = _attr.value full_name = name + "." + attr if not full_name in mapping: return to_repl = mapping[full_name] if "." in to_repl: repl_name, repl_attr = to_repl.split(".") _name.replace(Name(repl_name, prefix=_name.prefix)) _attr.replace(Name(repl_attr, prefix=_attr.prefix)) elif node.type == syms.dotted_name: node.replace(Name(to_repl, prefix=node.prefix)) elif node.type == syms.power: _name.replace(Name(to_repl, prefix=_name.prefix)) parent = _attr.parent _attr.remove() parent.remove()
def name_import_replacement(name, attr): children = [Name("import")] for c in all_candidates(name.value, attr.value): children.append(Name(c, prefix=" ")) children.append(Comma()) children.pop() replacement = Node(syms.import_name, children) return replacement
def handle_name(name, prefix): if name.type == syms.import_as_name: kids = [ Name(name.children[0].value, prefix=prefix), name.children[1].clone(), name.children[2].clone(), ] return [Node(syms.import_as_name, kids)] return [Name(name.value, prefix=prefix)]
def transform(self, node, results): sys_attr = results["attribute"][0] index = Number(self.exc_info.index(sys_attr.value)) call = Call(Name("exc_info"), prefix=sys_attr.prefix) attr = Attr(Name("sys"), call) attr[1].children[0].prefix = results["dot"].prefix attr.append(Subscript(index)) return Node(syms.power, attr, prefix=node.prefix)
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()]))
def transform_isinstance(self, node, results): x = results["x"].clone() # The thing inside of type() T = results["T"].clone() # The type being compared against x.prefix = "" T.prefix = " " test = Call(Name("isinstance"), [x, Comma(), T]) if "n" in results: test.prefix = " " test = Node(syms.not_test, [Name("not"), test]) test.prefix = node.prefix return test
def transform_range(self, node, results): if id( node ) not in self.transformed_xranges and not self.in_special_context( node): range_call = Call(Name("range"), [results["args"].clone()]) # Encase the range call in list(). list_call = Call(Name("list"), [range_call], prefix=node.prefix) # Put things that were after the range() call after the list call. for n in results["rest"]: list_call.append_child(n) return list_call
def insert_args(name, class_name, rparen): parent = rparen.parent if class_name: class_node = Node(syms.power, [Name(class_name)]) else: class_node = Node(syms.power, [Name(name), dot_class.clone()]) idx = parent.children.index(rparen) parent.insert_child(idx, Name(name, prefix=" ")) parent.insert_child(idx, Comma()) parent.insert_child(idx, class_node)
def transform(self, node, results): syms = self.syms exc = results["exc"].clone() if exc.type == token.STRING: msg = "Python 3 does not support string exceptions" self.cannot_convert(node, msg) return # Python 2 supports # raise ((((E1, E2), E3), E4), E5), V # as a synonym for # raise E1, V # Since Python 3 will not support this, we recurse down any tuple # literals, always taking the first element. if is_tuple(exc): while is_tuple(exc): # exc.children[1:-1] is the unparenthesized tuple # exc.children[1].children[0] is the first element of the tuple exc = exc.children[1].children[0].clone() exc.prefix = " " if "val" not in results: # One-argument raise new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) new.prefix = node.prefix return new val = results["val"].clone() if is_tuple(val): args = [c.clone() for c in val.children[1:-1]] else: val.prefix = "" args = [val] if "tb" in results: tb = results["tb"].clone() tb.prefix = "" e = exc # If there's a traceback and None is passed as the value, then don't # add a call, since the user probably just wants to add a # traceback. See issue #9661. if val.type != token.NAME or val.value != "None": e = Call(exc, args) with_tb = Attr(e, Name("with_traceback")) + [ArgList([tb])] new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb) new.prefix = node.prefix return new else: return pytree.Node(syms.raise_stmt, [Name("raise"), Call(exc, args)], prefix=node.prefix)
def transform(self, node, results): assert results syms = self.syms if node.parent.type == syms.not_test and self.pattern.match( node.parent): # Don't transform a node matching the first alternative of the # pattern when its parent matches the second alternative return None negation = results.get("negation") anchor = results["anchor"] prefix = node.prefix before = [n.clone() for n in results["before"]] arg = results["arg"].clone() after = results.get("after") if after: after = [n.clone() for n in after] if arg.type in ( syms.comparison, syms.not_test, syms.and_test, syms.or_test, syms.test, syms.lambdef, syms.argument, ): arg = parenthesize(arg) if len(before) == 1: before = before[0] else: before = pytree.Node(syms.power, before) before.prefix = " " n_op = Name("in", prefix=" ") if negation: n_not = Name("not", prefix=" ") n_op = pytree.Node(syms.comp_op, (n_not, n_op)) new = pytree.Node(syms.comparison, (arg, n_op, before)) if after: new = parenthesize(new) new = pytree.Node(syms.power, (new, ) + tuple(after)) if node.parent.type in ( syms.comparison, syms.expr, syms.xor_expr, syms.and_expr, syms.shift_expr, syms.arith_expr, syms.term, syms.factor, syms.power, ): new = parenthesize(new) new.prefix = prefix return new
def transform(self, node, results): assert results base = results.get("base") attr = results.get("attr") head = results.get("head") arg_ = results.get("arg") if arg_: arg = arg_.clone() head.replace(Attr(Name(str(arg), prefix=head.prefix), Name("next"))) arg_.remove() elif base: attr.replace(Name("next", prefix=attr.prefix))
def transform(self, node, results): if self.should_skip(node): return trailers = [] if "extra_trailers" in results: for t in results["extra_trailers"]: trailers.append(t.clone()) if node.parent.type == syms.simple_stmt: self.warning(node, "You should use a for loop here") new = node.clone() new.prefix = "" new = Call(Name("list"), [new]) elif "map_lambda" in results: new = ListComp(results["xp"].clone(), results["fp"].clone(), results["it"].clone()) new = Node(syms.power, [new] + trailers, prefix="") else: if "map_none" in results: new = results["arg"].clone() new.prefix = "" else: if "args" in results: args = results["args"] if (args.type == syms.trailer and args.children[1].type == syms.arglist and args.children[1].children[0].type == token.NAME and args.children[1].children[0].value == "None"): self.warning( node, "cannot convert map(None, ...) " "with multiple arguments because map() " "now truncates to the shortest sequence", ) return new = Node(syms.power, [Name("map"), args.clone()]) new.prefix = "" if in_special_context(node): return None new = Node(syms.power, [Name("list"), ArgList([new])] + trailers) new.prefix = "" new.prefix = node.prefix return new
def transform_import(self, node, results): """Transform for the basic import case. Replaces the old import name with a comma separated list of its replacements. """ import_mod = results.get("module") pref = import_mod.prefix names = [] # create a Node list of the replacement modules for name in MAPPING[import_mod.value][:-1]: names.extend([Name(name[0], prefix=pref), Comma()]) names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref)) import_mod.replace(names)
def transform(self, node, results): no_call = results.get("no_call") if no_call: no_call.replace(Name("__iter__", prefix=no_call.prefix)) else: node.replace([x.clone() for x in results["call"]])
def transform(self, node, results): syms = self.syms exc = results["exc"].clone() if exc.type is token.STRING: self.cannot_convert(node, "Python 3 does not support string exceptions") return # Leave "g.throw(E)" alone val = results.get("val") if val is None: return val = val.clone() if is_tuple(val): args = [c.clone() for c in val.children[1:-1]] else: val.prefix = "" args = [val] throw_args = results["args"] if "tb" in results: tb = results["tb"].clone() tb.prefix = "" e = Call(exc, args) with_tb = Attr(e, Name("with_traceback")) + [ArgList([tb])] throw_args.replace(pytree.Node(syms.power, with_tb)) else: throw_args.replace(Call(exc, args))
def transform(self, node, results): syms = self.syms tail = [n.clone() for n in results["tail"]] try_cleanup = [ch.clone() for ch in results["cleanup"]] for except_clause, e_suite in find_excepts(try_cleanup): if len(except_clause.children) == 4: (E, comma, N) = except_clause.children[1:4] comma.replace(Name("as", prefix=" ")) if N.type != token.NAME: # Generate a new N for the except clause new_N = Name(self.new_name(), prefix=" ") target = N.clone() target.prefix = "" N.replace(new_N) new_N = new_N.clone() # Insert "old_N = new_N" as the first statement in # the except body. This loop skips leading whitespace # and indents # TODO(cwinter) suite-cleanup suite_stmts = e_suite.children for i, stmt in enumerate(suite_stmts): if isinstance(stmt, pytree.Node): break # The assignment is different if old_N is a tuple or list # In that case, the assignment is old_N = new_N.args if is_tuple(N) or is_list(N): assign = Assign(target, Attr(new_N, Name("args"))) else: assign = Assign(target, new_N) # TODO(cwinter) stopgap until children becomes a smart list for child in reversed(suite_stmts[:i]): e_suite.insert_child(0, child) e_suite.insert_child(i, assign) elif N.prefix == "": # No space after a comma is legal; no space after "as", # not so much. N.prefix = " " # TODO(cwinter) fix this when children becomes a smart list children = [c.clone() for c in node.children[:3]] + try_cleanup + tail return pytree.Node(node.type, children)
def transform(self, node, results): # If we're already wrapped in an eval() call, we're done. if context.match(node.parent.parent): return new = node.clone() new.prefix = "" return Call(Name("eval"), [new], prefix=node.prefix)
def transform(self, node, results): collections = results["collections"] name = results["name"][0] collections.replace(Name(name.value, prefix=collections.prefix)) if node.type == syms.power: touch_import(None, name.value, node)
def fix_submod_import(self, imported, name, node): """ Accepts a list of NAME leafs, a name string, and a node node is given as an argument to BaseFix.transform() NAME leafs come from an import_as_names node (the children) name string is the base name found in node. """ submods = [] missed = [] for attr in imported: dotted = ".".join((name, attr.value)) if dotted in MAPPING: # get the replacement module to_repl = MAPPING[dotted] if "." not in to_repl: # it's a simple name, so use a simple replacement. _import = NameImport(Name(to_repl, prefix=" "), attr.value) submods.append(_import) elif attr.type == token.NAME: missed.append(attr.clone()) if not submods: return parent = node.parent node.replace(submods[0]) if len(submods) > 1: start = submods.pop(0) prev = start for submod in submods: parent.append_child(submod) if missed: self.warning( node, "Imported names not known to crosswind to be part of the package %s. Leaving those alone... high probability that this code will be incorrect." % (name), ) children = [ Name("from"), Name(name, prefix=" "), Name("import", prefix=" "), Node(syms.import_as_names, missed), ] orig_stripped = Node(syms.import_from, children) parent.append_child(Newline()) parent.append_child(orig_stripped)
def transform(self, node, results): if "paren" in results: paren = results["paren"] idx = node.children.index(paren) node.insert_child(idx + 1, Name("object")) else: colon = results["colon"] idx = node.children.index(colon) insert_object(node, idx)
def transform(self, node, results): mod_name = results.get("module_name") attr_name = results.get("attr_name") # bare_name = results.get("bare_name") # import_mod = results.get("module") if mod_name and attr_name: new_attr = LOOKUP[(mod_name.value, attr_name.value)] attr_name.replace(Name(new_attr, prefix=attr_name.prefix))
def _Call(self, name, args=None, prefix=None): """Help the next test""" children = [] if isinstance(args, list): for arg in args: children.append(arg) children.append(Comma()) children.pop() return Call(Name(name), children, prefix)
def add_kwarg(self, l_nodes, s_kwd, n_expr): # XXX All this prefix-setting may lose comments (though rarely) n_expr.prefix = "" n_argument = pytree.Node( self.syms.argument, (Name(s_kwd), pytree.Leaf(token.EQUAL, "="), n_expr)) if l_nodes: l_nodes.append(Comma()) n_argument.prefix = " " l_nodes.append(n_argument)
def transform(self, node, results): if "name" in results: name = results["name"] name.replace(Name("getcwdu", prefix=name.prefix)) elif "bad" in results: # Can't convert to getcwdu and then expect to catch every use. self.cannot_convert(node, "import os, use os.getcwd() instead.") return else: raise ValueError("For some reason, the pattern matcher failed.")
def transform(self, node, results): if self.should_skip(node): return if in_special_context(node): return None args = results["args"].clone() args.prefix = "" trailers = [] if "trailers" in results: trailers = [n.clone() for n in results["trailers"]] for n in trailers: n.prefix = "" new = Node(syms.power, [Name("zip"), args], prefix="") new = Node(syms.power, [Name("list"), ArgList([new])] + trailers) new.prefix = node.prefix return new
def transform(self, node, results): arg_list = results.get("args") if node.type == syms.import_name: new = BlankLine() return new elif arg_list: args = arg_list[0] args = args.clone() prefix = node.prefix return Node(syms.power, [Name("reload"), args], prefix=prefix)