diff options
author | Victor Stinner <vstinner@python.org> | 2020-03-09 22:37:49 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-09 22:37:49 (GMT) |
commit | 9ad58acbe8b90b4d0f2d2e139e38bb5aa32b7fb6 (patch) | |
tree | 7678fd0af5dc8c6922aee830e7f5b106dae23539 /Lib/test/test_threading.py | |
parent | 8e9c47a947954c997d4b725f4551d50a1d896722 (diff) | |
download | cpython-9ad58acbe8b90b4d0f2d2e139e38bb5aa32b7fb6.zip cpython-9ad58acbe8b90b4d0f2d2e139e38bb5aa32b7fb6.tar.gz cpython-9ad58acbe8b90b4d0f2d2e139e38bb5aa32b7fb6.tar.bz2 |
bpo-19466: Py_Finalize() clears daemon threads earlier (GH-18848)
Clear the frames of daemon threads earlier during the Python shutdown to
call objects destructors. So "unclosed file" resource warnings are now
emitted for daemon threads in a more reliable way.
Cleanup _PyThreadState_DeleteExcept() code: rename "garbage" to
"list".
Diffstat (limited to 'Lib/test/test_threading.py')
-rw-r--r-- | Lib/test/test_threading.py | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index a9d31af..87c68df 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -759,6 +759,51 @@ class ThreadTests(BaseTestCase): # Daemon threads must never add it to _shutdown_locks. self.assertNotIn(tstate_lock, threading._shutdown_locks) + def test_locals_at_exit(self): + # bpo-19466: thread locals must not be deleted before destructors + # are called + rc, out, err = assert_python_ok("-c", """if 1: + import threading + + class Atexit: + def __del__(self): + print("thread_dict.atexit = %r" % thread_dict.atexit) + + thread_dict = threading.local() + thread_dict.atexit = "value" + + atexit = Atexit() + """) + self.assertEqual(out.rstrip(), b"thread_dict.atexit = 'value'") + + def test_warnings_at_exit(self): + # bpo-19466: try to call most destructors at Python shutdown before + # destroying Python thread states + filename = __file__ + rc, out, err = assert_python_ok("-Wd", "-c", """if 1: + import time + import threading + from test import support + + def open_sleep(): + # a warning will be emitted when the open file will be + # destroyed (without being explicitly closed) while the daemon + # thread is destroyed + fileobj = open(%a, 'rb') + start_event.set() + time.sleep(support.LONG_TIMEOUT) + + start_event = threading.Event() + + thread = threading.Thread(target=open_sleep, daemon=True) + thread.start() + + # wait until the thread started + start_event.wait() + """ % filename) + self.assertRegex(err.rstrip(), + b"^sys:1: ResourceWarning: unclosed file ") + class ThreadJoinOnShutdown(BaseTestCase): |