Commit 87d23a04 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-36724: Add _PyWarnings_Fini() (#12963)

Py_FinalizeEx() now clears _PyRuntime.warnings variables and
_PyRuntime.exitfuncs.

Changes:

* Add _PyWarnings_Fini(): called by Py_FinalizeEx()
* call_ll_exitfuncs() now clears _PyRuntime.exitfuncs while iterating
  on it (on backward order).
parent 99e69d44
...@@ -76,6 +76,7 @@ extern void PyLong_Fini(void); ...@@ -76,6 +76,7 @@ extern void PyLong_Fini(void);
extern void _PyFaulthandler_Fini(void); extern void _PyFaulthandler_Fini(void);
extern void _PyHash_Fini(void); extern void _PyHash_Fini(void);
extern int _PyTraceMalloc_Fini(void); extern int _PyTraceMalloc_Fini(void);
extern void _PyWarnings_Fini(_PyRuntimeState *runtime);
extern void _PyGILState_Init( extern void _PyGILState_Init(
_PyRuntimeState *runtime, _PyRuntimeState *runtime,
......
...@@ -1259,35 +1259,46 @@ _PyWarnings_Init(void) ...@@ -1259,35 +1259,46 @@ _PyWarnings_Init(void)
if (m == NULL) if (m == NULL)
return NULL; return NULL;
if (_PyRuntime.warnings.filters == NULL) { struct _warnings_runtime_state *state = &_PyRuntime.warnings;
_PyRuntime.warnings.filters = init_filters(); if (state->filters == NULL) {
if (_PyRuntime.warnings.filters == NULL) state->filters = init_filters();
if (state->filters == NULL)
return NULL; return NULL;
} }
Py_INCREF(_PyRuntime.warnings.filters); Py_INCREF(state->filters);
if (PyModule_AddObject(m, "filters", _PyRuntime.warnings.filters) < 0) if (PyModule_AddObject(m, "filters", state->filters) < 0)
return NULL; return NULL;
if (_PyRuntime.warnings.once_registry == NULL) { if (state->once_registry == NULL) {
_PyRuntime.warnings.once_registry = PyDict_New(); state->once_registry = PyDict_New();
if (_PyRuntime.warnings.once_registry == NULL) if (state->once_registry == NULL)
return NULL; return NULL;
} }
Py_INCREF(_PyRuntime.warnings.once_registry); Py_INCREF(state->once_registry);
if (PyModule_AddObject(m, "_onceregistry", if (PyModule_AddObject(m, "_onceregistry",
_PyRuntime.warnings.once_registry) < 0) state->once_registry) < 0)
return NULL; return NULL;
if (_PyRuntime.warnings.default_action == NULL) { if (state->default_action == NULL) {
_PyRuntime.warnings.default_action = PyUnicode_FromString("default"); state->default_action = PyUnicode_FromString("default");
if (_PyRuntime.warnings.default_action == NULL) if (state->default_action == NULL)
return NULL; return NULL;
} }
Py_INCREF(_PyRuntime.warnings.default_action); Py_INCREF(state->default_action);
if (PyModule_AddObject(m, "_defaultaction", if (PyModule_AddObject(m, "_defaultaction",
_PyRuntime.warnings.default_action) < 0) state->default_action) < 0)
return NULL; return NULL;
_PyRuntime.warnings.filters_version = 0; state->filters_version = 0;
return m; return m;
} }
void
_PyWarnings_Fini(_PyRuntimeState *runtime)
{
struct _warnings_runtime_state *state = &runtime->warnings;
Py_CLEAR(state->filters);
Py_CLEAR(state->once_registry);
Py_CLEAR(state->default_action);
}
...@@ -1313,6 +1313,7 @@ Py_FinalizeEx(void) ...@@ -1313,6 +1313,7 @@ Py_FinalizeEx(void)
PyDict_Fini(); PyDict_Fini();
PySlice_Fini(); PySlice_Fini();
_PyGC_Fini(runtime); _PyGC_Fini(runtime);
_PyWarnings_Fini(runtime);
_Py_HashRandomization_Fini(); _Py_HashRandomization_Fini();
_PyArg_Fini(); _PyArg_Fini();
PyAsyncGen_Fini(); PyAsyncGen_Fini();
...@@ -2248,7 +2249,12 @@ static void ...@@ -2248,7 +2249,12 @@ static void
call_ll_exitfuncs(_PyRuntimeState *runtime) call_ll_exitfuncs(_PyRuntimeState *runtime)
{ {
while (runtime->nexitfuncs > 0) { while (runtime->nexitfuncs > 0) {
(*runtime->exitfuncs[--runtime->nexitfuncs])(); /* pop last function from the list */
runtime->nexitfuncs--;
void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs];
runtime->exitfuncs[runtime->nexitfuncs] = NULL;
exitfunc();
} }
fflush(stdout); fflush(stdout);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment