diff options
-rw-r--r-- | Lib/atexit.py | 3 | ||||
-rw-r--r-- | Python/pythonrun.c | 11 |
2 files changed, 11 insertions, 3 deletions
diff --git a/Lib/atexit.py b/Lib/atexit.py index bcf7e54..61f2458 100644 --- a/Lib/atexit.py +++ b/Lib/atexit.py @@ -16,9 +16,8 @@ def _run_exitfuncs(): """ while _exithandlers: - func, targs, kargs = _exithandlers[-1] + func, targs, kargs = _exithandlers.pop() apply(func, targs, kargs) - _exithandlers.remove(_exithandlers[-1]) def register(func, *targs, **kargs): """register a function to be executed upon normal program termination diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ff2142b..4c94f9b 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -181,9 +181,18 @@ Py_Finalize(void) if (!initialized) return; - initialized = 0; + /* The interpreter is still entirely intact at this point, and the + * exit funcs may be relying on that. In particular, if some thread + * or exit func is still waiting to do an import, the import machinery + * expects Py_IsInitialized() to return true. So don't say the + * interpreter is uninitialized until after the exit funcs have run. + * Note that Threading.py uses an exit func to do a join on all the + * threads created thru it, so this also protects pending imports in + * the threads created via Threading. + */ call_sys_exitfunc(); + initialized = 0; /* Get current thread state and interpreter pointer */ tstate = PyThreadState_Get(); |