Because of a bug, warnings were not emitted during Python shutdown. I fixed the bug in issue #19424, and now Python crashs when a warning is emitted during shutdown. See also issue #19421: "FileIO destructor imports indirectly the io module at exit". The warnings module uses globals()['__name__'] to get the name of the current module. The bug was the during Python shutdown, the module is None and _PyUnicode_AsString(None) was raising an exception (in setup_context() of _warnings.c) and so the warning was not emitted. For example, FileIO destructor emits a warning when a unclosed file is destroyed. The destructor removes the exception raised the warning module.
The changeset 1787277915e9 is closer to a workaround than a real fix: + if (module != Py_None) { + res = warn_explicit(category, message, filename, lineno, module, registry, + NULL); + } + else { + /* FIXME: emitting warnings at exit does crash Python */ + res = Py_None; + Py_INCREF(res); + }
warn_shutdown.py: example of script emitting warning at shutdown. Depending on the timing, the warning is shown or not (replace "if 0:" with "if 1:" to always display the warning). This example is a simplified example of the original crasher: test_threading.test_4_daemon_threads().
warn_shutdown.py does not emit warnings because the thread states are destroyed too late, when the modules have been destroyed. I opened a new issue #19466 "Clear state of threads earlier in Python shutdown" which would permit to emit properly warnings, at least for the specific case of warn_shutdown.py. > The changeset 1787277915e9 is closer to a workaround than a real fix: ... If the module is None, it's too late: modules have been destroyed, so it's safer to not call warn_explicit() and do nothing. I tested to fail with an assertion error if a warning is emitted too late (ie. when module is None). test_threading.test_4_daemon_threads() does fail in this case. Using the patch attached to #19466, the full test suite pass correctly.