Skip to content

Commit 914f636

Browse files
GH-95899: fix asyncio.Runner to call set_event_loop only once (#95900)
1 parent 2fa03b1 commit 914f636

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

Lib/asyncio/runners.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ def run(self, coro, *, context=None):
114114

115115
self._interrupt_count = 0
116116
try:
117-
if self._set_event_loop:
118-
events.set_event_loop(self._loop)
119117
return self._loop.run_until_complete(task)
120118
except exceptions.CancelledError:
121119
if self._interrupt_count > 0:
@@ -136,7 +134,11 @@ def _lazy_init(self):
136134
return
137135
if self._loop_factory is None:
138136
self._loop = events.new_event_loop()
139-
self._set_event_loop = True
137+
if not self._set_event_loop:
138+
# Call set_event_loop only once to avoid calling
139+
# attach_loop multiple times on child watchers
140+
events.set_event_loop(self._loop)
141+
self._set_event_loop = True
140142
else:
141143
self._loop = self._loop_factory()
142144
if self._debug is not None:

Lib/test/test_asyncio/test_runners.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,20 @@ async def coro():
455455
):
456456
runner.run(coro())
457457

458+
def test_set_event_loop_called_once(self):
459+
# See https://github.com/python/cpython/issues/95736
460+
async def coro():
461+
pass
462+
463+
policy = asyncio.get_event_loop_policy()
464+
policy.set_event_loop = mock.Mock()
465+
runner = asyncio.Runner()
466+
runner.run(coro())
467+
runner.run(coro())
468+
469+
self.assertEqual(1, policy.set_event_loop.call_count)
470+
runner.close()
471+
458472

459473
if __name__ == '__main__':
460474
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix :class:`asyncio.Runner` to call :func:`asyncio.set_event_loop` only once to avoid calling :meth:`~asyncio.AbstractChildWatcher.attach_loop` multiple times on child watchers. Patch by Kumar Aditya.

0 commit comments

Comments
 (0)