]> granicus.if.org Git - python/commitdiff
bpo-36724: Add _PyWarnings_Fini() (#12963)
authorVictor Stinner <vstinner@redhat.com>
Fri, 26 Apr 2019 03:49:26 +0000 (05:49 +0200)
committerGitHub <noreply@github.com>
Fri, 26 Apr 2019 03:49:26 +0000 (05:49 +0200)
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).

Include/internal/pycore_pylifecycle.h
Python/_warnings.c
Python/pylifecycle.c

index 24847f4f454e5b69372a326288c3c06b6bf632ce..f5da1431d94cc955a4fc1dfd91f3cc9c8318ebb2 100644 (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,
index 33b461511585e577c5c62a14b56fb60d8d2e4461..388b29954081eb218eb0c39cdcafa127a00ad99a 100644 (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);
+}
index 03486c3b195a52d6fae0f4f174890c9f7c5e774a..ae2d0bf92c6e1f6b4c5956a7fc54bb1b8867154c 100644 (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);