Skip to content

Commit ba67971

Browse files
committed
Update test_atexit to CPython 3.10
1 parent 617a820 commit ba67971

File tree

1 file changed

+34
-156
lines changed

1 file changed

+34
-156
lines changed

Lib/test/test_atexit.py

Lines changed: 34 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,174 +1,52 @@
1-
import sys
2-
import unittest
3-
import io
41
import atexit
52
import os
3+
import sys
4+
import textwrap
5+
import unittest
66
from test import support
77
from test.support import script_helper
88

9-
### helpers
10-
def h1():
11-
print("h1")
12-
13-
def h2():
14-
print("h2")
15-
16-
def h3():
17-
print("h3")
18-
19-
def h4(*args, **kwargs):
20-
print("h4", args, kwargs)
21-
22-
def raise1():
23-
raise TypeError
24-
25-
def raise2():
26-
raise SystemError
27-
28-
def exit():
29-
raise SystemExit
30-
319

3210
class GeneralTest(unittest.TestCase):
11+
def test_general(self):
12+
# Run _test_atexit.py in a subprocess since it calls atexit._clear()
13+
script = support.findfile("_test_atexit.py")
14+
script_helper.run_test_script(script)
3315

34-
def setUp(self):
35-
self.save_stdout = sys.stdout
36-
self.save_stderr = sys.stderr
37-
self.stream = io.StringIO()
38-
sys.stdout = sys.stderr = self.stream
39-
atexit._clear()
40-
41-
def tearDown(self):
42-
sys.stdout = self.save_stdout
43-
sys.stderr = self.save_stderr
44-
atexit._clear()
45-
46-
def test_args(self):
47-
# be sure args are handled properly
48-
atexit.register(h1)
49-
atexit.register(h4)
50-
atexit.register(h4, 4, kw="abc")
51-
atexit._run_exitfuncs()
52-
53-
self.assertEqual(self.stream.getvalue(),
54-
"h4 (4,) {'kw': 'abc'}\nh4 () {}\nh1\n")
55-
56-
def test_badargs(self):
57-
atexit.register(lambda: 1, 0, 0, (x for x in (1,2)), 0, 0)
58-
self.assertRaises(TypeError, atexit._run_exitfuncs)
59-
60-
def test_order(self):
61-
# be sure handlers are executed in reverse order
62-
atexit.register(h1)
63-
atexit.register(h2)
64-
atexit.register(h3)
65-
atexit._run_exitfuncs()
66-
67-
self.assertEqual(self.stream.getvalue(), "h3\nh2\nh1\n")
68-
69-
def test_raise(self):
70-
# be sure raises are handled properly
71-
atexit.register(raise1)
72-
atexit.register(raise2)
73-
74-
self.assertRaises(TypeError, atexit._run_exitfuncs)
75-
76-
def test_raise_unnormalized(self):
77-
# Issue #10756: Make sure that an unnormalized exception is
78-
# handled properly
79-
atexit.register(lambda: 1 / 0)
80-
81-
self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs)
82-
self.assertIn("ZeroDivisionError", self.stream.getvalue())
83-
84-
def test_exit(self):
85-
# be sure a SystemExit is handled properly
86-
atexit.register(exit)
87-
88-
self.assertRaises(SystemExit, atexit._run_exitfuncs)
89-
self.assertEqual(self.stream.getvalue(), '')
90-
91-
def test_print_tracebacks(self):
92-
# Issue #18776: the tracebacks should be printed when errors occur.
93-
def f():
94-
1/0 # one
95-
def g():
96-
1/0 # two
97-
def h():
98-
1/0 # three
99-
atexit.register(f)
100-
atexit.register(g)
101-
atexit.register(h)
102-
103-
self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs)
104-
stderr = self.stream.getvalue()
105-
self.assertEqual(stderr.count("ZeroDivisionError"), 3)
106-
self.assertIn("# one", stderr)
107-
self.assertIn("# two", stderr)
108-
self.assertIn("# three", stderr)
109-
110-
def test_stress(self):
111-
a = [0]
112-
def inc():
113-
a[0] += 1
114-
115-
for i in range(128):
116-
atexit.register(inc)
117-
atexit._run_exitfuncs()
118-
119-
self.assertEqual(a[0], 128)
120-
121-
def test_clear(self):
122-
a = [0]
123-
def inc():
124-
a[0] += 1
125-
126-
atexit.register(inc)
127-
atexit._clear()
128-
atexit._run_exitfuncs()
129-
130-
self.assertEqual(a[0], 0)
131-
132-
def test_unregister(self):
133-
a = [0]
134-
def inc():
135-
a[0] += 1
136-
def dec():
137-
a[0] -= 1
138-
139-
for i in range(4):
140-
atexit.register(inc)
141-
atexit.register(dec)
142-
atexit.unregister(inc)
143-
atexit._run_exitfuncs()
144-
145-
self.assertEqual(a[0], -1)
146-
147-
def test_bound_methods(self):
148-
l = []
149-
atexit.register(l.append, 5)
150-
atexit._run_exitfuncs()
151-
self.assertEqual(l, [5])
152-
153-
atexit.unregister(l.append)
154-
atexit._run_exitfuncs()
155-
self.assertEqual(l, [5])
156-
16+
class FunctionalTest(unittest.TestCase):
15717
def test_shutdown(self):
15818
# Actually test the shutdown mechanism in a subprocess
159-
code = """if 1:
19+
code = textwrap.dedent("""
16020
import atexit
16121
16222
def f(msg):
16323
print(msg)
16424
16525
atexit.register(f, "one")
16626
atexit.register(f, "two")
167-
"""
27+
""")
16828
res = script_helper.assert_python_ok("-c", code)
16929
self.assertEqual(res.out.decode().splitlines(), ["two", "one"])
17030
self.assertFalse(res.err)
17131

32+
def test_atexit_instances(self):
33+
# bpo-42639: It is safe to have more than one atexit instance.
34+
code = textwrap.dedent("""
35+
import sys
36+
import atexit as atexit1
37+
del sys.modules['atexit']
38+
import atexit as atexit2
39+
del sys.modules['atexit']
40+
41+
assert atexit2 is not atexit1
42+
43+
atexit1.register(print, "atexit1")
44+
atexit2.register(print, "atexit2")
45+
""")
46+
res = script_helper.assert_python_ok("-c", code)
47+
self.assertEqual(res.out.decode().splitlines(), ["atexit2", "atexit1"])
48+
self.assertFalse(res.err)
49+
17250

17351
@support.cpython_only
17452
class SubinterpreterTest(unittest.TestCase):
@@ -178,13 +56,13 @@ def test_callbacks_leak(self):
17856
# take care to free callbacks in its per-subinterpreter module
17957
# state.
18058
n = atexit._ncallbacks()
181-
code = r"""if 1:
59+
code = textwrap.dedent(r"""
18260
import atexit
18361
def f():
18462
pass
18563
atexit.register(f)
18664
del atexit
187-
"""
65+
""")
18866
ret = support.run_in_subinterp(code)
18967
self.assertEqual(ret, 0)
19068
self.assertEqual(atexit._ncallbacks(), n)
@@ -193,13 +71,13 @@ def test_callbacks_leak_refcycle(self):
19371
# Similar to the above, but with a refcycle through the atexit
19472
# module.
19573
n = atexit._ncallbacks()
196-
code = r"""if 1:
74+
code = textwrap.dedent(r"""
19775
import atexit
19876
def f():
19977
pass
20078
atexit.register(f)
20179
atexit.__atexit = atexit
202-
"""
80+
""")
20381
ret = support.run_in_subinterp(code)
20482
self.assertEqual(ret, 0)
20583
self.assertEqual(atexit._ncallbacks(), n)
@@ -210,13 +88,13 @@ def test_callback_on_subinterpreter_teardown(self):
21088
expected = b"The test has passed!"
21189
r, w = os.pipe()
21290

213-
code = r"""if 1:
91+
code = textwrap.dedent(r"""
21492
import os
21593
import atexit
21694
def callback():
21795
os.write({:d}, b"The test has passed!")
21896
atexit.register(callback)
219-
""".format(w)
97+
""".format(w))
22098
ret = support.run_in_subinterp(code)
22199
os.close(w)
222100
self.assertEqual(os.read(r, len(expected)), expected)

0 commit comments

Comments
 (0)