]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-110774: allow setting the Runner(loop_factory=...) from IsolatedAsyncioTestCase...
authorThomas Grainger <tagrain@gmail.com>
Tue, 31 Oct 2023 22:03:54 +0000 (15:03 -0700)
committerGitHub <noreply@github.com>
Tue, 31 Oct 2023 22:03:54 +0000 (15:03 -0700)
Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
Doc/library/unittest.rst
Lib/test/test_unittest/test_async_case.py
Lib/unittest/async_case.py
Misc/NEWS.d/next/Library/2023-10-12-15-16-44.gh-issue-110774.AdCb5A.rst [new file with mode: 0644]

index 21abc583f853a702bbc3c7930e88bcfe051ea563..c90c554591e74844e24ddc1f2c51f295e915cc07 100644 (file)
@@ -1571,6 +1571,14 @@ Test cases
 
    .. versionadded:: 3.8
 
+   .. attribute:: loop_factory
+
+      The *loop_factory* passed to :class:`asyncio.Runner`. Override
+      in subclasses with :class:`asyncio.EventLoop` to avoid using the
+      asyncio policy system.
+
+      .. versionadded:: 3.13
+
    .. coroutinemethod:: asyncSetUp()
 
       Method called to prepare the test fixture. This is called after :meth:`setUp`.
index a465103b59b6ecaab8ad98eff361dab57d812161..ba1ab838cd4a223309c9f597219cfa4e74fc7209 100644 (file)
@@ -484,5 +484,19 @@ class TestAsyncCase(unittest.TestCase):
         result = test.run()
         self.assertTrue(result.wasSuccessful())
 
+    def test_loop_factory(self):
+        asyncio.set_event_loop_policy(None)
+
+        class TestCase1(unittest.IsolatedAsyncioTestCase):
+            loop_factory = asyncio.EventLoop
+
+            async def test_demo1(self):
+                pass
+
+        test = TestCase1('test_demo1')
+        result = test.run()
+        self.assertTrue(result.wasSuccessful())
+        self.assertIsNone(support.maybe_get_event_loop_policy())
+
 if __name__ == "__main__":
     unittest.main()
index bd2a471156065bd0a1609ee6b9ed25baecb1bce5..63ff6a5d1f8b611f4a69088d7dc6d5e84d8de8f3 100644 (file)
@@ -25,12 +25,15 @@ class IsolatedAsyncioTestCase(TestCase):
     # them inside the same task.
 
     # Note: the test case modifies event loop policy if the policy was not instantiated
-    # yet.
+    # yet, unless loop_factory=asyncio.EventLoop is set.
     # asyncio.get_event_loop_policy() creates a default policy on demand but never
     # returns None
     # I believe this is not an issue in user level tests but python itself for testing
     # should reset a policy in every test module
     # by calling asyncio.set_event_loop_policy(None) in tearDownModule()
+    # or set loop_factory=asyncio.EventLoop
+
+    loop_factory = None
 
     def __init__(self, methodName='runTest'):
         super().__init__(methodName)
@@ -118,7 +121,7 @@ class IsolatedAsyncioTestCase(TestCase):
 
     def _setupAsyncioRunner(self):
         assert self._asyncioRunner is None, 'asyncio runner is already initialized'
-        runner = asyncio.Runner(debug=True)
+        runner = asyncio.Runner(debug=True, loop_factory=self.loop_factory)
         self._asyncioRunner = runner
 
     def _tearDownAsyncioRunner(self):
diff --git a/Misc/NEWS.d/next/Library/2023-10-12-15-16-44.gh-issue-110774.AdCb5A.rst b/Misc/NEWS.d/next/Library/2023-10-12-15-16-44.gh-issue-110774.AdCb5A.rst
new file mode 100644 (file)
index 0000000..a5a9fed
--- /dev/null
@@ -0,0 +1 @@
+Support setting the :class:`asyncio.Runner` loop_factory kwarg in :class:`unittest.IsolatedAsyncioTestCase`