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