ยปCore Development>Code coverage>Lib/lib2to3/fixes/fix_has_key.py

# Python code coverage for Lib/lib2to3/fixes/fix_has_key.py

#countcontent
2n/a# Licensed to PSF under a Contributor Agreement.
3n/a
4n/a"""Fixer for has_key().
5n/a
6n/aCalls to .has_key() methods are expressed in terms of the 'in'
7n/aoperator:
8n/a
9n/a d.has_key(k) -> k in d
10n/a
11n/aCAVEATS:
12n/a1) While the primary target of this fixer is dict.has_key(), the
13n/a fixer will change any has_key() method call, regardless of its
14n/a class.
15n/a
16n/a2) Cases like this will not be converted:
17n/a
18n/a m = d.has_key
19n/a if m(k):
20n/a ...
21n/a
22n/a Only *calls* to has_key() are converted. While it is possible to
23n/a convert the above to something like
24n/a
25n/a m = d.__contains__
26n/a if m(k):
27n/a ...
28n/a
29n/a this is currently not done.
30n/a"""
31n/a
32n/a# Local imports
33n/afrom .. import pytree
34n/afrom .. import fixer_base
35n/afrom ..fixer_util import Name, parenthesize
36n/a
37n/a
39n/a BM_compatible = True
40n/a
41n/a PATTERN = """
42n/a anchor=power<
43n/a before=any+
44n/a trailer< '.' 'has_key' >
45n/a trailer<
46n/a '('
47n/a ( not(arglist | argument<any '=' any>) arg=any
48n/a | arglist<(not argument<any '=' any>) arg=any ','>
49n/a )
50n/a ')'
51n/a >
52n/a after=any*
53n/a >
54n/a |
55n/a negation=not_test<
56n/a 'not'
57n/a anchor=power<
58n/a before=any+
59n/a trailer< '.' 'has_key' >
60n/a trailer<
61n/a '('
62n/a ( not(arglist | argument<any '=' any>) arg=any
63n/a | arglist<(not argument<any '=' any>) arg=any ','>
64n/a )
65n/a ')'
66n/a >
67n/a >
68n/a >
69n/a """
70n/a
71n/a def transform(self, node, results):
72n/a assert results
73n/a syms = self.syms
74n/a if (node.parent.type == syms.not_test and
75n/a self.pattern.match(node.parent)):
76n/a # Don't transform a node matching the first alternative of the
77n/a # pattern when its parent matches the second alternative
78n/a return None
79n/a negation = results.get("negation")
80n/a anchor = results["anchor"]
81n/a prefix = node.prefix
82n/a before = [n.clone() for n in results["before"]]
83n/a arg = results["arg"].clone()
84n/a after = results.get("after")
85n/a if after:
86n/a after = [n.clone() for n in after]
87n/a if arg.type in (syms.comparison, syms.not_test, syms.and_test,
88n/a syms.or_test, syms.test, syms.lambdef, syms.argument):
89n/a arg = parenthesize(arg)
90n/a if len(before) == 1:
91n/a before = before[0]
92n/a else:
93n/a before = pytree.Node(syms.power, before)
94n/a before.prefix = " "
95n/a n_op = Name("in", prefix=" ")
96n/a if negation:
97n/a n_not = Name("not", prefix=" ")
98n/a n_op = pytree.Node(syms.comp_op, (n_not, n_op))
99n/a new = pytree.Node(syms.comparison, (arg, n_op, before))
100n/a if after:
101n/a new = parenthesize(new)
102n/a new = pytree.Node(syms.power, (new,) + tuple(after))
103n/a if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr,
104n/a syms.and_expr, syms.shift_expr,
105n/a syms.arith_expr, syms.term,
106n/a syms.factor, syms.power):
107n/a new = parenthesize(new)
108n/a new.prefix = prefix
109n/a return new