commit 0cb1017c66f59477475e700b3081190df7f24fff Author: Damian Johnson atagar@torproject.org Date: Thu Jul 16 17:21:38 2020 -0700
Drop usage of get_running_loop()
Stem supports Python 3.6+ but asyncio.get_running_loop() was added in 3.7.
The only difference between get_running_loop() and get_event_loop() is that the former raises a RuntimeError when outside an asyncio context. These calls are assured to be asyncronous so it really doesn't matter - I just picked get_running_loop() because it reads a tad better.
The one exception is our is_asyncio_context() function. For that we need a fallback, which fortunately a private method provides...
https://github.com/Azure/msrest-for-python/issues/136 --- stem/descriptor/remote.py | 4 +++- stem/util/__init__.py | 11 ++++++++++- test/unit/util/synchronous.py | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py index 3428f0d2..2c97c361 100644 --- a/stem/descriptor/remote.py +++ b/stem/descriptor/remote.py @@ -442,7 +442,9 @@ class Query(Synchronous):
with self._downloader_lock: if self._downloader_task is None: - loop = asyncio.get_running_loop() + # TODO: replace with get_running_loop() when we remove python 3.6 support + + loop = asyncio.get_event_loop() self._downloader_task = loop.create_task(self._download_descriptors(self.retries, self.timeout))
async def run(self, suppress: bool = False, stop: bool = True) -> List['stem.descriptor.Descriptor']: diff --git a/stem/util/__init__.py b/stem/util/__init__.py index de946fd9..c525dd6f 100644 --- a/stem/util/__init__.py +++ b/stem/util/__init__.py @@ -210,7 +210,9 @@ class Synchronous(object): self._no_op = Synchronous.is_asyncio_context()
if self._no_op: - self._loop = asyncio.get_running_loop() + # TODO: replace with get_running_loop() when we remove python 3.6 support + + self._loop = asyncio.get_event_loop() self.__ainit__() # this is already an asyncio context else: # Run coroutines through our loop. This calls methods by name rather than @@ -316,6 +318,13 @@ class Synchronous(object): return True except RuntimeError: return False + except AttributeError: + # TODO: drop when we remove python 3.6 support + + try: + return asyncio._get_running_loop() is not None + except AttributeError: + return False # python 3.5.3 or below
def _run_async_method(self, method_name: str, *args: Any, **kwargs: Any) -> Any: """ diff --git a/test/unit/util/synchronous.py b/test/unit/util/synchronous.py index 602d81f4..9485e09a 100644 --- a/test/unit/util/synchronous.py +++ b/test/unit/util/synchronous.py @@ -72,6 +72,20 @@ class TestSynchronous(unittest.TestCase):
self.assertEqual(EXAMPLE_OUTPUT, stdout_mock.getvalue())
+ def test_is_asyncio_context(self): + """ + Check that we can differentiate a synchronous from an async context. + """ + + def sync_test(): + self.assertFalse(Synchronous.is_asyncio_context()) + + async def async_test(): + self.assertTrue(Synchronous.is_asyncio_context()) + + sync_test() + asyncio.run(async_test()) + def test_ainit(self): """ Check that construction runs __ainit__ with a loop when present.
tor-commits@lists.torproject.org