diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-03-19 04:43:46 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-03-19 04:43:46 (GMT) |
commit | 5e37baea8007cb64b65a180e4d6c80de292a8a4a (patch) | |
tree | af8b06bfe03af755de5bf83e9aa01f299186a8f7 /Lib/lib2to3/fixes/fix_has_key.py | |
parent | a4d77898db3856cd3d8c9411d024bea88be25b66 (diff) | |
download | cpython-5e37baea8007cb64b65a180e4d6c80de292a8a4a.zip cpython-5e37baea8007cb64b65a180e4d6c80de292a8a4a.tar.gz cpython-5e37baea8007cb64b65a180e4d6c80de292a8a4a.tar.bz2 |
Import lib2to3.
Diffstat (limited to 'Lib/lib2to3/fixes/fix_has_key.py')
-rw-r--r-- | Lib/lib2to3/fixes/fix_has_key.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/Lib/lib2to3/fixes/fix_has_key.py b/Lib/lib2to3/fixes/fix_has_key.py new file mode 100644 index 0000000..ea7bfc5 --- /dev/null +++ b/Lib/lib2to3/fixes/fix_has_key.py @@ -0,0 +1,109 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for has_key(). + +Calls to .has_key() methods are expressed in terms of the 'in' +operator: + + d.has_key(k) -> k in d + +CAVEATS: +1) While the primary target of this fixer is dict.has_key(), the + fixer will change any has_key() method call, regardless of its + class. + +2) Cases like this will not be converted: + + m = d.has_key + if m(k): + ... + + Only *calls* to has_key() are converted. While it is possible to + convert the above to something like + + m = d.__contains__ + if m(k): + ... + + this is currently not done. +""" + +# Local imports +from .. import pytree +from ..pgen2 import token +from . import basefix +from .util import Name + + +class FixHasKey(basefix.BaseFix): + + PATTERN = """ + anchor=power< + before=any+ + trailer< '.' 'has_key' > + trailer< + '(' + ( not(arglist | argument<any '=' any>) arg=any + | arglist<(not argument<any '=' any>) arg=any ','> + ) + ')' + > + after=any* + > + | + negation=not_test< + 'not' + anchor=power< + before=any+ + trailer< '.' 'has_key' > + trailer< + '(' + ( not(arglist | argument<any '=' any>) arg=any + | arglist<(not argument<any '=' any>) arg=any ','> + ) + ')' + > + > + > + """ + + def transform(self, node, results): + assert results + syms = self.syms + if (node.parent.type == syms.not_test and + self.pattern.match(node.parent)): + # Don't transform a node matching the first alternative of the + # pattern when its parent matches the second alternative + return None + negation = results.get("negation") + anchor = results["anchor"] + prefix = node.get_prefix() + before = [n.clone() for n in results["before"]] + arg = results["arg"].clone() + after = results.get("after") + if after: + after = [n.clone() for n in after] + if arg.type in (syms.comparison, syms.not_test, syms.and_test, + syms.or_test, syms.test, syms.lambdef, syms.argument): + arg = self.parenthesize(arg) + if len(before) == 1: + before = before[0] + else: + before = pytree.Node(syms.power, before) + before.set_prefix(" ") + n_op = Name("in", prefix=" ") + if negation: + n_not = Name("not", prefix=" ") + n_op = pytree.Node(syms.comp_op, (n_not, n_op)) + new = pytree.Node(syms.comparison, (arg, n_op, before)) + if after: + new = self.parenthesize(new) + new = pytree.Node(syms.power, (new,) + tuple(after)) + if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr, + syms.and_expr, syms.shift_expr, + syms.arith_expr, syms.term, + syms.factor, syms.power): + new = self.parenthesize(new) + new.set_prefix(prefix) + return new |