Skip to content

Commit 33a38b8

Browse files
Switch to ThreadedChildWatcher and test (#5877)
Co-authored-by: Sviatoslav Sydorenko <[email protected]>
1 parent 98d97cc commit 33a38b8

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

CHANGES/5877.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Uses :py:class:`~asyncio.ThreadedChildWatcher` under POSIX to allow setting up test loop in non-main thread.

aiohttp/test_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ def setup_test_loop(
497497
# * https://stackoverflow.com/a/58614689/595220
498498
# * https://bugs.python.org/issue35621
499499
# * https://github.com/python/cpython/pull/14344
500-
watcher = asyncio.MultiLoopChildWatcher()
500+
watcher = asyncio.ThreadedChildWatcher()
501501
except AttributeError: # Python < 3.8
502502
watcher = asyncio.SafeChildWatcher()
503503
watcher.attach_loop(loop)

tests/test_loop.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
import pytest
77

88
from aiohttp import web
9-
from aiohttp.test_utils import AioHTTPTestCase
9+
from aiohttp.helpers import PY_38
10+
from aiohttp.test_utils import AioHTTPTestCase, loop_context
1011

1112

1213
@pytest.mark.skipif(
1314
platform.system() == "Windows", reason="the test is not valid for Windows"
1415
)
1516
async def test_subprocess_co(loop: Any) -> None:
16-
assert threading.current_thread() is threading.main_thread()
17+
assert PY_38 or threading.current_thread() is threading.main_thread()
1718
proc = await asyncio.create_subprocess_shell(
1819
"exit 0",
1920
stdin=asyncio.subprocess.DEVNULL,
@@ -43,3 +44,24 @@ def test_default_loop(self) -> None:
4344

4445
def test_default_loop(loop: Any) -> None:
4546
assert asyncio.get_event_loop() is loop
47+
48+
49+
@pytest.mark.xfail(not PY_38, reason="ThreadedChildWatcher is only available in 3.8+")
50+
def test_setup_loop_non_main_thread() -> None:
51+
child_exc = None
52+
53+
def target() -> None:
54+
try:
55+
with loop_context() as loop:
56+
assert asyncio.get_event_loop() is loop
57+
loop.run_until_complete(test_subprocess_co(loop))
58+
except Exception as exc:
59+
nonlocal child_exc
60+
child_exc = exc
61+
62+
# Ensures setup_test_loop can be called by pytest-xdist in non-main thread.
63+
t = threading.Thread(target=target)
64+
t.start()
65+
t.join()
66+
67+
assert child_exc is None

0 commit comments

Comments
 (0)