symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/lib2to3/fixes/fix_next.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Fixer for it.next() -> next(it), per PEP 3114."""
       
     2 # Author: Collin Winter
       
     3 
       
     4 # Things that currently aren't covered:
       
     5 #   - listcomp "next" names aren't warned
       
     6 #   - "with" statement targets aren't checked
       
     7 
       
     8 # Local imports
       
     9 from ..pgen2 import token
       
    10 from ..pygram import python_symbols as syms
       
    11 from .. import fixer_base
       
    12 from ..fixer_util import Name, Call, find_binding
       
    13 
       
    14 bind_warning = "Calls to builtin next() possibly shadowed by global binding"
       
    15 
       
    16 
       
    17 class FixNext(fixer_base.BaseFix):
       
    18     PATTERN = """
       
    19     power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > >
       
    20     |
       
    21     power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > >
       
    22     |
       
    23     classdef< 'class' any+ ':'
       
    24               suite< any*
       
    25                      funcdef< 'def'
       
    26                               name='next'
       
    27                               parameters< '(' NAME ')' > any+ >
       
    28                      any* > >
       
    29     |
       
    30     global=global_stmt< 'global' any* 'next' any* >
       
    31     """
       
    32 
       
    33     order = "pre" # Pre-order tree traversal
       
    34 
       
    35     def start_tree(self, tree, filename):
       
    36         super(FixNext, self).start_tree(tree, filename)
       
    37 
       
    38         n = find_binding('next', tree)
       
    39         if n:
       
    40             self.warning(n, bind_warning)
       
    41             self.shadowed_next = True
       
    42         else:
       
    43             self.shadowed_next = False
       
    44 
       
    45     def transform(self, node, results):
       
    46         assert results
       
    47 
       
    48         base = results.get("base")
       
    49         attr = results.get("attr")
       
    50         name = results.get("name")
       
    51         mod = results.get("mod")
       
    52 
       
    53         if base:
       
    54             if self.shadowed_next:
       
    55                 attr.replace(Name("__next__", prefix=attr.get_prefix()))
       
    56             else:
       
    57                 base = [n.clone() for n in base]
       
    58                 base[0].set_prefix("")
       
    59                 node.replace(Call(Name("next", prefix=node.get_prefix()), base))
       
    60         elif name:
       
    61             n = Name("__next__", prefix=name.get_prefix())
       
    62             name.replace(n)
       
    63         elif attr:
       
    64             # We don't do this transformation if we're assigning to "x.next".
       
    65             # Unfortunately, it doesn't seem possible to do this in PATTERN,
       
    66             #  so it's being done here.
       
    67             if is_assign_target(node):
       
    68                 head = results["head"]
       
    69                 if "".join([str(n) for n in head]).strip() == '__builtin__':
       
    70                     self.warning(node, bind_warning)
       
    71                 return
       
    72             attr.replace(Name("__next__"))
       
    73         elif "global" in results:
       
    74             self.warning(node, bind_warning)
       
    75             self.shadowed_next = True
       
    76 
       
    77 
       
    78 ### The following functions help test if node is part of an assignment
       
    79 ###  target.
       
    80 
       
    81 def is_assign_target(node):
       
    82     assign = find_assign(node)
       
    83     if assign is None:
       
    84         return False
       
    85 
       
    86     for child in assign.children:
       
    87         if child.type == token.EQUAL:
       
    88             return False
       
    89         elif is_subtree(child, node):
       
    90             return True
       
    91     return False
       
    92 
       
    93 def find_assign(node):
       
    94     if node.type == syms.expr_stmt:
       
    95         return node
       
    96     if node.type == syms.simple_stmt or node.parent is None:
       
    97         return None
       
    98     return find_assign(node.parent)
       
    99 
       
   100 def is_subtree(root, node):
       
   101     if root == node:
       
   102         return True
       
   103     return any([is_subtree(c, node) for c in root.children])