123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- # 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 .. import fixer_base
- from ..fixer_util import Name, parenthesize
- class FixHasKey(fixer_base.BaseFix):
- BM_compatible = True
- 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.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 = parenthesize(arg)
- if len(before) == 1:
- before = before[0]
- else:
- before = pytree.Node(syms.power, before)
- before.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 = 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 = parenthesize(new)
- new.prefix = prefix
- return new
|