ยปCore Development>Code coverage>Lib/test/test_metaclass.py

Python code coverage for Lib/test/test_metaclass.py

#countcontent
1n/adoctests = """
2n/a
3n/aBasic class construction.
4n/a
5n/a >>> class C:
6n/a ... def meth(self): print("Hello")
7n/a ...
8n/a >>> C.__class__ is type
9n/a True
10n/a >>> a = C()
11n/a >>> a.__class__ is C
12n/a True
13n/a >>> a.meth()
14n/a Hello
15n/a >>>
16n/a
17n/aUse *args notation for the bases.
18n/a
19n/a >>> class A: pass
20n/a >>> class B: pass
21n/a >>> bases = (A, B)
22n/a >>> class C(*bases): pass
23n/a >>> C.__bases__ == bases
24n/a True
25n/a >>>
26n/a
27n/aUse a trivial metaclass.
28n/a
29n/a >>> class M(type):
30n/a ... pass
31n/a ...
32n/a >>> class C(metaclass=M):
33n/a ... def meth(self): print("Hello")
34n/a ...
35n/a >>> C.__class__ is M
36n/a True
37n/a >>> a = C()
38n/a >>> a.__class__ is C
39n/a True
40n/a >>> a.meth()
41n/a Hello
42n/a >>>
43n/a
44n/aUse **kwds notation for the metaclass keyword.
45n/a
46n/a >>> kwds = {'metaclass': M}
47n/a >>> class C(**kwds): pass
48n/a ...
49n/a >>> C.__class__ is M
50n/a True
51n/a >>> a = C()
52n/a >>> a.__class__ is C
53n/a True
54n/a >>>
55n/a
56n/aUse a metaclass with a __prepare__ static method.
57n/a
58n/a >>> class M(type):
59n/a ... @staticmethod
60n/a ... def __prepare__(*args, **kwds):
61n/a ... print("Prepare called:", args, kwds)
62n/a ... return dict()
63n/a ... def __new__(cls, name, bases, namespace, **kwds):
64n/a ... print("New called:", kwds)
65n/a ... return type.__new__(cls, name, bases, namespace)
66n/a ... def __init__(cls, *args, **kwds):
67n/a ... pass
68n/a ...
69n/a >>> class C(metaclass=M):
70n/a ... def meth(self): print("Hello")
71n/a ...
72n/a Prepare called: ('C', ()) {}
73n/a New called: {}
74n/a >>>
75n/a
76n/aAlso pass another keyword.
77n/a
78n/a >>> class C(object, metaclass=M, other="haha"):
79n/a ... pass
80n/a ...
81n/a Prepare called: ('C', (<class 'object'>,)) {'other': 'haha'}
82n/a New called: {'other': 'haha'}
83n/a >>> C.__class__ is M
84n/a True
85n/a >>> C.__bases__ == (object,)
86n/a True
87n/a >>> a = C()
88n/a >>> a.__class__ is C
89n/a True
90n/a >>>
91n/a
92n/aCheck that build_class doesn't mutate the kwds dict.
93n/a
94n/a >>> kwds = {'metaclass': type}
95n/a >>> class C(**kwds): pass
96n/a ...
97n/a >>> kwds == {'metaclass': type}
98n/a True
99n/a >>>
100n/a
101n/aUse various combinations of explicit keywords and **kwds.
102n/a
103n/a >>> bases = (object,)
104n/a >>> kwds = {'metaclass': M, 'other': 'haha'}
105n/a >>> class C(*bases, **kwds): pass
106n/a ...
107n/a Prepare called: ('C', (<class 'object'>,)) {'other': 'haha'}
108n/a New called: {'other': 'haha'}
109n/a >>> C.__class__ is M
110n/a True
111n/a >>> C.__bases__ == (object,)
112n/a True
113n/a >>> class B: pass
114n/a >>> kwds = {'other': 'haha'}
115n/a >>> class C(B, metaclass=M, *bases, **kwds): pass
116n/a ...
117n/a Prepare called: ('C', (<class 'test.test_metaclass.B'>, <class 'object'>)) {'other': 'haha'}
118n/a New called: {'other': 'haha'}
119n/a >>> C.__class__ is M
120n/a True
121n/a >>> C.__bases__ == (B, object)
122n/a True
123n/a >>>
124n/a
125n/aCheck for duplicate keywords.
126n/a
127n/a >>> class C(metaclass=type, metaclass=type): pass
128n/a ...
129n/a Traceback (most recent call last):
130n/a [...]
131n/a SyntaxError: keyword argument repeated
132n/a >>>
133n/a
134n/aAnother way.
135n/a
136n/a >>> kwds = {'metaclass': type}
137n/a >>> class C(metaclass=type, **kwds): pass
138n/a ...
139n/a Traceback (most recent call last):
140n/a [...]
141n/a TypeError: __build_class__() got multiple values for keyword argument 'metaclass'
142n/a >>>
143n/a
144n/aUse a __prepare__ method that returns an instrumented dict.
145n/a
146n/a >>> class LoggingDict(dict):
147n/a ... def __setitem__(self, key, value):
148n/a ... print("d[%r] = %r" % (key, value))
149n/a ... dict.__setitem__(self, key, value)
150n/a ...
151n/a >>> class Meta(type):
152n/a ... @staticmethod
153n/a ... def __prepare__(name, bases):
154n/a ... return LoggingDict()
155n/a ...
156n/a >>> class C(metaclass=Meta):
157n/a ... foo = 2+2
158n/a ... foo = 42
159n/a ... bar = 123
160n/a ...
161n/a d['__module__'] = 'test.test_metaclass'
162n/a d['__qualname__'] = 'C'
163n/a d['foo'] = 4
164n/a d['foo'] = 42
165n/a d['bar'] = 123
166n/a >>>
167n/a
168n/aUse a metaclass that doesn't derive from type.
169n/a
170n/a >>> def meta(name, bases, namespace, **kwds):
171n/a ... print("meta:", name, bases)
172n/a ... print("ns:", sorted(namespace.items()))
173n/a ... print("kw:", sorted(kwds.items()))
174n/a ... return namespace
175n/a ...
176n/a >>> class C(metaclass=meta):
177n/a ... a = 42
178n/a ... b = 24
179n/a ...
180n/a meta: C ()
181n/a ns: [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)]
182n/a kw: []
183n/a >>> type(C) is dict
184n/a True
185n/a >>> print(sorted(C.items()))
186n/a [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)]
187n/a >>>
188n/a
189n/aAnd again, with a __prepare__ attribute.
190n/a
191n/a >>> def prepare(name, bases, **kwds):
192n/a ... print("prepare:", name, bases, sorted(kwds.items()))
193n/a ... return LoggingDict()
194n/a ...
195n/a >>> meta.__prepare__ = prepare
196n/a >>> class C(metaclass=meta, other="booh"):
197n/a ... a = 1
198n/a ... a = 2
199n/a ... b = 3
200n/a ...
201n/a prepare: C () [('other', 'booh')]
202n/a d['__module__'] = 'test.test_metaclass'
203n/a d['__qualname__'] = 'C'
204n/a d['a'] = 1
205n/a d['a'] = 2
206n/a d['b'] = 3
207n/a meta: C ()
208n/a ns: [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 2), ('b', 3)]
209n/a kw: [('other', 'booh')]
210n/a >>>
211n/a
212n/aThe default metaclass must define a __prepare__() method.
213n/a
214n/a >>> type.__prepare__()
215n/a {}
216n/a >>>
217n/a
218n/aMake sure it works with subclassing.
219n/a
220n/a >>> class M(type):
221n/a ... @classmethod
222n/a ... def __prepare__(cls, *args, **kwds):
223n/a ... d = super().__prepare__(*args, **kwds)
224n/a ... d["hello"] = 42
225n/a ... return d
226n/a ...
227n/a >>> class C(metaclass=M):
228n/a ... print(hello)
229n/a ...
230n/a 42
231n/a >>> print(C.hello)
232n/a 42
233n/a >>>
234n/a
235n/aTest failures in looking up the __prepare__ method work.
236n/a >>> class ObscureException(Exception):
237n/a ... pass
238n/a >>> class FailDescr:
239n/a ... def __get__(self, instance, owner):
240n/a ... raise ObscureException
241n/a >>> class Meta(type):
242n/a ... __prepare__ = FailDescr()
243n/a >>> class X(metaclass=Meta):
244n/a ... pass
245n/a Traceback (most recent call last):
246n/a [...]
247n/a test.test_metaclass.ObscureException
248n/a
249n/a"""
250n/a
251n/aimport sys
252n/a
253n/a# Trace function introduces __locals__ which causes various tests to fail.
254n/aif hasattr(sys, 'gettrace') and sys.gettrace():
255n/a __test__ = {}
256n/aelse:
257n/a __test__ = {'doctests' : doctests}
258n/a
259n/adef test_main(verbose=False):
260n/a from test import support
261n/a from test import test_metaclass
262n/a support.run_doctest(test_metaclass, verbose)
263n/a
264n/aif __name__ == "__main__":
265n/a test_main(verbose=True)