From: Ben Darnell Date: Sat, 13 Jan 2018 18:55:32 +0000 (-0500) Subject: ioloop: Make clear_current work if called first in a thread X-Git-Tag: v5.0.0~16^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d7fb199ca91d0e6fb521f347fa1807efe7e121e;p=thirdparty%2Ftornado.git ioloop: Make clear_current work if called first in a thread Fixes #2240 --- diff --git a/tornado/ioloop.py b/tornado/ioloop.py index 138a61b5c..c829afcf5 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -321,7 +321,7 @@ class IOLoop(Configurable): .. versionchanged:: 5.0 This method also clears the current `asyncio` event loop. """ - old = IOLoop._current.instance + old = getattr(IOLoop._current, "instance", None) if old is not None: old._clear_current_hook() IOLoop._current.instance = None diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py index b761a3f54..7cae9f1ab 100644 --- a/tornado/test/ioloop_test.py +++ b/tornado/test/ioloop_test.py @@ -1,5 +1,6 @@ from __future__ import absolute_import, division, print_function +from concurrent.futures import ThreadPoolExecutor import contextlib import datetime import functools @@ -495,6 +496,16 @@ class TestIOLoopCurrent(unittest.TestCase): self.assertIs(self.io_loop, IOLoop.current()) +class TestIOLoopCurrentAsync(AsyncTestCase): + @gen_test + def test_clear_without_current(self): + # If there is no current IOLoop, clear_current is a no-op (but + # should not fail). Use a thread so we see the threading.Local + # in a pristine state. + with ThreadPoolExecutor(1) as e: + yield e.submit(IOLoop.clear_current) + + class TestIOLoopAddCallback(AsyncTestCase): def setUp(self): super(TestIOLoopAddCallback, self).setUp()