+++ /dev/null
-"""Fixer for it.next() -> next(it), per PEP 3114."""\r
-# Author: Collin Winter\r
-\r
-# Things that currently aren't covered:\r
-# - listcomp "next" names aren't warned\r
-# - "with" statement targets aren't checked\r
-\r
-# Local imports\r
-from ..pgen2 import token\r
-from ..pygram import python_symbols as syms\r
-from .. import fixer_base\r
-from ..fixer_util import Name, Call, find_binding\r
-\r
-bind_warning = "Calls to builtin next() possibly shadowed by global binding"\r
-\r
-\r
-class FixNext(fixer_base.BaseFix):\r
- BM_compatible = True\r
- PATTERN = """\r
- power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > >\r
- |\r
- power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > >\r
- |\r
- classdef< 'class' any+ ':'\r
- suite< any*\r
- funcdef< 'def'\r
- name='next'\r
- parameters< '(' NAME ')' > any+ >\r
- any* > >\r
- |\r
- global=global_stmt< 'global' any* 'next' any* >\r
- """\r
-\r
- order = "pre" # Pre-order tree traversal\r
-\r
- def start_tree(self, tree, filename):\r
- super(FixNext, self).start_tree(tree, filename)\r
-\r
- n = find_binding(u'next', tree)\r
- if n:\r
- self.warning(n, bind_warning)\r
- self.shadowed_next = True\r
- else:\r
- self.shadowed_next = False\r
-\r
- def transform(self, node, results):\r
- assert results\r
-\r
- base = results.get("base")\r
- attr = results.get("attr")\r
- name = results.get("name")\r
-\r
- if base:\r
- if self.shadowed_next:\r
- attr.replace(Name(u"__next__", prefix=attr.prefix))\r
- else:\r
- base = [n.clone() for n in base]\r
- base[0].prefix = u""\r
- node.replace(Call(Name(u"next", prefix=node.prefix), base))\r
- elif name:\r
- n = Name(u"__next__", prefix=name.prefix)\r
- name.replace(n)\r
- elif attr:\r
- # We don't do this transformation if we're assigning to "x.next".\r
- # Unfortunately, it doesn't seem possible to do this in PATTERN,\r
- # so it's being done here.\r
- if is_assign_target(node):\r
- head = results["head"]\r
- if "".join([str(n) for n in head]).strip() == u'__builtin__':\r
- self.warning(node, bind_warning)\r
- return\r
- attr.replace(Name(u"__next__"))\r
- elif "global" in results:\r
- self.warning(node, bind_warning)\r
- self.shadowed_next = True\r
-\r
-\r
-### The following functions help test if node is part of an assignment\r
-### target.\r
-\r
-def is_assign_target(node):\r
- assign = find_assign(node)\r
- if assign is None:\r
- return False\r
-\r
- for child in assign.children:\r
- if child.type == token.EQUAL:\r
- return False\r
- elif is_subtree(child, node):\r
- return True\r
- return False\r
-\r
-def find_assign(node):\r
- if node.type == syms.expr_stmt:\r
- return node\r
- if node.type == syms.simple_stmt or node.parent is None:\r
- return None\r
- return find_assign(node.parent)\r
-\r
-def is_subtree(root, node):\r
- if root == node:\r
- return True\r
- return any(is_subtree(c, node) for c in root.children)\r