diff options
author | Antoine Pitrou <pitrou@free.fr> | 2017-12-13 02:29:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-13 02:29:07 +0100 |
commit | fc5db95e0063eafa2bfb7f487fcaad5a7c4b65a1 (patch) | |
tree | 61bc58e4e52f4114140dee0e21f77b91364afa31 | |
parent | 317def9fdb29893df1ab380d396fcdd2eafe0588 (diff) | |
download | cpython-git-fc5db95e0063eafa2bfb7f487fcaad5a7c4b65a1.tar.gz |
Test atexit shutdown mechanism in a subprocess (#4828)
* Test atexit shutdown mechanism in a subprocess
-rw-r--r-- | Lib/test/test_atexit.py | 16 | ||||
-rw-r--r-- | Python/pylifecycle.c | 2 |
2 files changed, 18 insertions, 0 deletions
diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index 1d0b018aaf..aa56388ef6 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -3,6 +3,7 @@ import unittest import io import atexit from test import support +from test.support import script_helper ### helpers def h1(): @@ -152,6 +153,21 @@ class GeneralTest(unittest.TestCase): atexit._run_exitfuncs() self.assertEqual(l, [5]) + def test_shutdown(self): + # Actually test the shutdown mechanism in a subprocess + code = """if 1: + import atexit + + def f(msg): + print(msg) + + atexit.register(f, "one") + atexit.register(f, "two") + """ + res = script_helper.assert_python_ok("-c", code) + self.assertEqual(res.out.decode().splitlines(), ["two", "one"]) + self.assertFalse(res.err) + @support.cpython_only class SubinterpreterTest(unittest.TestCase): diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index fdb09d910d..f284855f34 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2086,6 +2086,8 @@ _Py_FatalInitError(_PyInitError err) /* For the atexit module. */ void _Py_PyAtExit(void (*func)(void)) { + /* Guard against API misuse (see bpo-17852) */ + assert(_PyRuntime.pyexitfunc == NULL || _PyRuntime.pyexitfunc == func); _PyRuntime.pyexitfunc = func; } |