[tor-commits] [stem/master] Drop usage of get_running_loop()

atagar at torproject.org atagar at torproject.org
Sat Jul 18 00:39:41 UTC 2020


commit 0cb1017c66f59477475e700b3081190df7f24fff
Author: Damian Johnson <atagar at 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.



More information about the tor-commits mailing list