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).
This commit is contained in:
Victor Stinner 2019-04-26 05:49:26 +02:00 committed by GitHub
parent 99e69d44f4
commit 87d23a041d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 17 deletions

View File

@ -76,6 +76,7 @@ extern void PyLong_Fini(void);
extern void _PyFaulthandler_Fini(void);
extern void _PyHash_Fini(void);
extern int _PyTraceMalloc_Fini(void);
extern void _PyWarnings_Fini(_PyRuntimeState *runtime);
extern void _PyGILState_Init(
_PyRuntimeState *runtime,

View File

@ -1259,35 +1259,46 @@ _PyWarnings_Init(void)
if (m == NULL)
return NULL;
if (_PyRuntime.warnings.filters == NULL) {
_PyRuntime.warnings.filters = init_filters();
if (_PyRuntime.warnings.filters == NULL)
struct _warnings_runtime_state *state = &_PyRuntime.warnings;
if (state->filters == NULL) {
state->filters = init_filters();
if (state->filters == NULL)
return NULL;
}
Py_INCREF(_PyRuntime.warnings.filters);
if (PyModule_AddObject(m, "filters", _PyRuntime.warnings.filters) < 0)
Py_INCREF(state->filters);
if (PyModule_AddObject(m, "filters", state->filters) < 0)
return NULL;
if (_PyRuntime.warnings.once_registry == NULL) {
_PyRuntime.warnings.once_registry = PyDict_New();
if (_PyRuntime.warnings.once_registry == NULL)
if (state->once_registry == NULL) {
state->once_registry = PyDict_New();
if (state->once_registry == NULL)
return NULL;
}
Py_INCREF(_PyRuntime.warnings.once_registry);
Py_INCREF(state->once_registry);
if (PyModule_AddObject(m, "_onceregistry",
_PyRuntime.warnings.once_registry) < 0)
state->once_registry) < 0)
return NULL;
if (_PyRuntime.warnings.default_action == NULL) {
_PyRuntime.warnings.default_action = PyUnicode_FromString("default");
if (_PyRuntime.warnings.default_action == NULL)
if (state->default_action == NULL) {
state->default_action = PyUnicode_FromString("default");
if (state->default_action == NULL)
return NULL;
}
Py_INCREF(_PyRuntime.warnings.default_action);
Py_INCREF(state->default_action);
if (PyModule_AddObject(m, "_defaultaction",
_PyRuntime.warnings.default_action) < 0)
state->default_action) < 0)
return NULL;
_PyRuntime.warnings.filters_version = 0;
state->filters_version = 0;
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);
}

View File

@ -1313,6 +1313,7 @@ Py_FinalizeEx(void)
PyDict_Fini();
PySlice_Fini();
_PyGC_Fini(runtime);
_PyWarnings_Fini(runtime);
_Py_HashRandomization_Fini();
_PyArg_Fini();
PyAsyncGen_Fini();
@ -2248,7 +2249,12 @@ static void
call_ll_exitfuncs(_PyRuntimeState *runtime)
{
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);