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

Python code coverage for Lib/test/test_atexit.py

#countcontent
1n/aimport sys
2n/aimport unittest
3n/aimport io
4n/aimport atexit
5n/afrom test import support
6n/a
7n/a### helpers
8n/adef h1():
9n/a print("h1")
10n/a
11n/adef h2():
12n/a print("h2")
13n/a
14n/adef h3():
15n/a print("h3")
16n/a
17n/adef h4(*args, **kwargs):
18n/a print("h4", args, kwargs)
19n/a
20n/adef raise1():
21n/a raise TypeError
22n/a
23n/adef raise2():
24n/a raise SystemError
25n/a
26n/a
27n/aclass GeneralTest(unittest.TestCase):
28n/a
29n/a def setUp(self):
30n/a self.save_stdout = sys.stdout
31n/a self.save_stderr = sys.stderr
32n/a self.stream = io.StringIO()
33n/a sys.stdout = sys.stderr = self.stream
34n/a atexit._clear()
35n/a
36n/a def tearDown(self):
37n/a sys.stdout = self.save_stdout
38n/a sys.stderr = self.save_stderr
39n/a atexit._clear()
40n/a
41n/a def test_args(self):
42n/a # be sure args are handled properly
43n/a atexit.register(h1)
44n/a atexit.register(h4)
45n/a atexit.register(h4, 4, kw="abc")
46n/a atexit._run_exitfuncs()
47n/a
48n/a self.assertEqual(self.stream.getvalue(),
49n/a "h4 (4,) {'kw': 'abc'}\nh4 () {}\nh1\n")
50n/a
51n/a def test_badargs(self):
52n/a atexit.register(lambda: 1, 0, 0, (x for x in (1,2)), 0, 0)
53n/a self.assertRaises(TypeError, atexit._run_exitfuncs)
54n/a
55n/a def test_order(self):
56n/a # be sure handlers are executed in reverse order
57n/a atexit.register(h1)
58n/a atexit.register(h2)
59n/a atexit.register(h3)
60n/a atexit._run_exitfuncs()
61n/a
62n/a self.assertEqual(self.stream.getvalue(), "h3\nh2\nh1\n")
63n/a
64n/a def test_raise(self):
65n/a # be sure raises are handled properly
66n/a atexit.register(raise1)
67n/a atexit.register(raise2)
68n/a
69n/a self.assertRaises(TypeError, atexit._run_exitfuncs)
70n/a
71n/a def test_raise_unnormalized(self):
72n/a # Issue #10756: Make sure that an unnormalized exception is
73n/a # handled properly
74n/a atexit.register(lambda: 1 / 0)
75n/a
76n/a self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs)
77n/a self.assertIn("ZeroDivisionError", self.stream.getvalue())
78n/a
79n/a def test_print_tracebacks(self):
80n/a # Issue #18776: the tracebacks should be printed when errors occur.
81n/a def f():
82n/a 1/0 # one
83n/a def g():
84n/a 1/0 # two
85n/a def h():
86n/a 1/0 # three
87n/a atexit.register(f)
88n/a atexit.register(g)
89n/a atexit.register(h)
90n/a
91n/a self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs)
92n/a stderr = self.stream.getvalue()
93n/a self.assertEqual(stderr.count("ZeroDivisionError"), 3)
94n/a self.assertIn("# one", stderr)
95n/a self.assertIn("# two", stderr)
96n/a self.assertIn("# three", stderr)
97n/a
98n/a def test_stress(self):
99n/a a = [0]
100n/a def inc():
101n/a a[0] += 1
102n/a
103n/a for i in range(128):
104n/a atexit.register(inc)
105n/a atexit._run_exitfuncs()
106n/a
107n/a self.assertEqual(a[0], 128)
108n/a
109n/a def test_clear(self):
110n/a a = [0]
111n/a def inc():
112n/a a[0] += 1
113n/a
114n/a atexit.register(inc)
115n/a atexit._clear()
116n/a atexit._run_exitfuncs()
117n/a
118n/a self.assertEqual(a[0], 0)
119n/a
120n/a def test_unregister(self):
121n/a a = [0]
122n/a def inc():
123n/a a[0] += 1
124n/a def dec():
125n/a a[0] -= 1
126n/a
127n/a for i in range(4):
128n/a atexit.register(inc)
129n/a atexit.register(dec)
130n/a atexit.unregister(inc)
131n/a atexit._run_exitfuncs()
132n/a
133n/a self.assertEqual(a[0], -1)
134n/a
135n/a def test_bound_methods(self):
136n/a l = []
137n/a atexit.register(l.append, 5)
138n/a atexit._run_exitfuncs()
139n/a self.assertEqual(l, [5])
140n/a
141n/a atexit.unregister(l.append)
142n/a atexit._run_exitfuncs()
143n/a self.assertEqual(l, [5])
144n/a
145n/a
146n/aclass SubinterpreterTest(unittest.TestCase):
147n/a
148n/a def test_callbacks_leak(self):
149n/a # This test shows a leak in refleak mode if atexit doesn't
150n/a # take care to free callbacks in its per-subinterpreter module
151n/a # state.
152n/a n = atexit._ncallbacks()
153n/a code = r"""if 1:
154n/a import atexit
155n/a def f():
156n/a pass
157n/a atexit.register(f)
158n/a del atexit
159n/a """
160n/a ret = support.run_in_subinterp(code)
161n/a self.assertEqual(ret, 0)
162n/a self.assertEqual(atexit._ncallbacks(), n)
163n/a
164n/a def test_callbacks_leak_refcycle(self):
165n/a # Similar to the above, but with a refcycle through the atexit
166n/a # module.
167n/a n = atexit._ncallbacks()
168n/a code = r"""if 1:
169n/a import atexit
170n/a def f():
171n/a pass
172n/a atexit.register(f)
173n/a atexit.__atexit = atexit
174n/a """
175n/a ret = support.run_in_subinterp(code)
176n/a self.assertEqual(ret, 0)
177n/a self.assertEqual(atexit._ncallbacks(), n)
178n/a
179n/a
180n/aif __name__ == "__main__":
181n/a unittest.main()