home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 June / maximum-cd-2011-06.iso / DiscContents / LibO_3.3.1_Win_x86_install_multi.exe / libreoffice1.cab / fix_dict.py < prev    next >
Encoding:
Python Source  |  2011-02-15  |  3.5 KB  |  100 lines

  1. # Copyright 2007 Google, Inc. All Rights Reserved.
  2. # Licensed to PSF under a Contributor Agreement.
  3.  
  4. """Fixer for dict methods.
  5.  
  6. d.keys() -> list(d.keys())
  7. d.items() -> list(d.items())
  8. d.values() -> list(d.values())
  9.  
  10. d.iterkeys() -> iter(d.keys())
  11. d.iteritems() -> iter(d.items())
  12. d.itervalues() -> iter(d.values())
  13.  
  14. Except in certain very specific contexts: the iter() can be dropped
  15. when the context is list(), sorted(), iter() or for...in; the list()
  16. can be dropped when the context is list() or sorted() (but not iter()
  17. or for...in!). Special contexts that apply to both: list(), sorted(), tuple()
  18. set(), any(), all(), sum().
  19.  
  20. Note: iter(d.keys()) could be written as iter(d) but since the
  21. original d.iterkeys() was also redundant we don't fix this.  And there
  22. are (rare) contexts where it makes a difference (e.g. when passing it
  23. as an argument to a function that introspects the argument).
  24. """
  25.  
  26. # Local imports
  27. from .. import pytree
  28. from .. import patcomp
  29. from ..pgen2 import token
  30. from .. import fixer_base
  31. from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot
  32. from .. import fixer_util
  33.  
  34.  
  35. iter_exempt = fixer_util.consuming_calls | set(["iter"])
  36.  
  37.  
  38. class FixDict(fixer_base.BaseFix):
  39.     PATTERN = """
  40.     power< head=any+
  41.          trailer< '.' method=('keys'|'items'|'values'|
  42.                               'iterkeys'|'iteritems'|'itervalues') >
  43.          parens=trailer< '(' ')' >
  44.          tail=any*
  45.     >
  46.     """
  47.  
  48.     def transform(self, node, results):
  49.         head = results["head"]
  50.         method = results["method"][0] # Extract node for method name
  51.         tail = results["tail"]
  52.         syms = self.syms
  53.         method_name = method.value
  54.         isiter = method_name.startswith("iter")
  55.         if isiter:
  56.             method_name = method_name[4:]
  57.         assert method_name in ("keys", "items", "values"), repr(method)
  58.         head = [n.clone() for n in head]
  59.         tail = [n.clone() for n in tail]
  60.         special = not tail and self.in_special_context(node, isiter)
  61.         args = head + [pytree.Node(syms.trailer,
  62.                                    [Dot(),
  63.                                     Name(method_name,
  64.                                          prefix=method.get_prefix())]),
  65.                        results["parens"].clone()]
  66.         new = pytree.Node(syms.power, args)
  67.         if not special:
  68.             new.set_prefix("")
  69.             new = Call(Name(isiter and "iter" or "list"), [new])
  70.         if tail:
  71.             new = pytree.Node(syms.power, [new] + tail)
  72.         new.set_prefix(node.get_prefix())
  73.         return new
  74.  
  75.     P1 = "power< func=NAME trailer< '(' node=any ')' > any* >"
  76.     p1 = patcomp.compile_pattern(P1)
  77.  
  78.     P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
  79.             | comp_for< 'for' any 'in' node=any any* >
  80.          """
  81.     p2 = patcomp.compile_pattern(P2)
  82.  
  83.     def in_special_context(self, node, isiter):
  84.         if node.parent is None:
  85.             return False
  86.         results = {}
  87.         if (node.parent.parent is not None and
  88.                self.p1.match(node.parent.parent, results) and
  89.                results["node"] is node):
  90.             if isiter:
  91.                 # iter(d.iterkeys()) -> iter(d.keys()), etc.
  92.                 return results["func"].value in iter_exempt
  93.             else:
  94.                 # list(d.keys()) -> list(d.keys()), etc.
  95.                 return results["func"].value in fixer_util.consuming_calls
  96.         if not isiter:
  97.             return False
  98.         # for ... in d.iterkeys() -> for ... in d.keys(), etc.
  99.         return self.p2.match(node.parent, results) and results["node"] is node
  100.