diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-04-26 03:49:26 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-26 03:49:26 (GMT) |
commit | 87d23a041d9efb743c5680ac23305ddddf300e51 (patch) | |
tree | f029bae963de4672d511759bd88e84d3a64544eb | |
parent | 99e69d44f499625786a2e6461a954adcd0037d69 (diff) | |
download | cpython-87d23a041d9efb743c5680ac23305ddddf300e51.zip cpython-87d23a041d9efb743c5680ac23305ddddf300e51.tar.gz cpython-87d23a041d9efb743c5680ac23305ddddf300e51.tar.bz2 |
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).
-rw-r--r-- | Include/internal/pycore_pylifecycle.h | 1 | ||||
-rw-r--r-- | Python/_warnings.c | 43 | ||||
-rw-r--r-- | Python/pylifecycle.c | 8 |
3 files changed, 35 insertions, 17 deletions
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 24847f4..f5da143 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -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, diff --git a/Python/_warnings.c b/Python/_warnings.c index 33b4615..388b299 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -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); +} diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 03486c3..ae2d0bf 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -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); |