From 597637168e6b20cfab2065f186ee1fbc0351dc42 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Sun, 11 Mar 2018 13:20:26 -0400 Subject: [PATCH] asyncio: Support Python 3.4.2 for compatibility with Debian jessie The ensure_future function was not introduced until 3.4.4, and some exceptions were changed from AssertionError to RuntimeError in 3.4.3. Fixes #2301 --- tornado/gen.py | 7 ++++++- tornado/ioloop.py | 2 +- tornado/platform/asyncio.py | 8 +++++--- tornado/test/asyncio_test.py | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tornado/gen.py b/tornado/gen.py index 762b44f9c..0ef7c9fc5 100644 --- a/tornado/gen.py +++ b/tornado/gen.py @@ -1292,7 +1292,12 @@ except ImportError: break raise Return(_r) else: - _wrap_awaitable = asyncio.ensure_future + try: + _wrap_awaitable = asyncio.ensure_future + except AttributeError: + # asyncio.ensure_future was introduced in Python 3.4.4, but + # Debian jessie still ships with 3.4.2 so try the old name. + _wrap_awaitable = getattr(asyncio, 'async') def convert_yielded(yielded): diff --git a/tornado/ioloop.py b/tornado/ioloop.py index b3fc35676..839e7ee54 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -281,7 +281,7 @@ class IOLoop(Configurable): else: try: loop = asyncio.get_event_loop() - except RuntimeError: + except (RuntimeError, AssertionError): if not instance: return None raise diff --git a/tornado/platform/asyncio.py b/tornado/platform/asyncio.py index 0d7eea3e5..b2ad9fe6e 100644 --- a/tornado/platform/asyncio.py +++ b/tornado/platform/asyncio.py @@ -104,7 +104,7 @@ class BaseAsyncIOLoop(IOLoop): def start(self): try: old_loop = asyncio.get_event_loop() - except RuntimeError: + except (RuntimeError, AssertionError): old_loop = None try: self._setup_logging() @@ -211,7 +211,7 @@ class AsyncIOLoop(BaseAsyncIOLoop): if not self.is_current: try: self.old_asyncio = asyncio.get_event_loop() - except RuntimeError: + except (RuntimeError, AssertionError): self.old_asyncio = None self.is_current = True asyncio.set_event_loop(self.asyncio_loop) @@ -270,7 +270,9 @@ class AnyThreadEventLoopPolicy(asyncio.DefaultEventLoopPolicy): def get_event_loop(self): try: return super().get_event_loop() - except RuntimeError: + except (RuntimeError, AssertionError): + # This was an AssertionError in python 3.4.2 (which ships with debian jessie) + # and changed to a RuntimeError in 3.4.3. # "There is no current event loop in thread %r" loop = self.new_event_loop() self.set_event_loop(loop) diff --git a/tornado/test/asyncio_test.py b/tornado/test/asyncio_test.py index bbabb5212..41fda20d4 100644 --- a/tornado/test/asyncio_test.py +++ b/tornado/test/asyncio_test.py @@ -150,7 +150,7 @@ class AnyThreadEventLoopPolicyTest(unittest.TestCase): def run_policy_test(self, accessor, expected_type): # With the default policy, non-main threads don't get an event # loop. - self.assertRaises(RuntimeError, + self.assertRaises((RuntimeError, AssertionError), self.executor.submit(accessor).result) # Set the policy and we can get a loop. asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy()) -- 2.47.2