bpo-42639: Move atexit state to PyInterpreterState#23763
bpo-42639: Move atexit state to PyInterpreterState#23763vstinner merged 1 commit intopython:masterfrom vstinner:atexit_state
Conversation
|
cc @corona10 |
|
I included multiple refactoring changes in this PR. I marked the PR as a draft. If the overall approach is accepted, I will merge this PR as multiple commits. |
corona10
left a comment
There was a problem hiding this comment.
I am +1 on this PR than my PR.
I will take a look at this PR
--- a/Modules/atexitmodule.c
+++ b/Modules/atexitmodule.c
@@ -10,6 +10,7 @@
#include "pycore_initconfig.h" // _PyStatus_NO_MEMORY
#include "pycore_interp.h" // PyInterpreterState.atexits
#include "pycore_pystate.h" // _PyInterpreterState_GET
+#include "pycore_pyerrors.h"
static inline struct atexit_state*
@@ -93,10 +94,6 @@ atexit_callfuncs(struct atexit_state *state, int ignore_exc)
PyObject *res = PyObject_Call(cb->func, cb->args, cb->kwargs);
if (res == NULL) {
- if (ignore_exc) {
- _PyErr_WriteUnraisableMsg("in atexit callback", cb->func);
- }
- else {
/* Maintain the last exception, but don't leak if there are
multiple exceptions. */
if (exc_type) {
@@ -110,7 +107,6 @@ atexit_callfuncs(struct atexit_state *state, int ignore_exc)
PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb);
PyErr_Display(exc_type, exc_value, exc_tb);
}
- }
}
else {
Py_DECREF(res);
@@ -135,6 +131,7 @@ _PyAtExit_Call(PyThreadState *tstate)
{
struct atexit_state *state = &tstate->interp->atexits;
atexit_callfuncs(state, 1);
+ _PyErr_Clear(tstate);
}may fix the CI |
|
I pushed two changes to prepare this PR (to make this PR shorter): https://bugs.python.org/issue42639 The PR is now ready for review. |
* Add _PyAtExit_Call() function and remove pyexitfunc and pyexitmodule members of PyInterpreterState. The function logs atexit callback errors using _PyErr_WriteUnraisableMsg(). * Add _PyAtExit_Init() and _PyAtExit_Fini() functions. * Remove traverse, clear and free functions of the atexit module. * Remove _Py_PyAtExit() function. * test_atexit uses textwrap.dedent(). * setup.py no longer tries to build atexit: it is always a built-in module. Co-Authored-By: Dong-hee Na <donghee.na@python.org>
|
@corona10: Would you mind to review the updated (shorter) PR? |
shihai1991
left a comment
There was a problem hiding this comment.
No other comments in here, LGTM.
encukou
left a comment
There was a problem hiding this comment.
LGTM! Two nitpicks; one of them below.
While you're here, consider changing "Error in atexit._run_exitfuncs:\n" to "Error in atexit callback:\n" on line 111. _run_exitfuncs is private test-only API; the label in the _PyErr_WriteUnraisableMsg branch is nicer.
| { | ||
| struct atexit_state *state = &interp->atexit; | ||
| atexit_cleanup(state); | ||
| PyMem_Free(state->callbacks); |
There was a problem hiding this comment.
It might be safer to set it to NULL after freeing.
* Add _PyAtExit_Call() function and remove pyexitfunc and pyexitmodule members of PyInterpreterState. The function logs atexit callback errors using _PyErr_WriteUnraisableMsg(). * Add _PyAtExit_Init() and _PyAtExit_Fini() functions. * Remove traverse, clear and free functions of the atexit module. Co-authored-by: Dong-hee Na <donghee.na@python.org>
pyexitmodule members of PyInterpreterState. The function
logs atexit callback errors using _PyErr_WriteUnraisableMsg().
module.
Co-Authored-By: Dong-hee Na donghee.na@python.org
https://bugs.python.org/issue42639