]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.2/Lib/lib2to3/fixes/fix_next.py
AppPkg/Applications/Python: Add Python 2.7.2 sources since the release of Python...
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / lib2to3 / fixes / fix_next.py
diff --git a/AppPkg/Applications/Python/Python-2.7.2/Lib/lib2to3/fixes/fix_next.py b/AppPkg/Applications/Python/Python-2.7.2/Lib/lib2to3/fixes/fix_next.py
new file mode 100644 (file)
index 0000000..bd0cfe9
--- /dev/null
@@ -0,0 +1,103 @@
+"""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