Skip to content

Commit 7705306

Browse files
graingertambvwillingc
authored
pythongh-110774: allow setting the Runner(loop_factory=...) from IsolatedAsyncioTestCase (python#110776)
Co-authored-by: Łukasz Langa <[email protected]> Co-authored-by: Carol Willing <[email protected]>
1 parent f6a0232 commit 7705306

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

Doc/library/unittest.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,14 @@ Test cases
15711571

15721572
.. versionadded:: 3.8
15731573

1574+
.. attribute:: loop_factory
1575+
1576+
The *loop_factory* passed to :class:`asyncio.Runner`. Override
1577+
in subclasses with :class:`asyncio.EventLoop` to avoid using the
1578+
asyncio policy system.
1579+
1580+
.. versionadded:: 3.13
1581+
15741582
.. coroutinemethod:: asyncSetUp()
15751583

15761584
Method called to prepare the test fixture. This is called after :meth:`setUp`.

Lib/test/test_unittest/test_async_case.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,5 +484,19 @@ async def test_demo1(self):
484484
result = test.run()
485485
self.assertTrue(result.wasSuccessful())
486486

487+
def test_loop_factory(self):
488+
asyncio.set_event_loop_policy(None)
489+
490+
class TestCase1(unittest.IsolatedAsyncioTestCase):
491+
loop_factory = asyncio.EventLoop
492+
493+
async def test_demo1(self):
494+
pass
495+
496+
test = TestCase1('test_demo1')
497+
result = test.run()
498+
self.assertTrue(result.wasSuccessful())
499+
self.assertIsNone(support.maybe_get_event_loop_policy())
500+
487501
if __name__ == "__main__":
488502
unittest.main()

Lib/unittest/async_case.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ class IsolatedAsyncioTestCase(TestCase):
2525
# them inside the same task.
2626

2727
# Note: the test case modifies event loop policy if the policy was not instantiated
28-
# yet.
28+
# yet, unless loop_factory=asyncio.EventLoop is set.
2929
# asyncio.get_event_loop_policy() creates a default policy on demand but never
3030
# returns None
3131
# I believe this is not an issue in user level tests but python itself for testing
3232
# should reset a policy in every test module
3333
# by calling asyncio.set_event_loop_policy(None) in tearDownModule()
34+
# or set loop_factory=asyncio.EventLoop
35+
36+
loop_factory = None
3437

3538
def __init__(self, methodName='runTest'):
3639
super().__init__(methodName)
@@ -118,7 +121,7 @@ def _callMaybeAsync(self, func, /, *args, **kwargs):
118121

119122
def _setupAsyncioRunner(self):
120123
assert self._asyncioRunner is None, 'asyncio runner is already initialized'
121-
runner = asyncio.Runner(debug=True)
124+
runner = asyncio.Runner(debug=True, loop_factory=self.loop_factory)
122125
self._asyncioRunner = runner
123126

124127
def _tearDownAsyncioRunner(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support setting the :class:`asyncio.Runner` loop_factory kwarg in :class:`unittest.IsolatedAsyncioTestCase`

0 commit comments

Comments
 (0)