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

Python code coverage for Lib/test/test_subclassinit.py

#countcontent
1n/aimport types
2n/aimport unittest
3n/a
4n/a
5n/aclass Test(unittest.TestCase):
6n/a def test_init_subclass(self):
7n/a class A:
8n/a initialized = False
9n/a
10n/a def __init_subclass__(cls):
11n/a super().__init_subclass__()
12n/a cls.initialized = True
13n/a
14n/a class B(A):
15n/a pass
16n/a
17n/a self.assertFalse(A.initialized)
18n/a self.assertTrue(B.initialized)
19n/a
20n/a def test_init_subclass_dict(self):
21n/a class A(dict):
22n/a initialized = False
23n/a
24n/a def __init_subclass__(cls):
25n/a super().__init_subclass__()
26n/a cls.initialized = True
27n/a
28n/a class B(A):
29n/a pass
30n/a
31n/a self.assertFalse(A.initialized)
32n/a self.assertTrue(B.initialized)
33n/a
34n/a def test_init_subclass_kwargs(self):
35n/a class A:
36n/a def __init_subclass__(cls, **kwargs):
37n/a cls.kwargs = kwargs
38n/a
39n/a class B(A, x=3):
40n/a pass
41n/a
42n/a self.assertEqual(B.kwargs, dict(x=3))
43n/a
44n/a def test_init_subclass_error(self):
45n/a class A:
46n/a def __init_subclass__(cls):
47n/a raise RuntimeError
48n/a
49n/a with self.assertRaises(RuntimeError):
50n/a class B(A):
51n/a pass
52n/a
53n/a def test_init_subclass_wrong(self):
54n/a class A:
55n/a def __init_subclass__(cls, whatever):
56n/a pass
57n/a
58n/a with self.assertRaises(TypeError):
59n/a class B(A):
60n/a pass
61n/a
62n/a def test_init_subclass_skipped(self):
63n/a class BaseWithInit:
64n/a def __init_subclass__(cls, **kwargs):
65n/a super().__init_subclass__(**kwargs)
66n/a cls.initialized = cls
67n/a
68n/a class BaseWithoutInit(BaseWithInit):
69n/a pass
70n/a
71n/a class A(BaseWithoutInit):
72n/a pass
73n/a
74n/a self.assertIs(A.initialized, A)
75n/a self.assertIs(BaseWithoutInit.initialized, BaseWithoutInit)
76n/a
77n/a def test_init_subclass_diamond(self):
78n/a class Base:
79n/a def __init_subclass__(cls, **kwargs):
80n/a super().__init_subclass__(**kwargs)
81n/a cls.calls = []
82n/a
83n/a class Left(Base):
84n/a pass
85n/a
86n/a class Middle:
87n/a def __init_subclass__(cls, middle, **kwargs):
88n/a super().__init_subclass__(**kwargs)
89n/a cls.calls += [middle]
90n/a
91n/a class Right(Base):
92n/a def __init_subclass__(cls, right="right", **kwargs):
93n/a super().__init_subclass__(**kwargs)
94n/a cls.calls += [right]
95n/a
96n/a class A(Left, Middle, Right, middle="middle"):
97n/a pass
98n/a
99n/a self.assertEqual(A.calls, ["right", "middle"])
100n/a self.assertEqual(Left.calls, [])
101n/a self.assertEqual(Right.calls, [])
102n/a
103n/a def test_set_name(self):
104n/a class Descriptor:
105n/a def __set_name__(self, owner, name):
106n/a self.owner = owner
107n/a self.name = name
108n/a
109n/a class A:
110n/a d = Descriptor()
111n/a
112n/a self.assertEqual(A.d.name, "d")
113n/a self.assertIs(A.d.owner, A)
114n/a
115n/a def test_set_name_metaclass(self):
116n/a class Meta(type):
117n/a def __new__(cls, name, bases, ns):
118n/a ret = super().__new__(cls, name, bases, ns)
119n/a self.assertEqual(ret.d.name, "d")
120n/a self.assertIs(ret.d.owner, ret)
121n/a return 0
122n/a
123n/a class Descriptor:
124n/a def __set_name__(self, owner, name):
125n/a self.owner = owner
126n/a self.name = name
127n/a
128n/a class A(metaclass=Meta):
129n/a d = Descriptor()
130n/a self.assertEqual(A, 0)
131n/a
132n/a def test_set_name_error(self):
133n/a class Descriptor:
134n/a def __set_name__(self, owner, name):
135n/a 1/0
136n/a
137n/a with self.assertRaises(RuntimeError) as cm:
138n/a class NotGoingToWork:
139n/a attr = Descriptor()
140n/a
141n/a exc = cm.exception
142n/a self.assertRegex(str(exc), r'\bNotGoingToWork\b')
143n/a self.assertRegex(str(exc), r'\battr\b')
144n/a self.assertRegex(str(exc), r'\bDescriptor\b')
145n/a self.assertIsInstance(exc.__cause__, ZeroDivisionError)
146n/a
147n/a def test_set_name_wrong(self):
148n/a class Descriptor:
149n/a def __set_name__(self):
150n/a pass
151n/a
152n/a with self.assertRaises(RuntimeError) as cm:
153n/a class NotGoingToWork:
154n/a attr = Descriptor()
155n/a
156n/a exc = cm.exception
157n/a self.assertRegex(str(exc), r'\bNotGoingToWork\b')
158n/a self.assertRegex(str(exc), r'\battr\b')
159n/a self.assertRegex(str(exc), r'\bDescriptor\b')
160n/a self.assertIsInstance(exc.__cause__, TypeError)
161n/a
162n/a def test_set_name_lookup(self):
163n/a resolved = []
164n/a class NonDescriptor:
165n/a def __getattr__(self, name):
166n/a resolved.append(name)
167n/a
168n/a class A:
169n/a d = NonDescriptor()
170n/a
171n/a self.assertNotIn('__set_name__', resolved,
172n/a '__set_name__ is looked up in instance dict')
173n/a
174n/a def test_set_name_init_subclass(self):
175n/a class Descriptor:
176n/a def __set_name__(self, owner, name):
177n/a self.owner = owner
178n/a self.name = name
179n/a
180n/a class Meta(type):
181n/a def __new__(cls, name, bases, ns):
182n/a self = super().__new__(cls, name, bases, ns)
183n/a self.meta_owner = self.owner
184n/a self.meta_name = self.name
185n/a return self
186n/a
187n/a class A:
188n/a def __init_subclass__(cls):
189n/a cls.owner = cls.d.owner
190n/a cls.name = cls.d.name
191n/a
192n/a class B(A, metaclass=Meta):
193n/a d = Descriptor()
194n/a
195n/a self.assertIs(B.owner, B)
196n/a self.assertEqual(B.name, 'd')
197n/a self.assertIs(B.meta_owner, B)
198n/a self.assertEqual(B.name, 'd')
199n/a
200n/a def test_set_name_modifying_dict(self):
201n/a notified = []
202n/a class Descriptor:
203n/a def __set_name__(self, owner, name):
204n/a setattr(owner, name + 'x', None)
205n/a notified.append(name)
206n/a
207n/a class A:
208n/a a = Descriptor()
209n/a b = Descriptor()
210n/a c = Descriptor()
211n/a d = Descriptor()
212n/a e = Descriptor()
213n/a
214n/a self.assertCountEqual(notified, ['a', 'b', 'c', 'd', 'e'])
215n/a
216n/a def test_errors(self):
217n/a class MyMeta(type):
218n/a pass
219n/a
220n/a with self.assertRaises(TypeError):
221n/a class MyClass(metaclass=MyMeta, otherarg=1):
222n/a pass
223n/a
224n/a with self.assertRaises(TypeError):
225n/a types.new_class("MyClass", (object,),
226n/a dict(metaclass=MyMeta, otherarg=1))
227n/a types.prepare_class("MyClass", (object,),
228n/a dict(metaclass=MyMeta, otherarg=1))
229n/a
230n/a class MyMeta(type):
231n/a def __init__(self, name, bases, namespace, otherarg):
232n/a super().__init__(name, bases, namespace)
233n/a
234n/a with self.assertRaises(TypeError):
235n/a class MyClass(metaclass=MyMeta, otherarg=1):
236n/a pass
237n/a
238n/a class MyMeta(type):
239n/a def __new__(cls, name, bases, namespace, otherarg):
240n/a return super().__new__(cls, name, bases, namespace)
241n/a
242n/a def __init__(self, name, bases, namespace, otherarg):
243n/a super().__init__(name, bases, namespace)
244n/a self.otherarg = otherarg
245n/a
246n/a class MyClass(metaclass=MyMeta, otherarg=1):
247n/a pass
248n/a
249n/a self.assertEqual(MyClass.otherarg, 1)
250n/a
251n/a def test_errors_changed_pep487(self):
252n/a # These tests failed before Python 3.6, PEP 487
253n/a class MyMeta(type):
254n/a def __new__(cls, name, bases, namespace):
255n/a return super().__new__(cls, name=name, bases=bases,
256n/a dict=namespace)
257n/a
258n/a with self.assertRaises(TypeError):
259n/a class MyClass(metaclass=MyMeta):
260n/a pass
261n/a
262n/a class MyMeta(type):
263n/a def __new__(cls, name, bases, namespace, otherarg):
264n/a self = super().__new__(cls, name, bases, namespace)
265n/a self.otherarg = otherarg
266n/a return self
267n/a
268n/a class MyClass(metaclass=MyMeta, otherarg=1):
269n/a pass
270n/a
271n/a self.assertEqual(MyClass.otherarg, 1)
272n/a
273n/a def test_type(self):
274n/a t = type('NewClass', (object,), {})
275n/a self.assertIsInstance(t, type)
276n/a self.assertEqual(t.__name__, 'NewClass')
277n/a
278n/a with self.assertRaises(TypeError):
279n/a type(name='NewClass', bases=(object,), dict={})
280n/a
281n/a
282n/aif __name__ == "__main__":
283n/a unittest.main()