Home | History | Annotate | Download | only in fixes
      1 # Copyright 2007 Google, Inc. All Rights Reserved.

      2 # Licensed to PSF under a Contributor Agreement.

      3 
      4 """Fixer that changes filter(F, X) into list(filter(F, X)).
      5 
      6 We avoid the transformation if the filter() call is directly contained
      7 in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or
      8 for V in <>:.
      9 
     10 NOTE: This is still not correct if the original code was depending on
     11 filter(F, X) to return a string if X is a string and a tuple if X is a
     12 tuple.  That would require type inference, which we don't do.  Let
     13 Python 2.6 figure it out.
     14 """
     15 
     16 # Local imports

     17 from ..pgen2 import token
     18 from .. import fixer_base
     19 from ..fixer_util import Name, Call, ListComp, in_special_context
     20 
     21 class FixFilter(fixer_base.ConditionalFix):
     22     BM_compatible = True
     23 
     24     PATTERN = """
     25     filter_lambda=power<
     26         'filter'
     27         trailer<
     28             '('
     29             arglist<
     30                 lambdef< 'lambda'
     31                          (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any
     32                 >
     33                 ','
     34                 it=any
     35             >
     36             ')'
     37         >
     38     >
     39     |
     40     power<
     41         'filter'
     42         trailer< '(' arglist< none='None' ',' seq=any > ')' >
     43     >
     44     |
     45     power<
     46         'filter'
     47         args=trailer< '(' [any] ')' >
     48     >
     49     """
     50 
     51     skip_on = "future_builtins.filter"
     52 
     53     def transform(self, node, results):
     54         if self.should_skip(node):
     55             return
     56 
     57         if "filter_lambda" in results:
     58             new = ListComp(results.get("fp").clone(),
     59                            results.get("fp").clone(),
     60                            results.get("it").clone(),
     61                            results.get("xp").clone())
     62 
     63         elif "none" in results:
     64             new = ListComp(Name(u"_f"),
     65                            Name(u"_f"),
     66                            results["seq"].clone(),
     67                            Name(u"_f"))
     68 
     69         else:
     70             if in_special_context(node):
     71                 return None
     72             new = node.clone()
     73             new.prefix = u""
     74             new = Call(Name(u"list"), [new])
     75         new.prefix = node.prefix
     76         return new
     77