Skip to content

Commit 5ff9a03

Browse files
Fix Windows compatibility for process group tests
The start_new_session=True parameter in anyio.open_process() is Unix-specific and causes child processes not to start properly on Windows. This fix: - Adds WindowsProcessWrapper class to provide anyio-compatible interface for subprocess.Popen on Windows - Uses CREATE_NEW_PROCESS_GROUP flag on Windows instead of start_new_session - Maintains Unix behavior with start_new_session=True for process group creation This ensures the child process cleanup tests work correctly on both Windows and Unix platforms.
1 parent e4b79c9 commit 5ff9a03

File tree

1 file changed

+48
-4
lines changed

1 file changed

+48
-4
lines changed

tests/client/test_stdio.py

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import shutil
3+
import subprocess
34
import sys
45
import tempfile
56
import textwrap
@@ -21,6 +22,25 @@
2122
python: str = shutil.which("python") # type: ignore
2223

2324

25+
class WindowsProcessWrapper:
26+
"""Minimal wrapper for subprocess.Popen to work with anyio-style process interface."""
27+
28+
def __init__(self, popen):
29+
self.pid = popen.pid
30+
self._popen = popen
31+
32+
async def wait(self):
33+
while self._popen.poll() is None:
34+
await anyio.sleep(0.1)
35+
return self._popen.returncode
36+
37+
def terminate(self):
38+
self._popen.terminate()
39+
40+
def kill(self):
41+
self._popen.kill()
42+
43+
2444
@pytest.mark.anyio
2545
@pytest.mark.skipif(tee is None, reason="could not find tee command")
2646
async def test_stdio_context_manager_exiting():
@@ -120,7 +140,7 @@ async def test_stdio_client_universal_cleanup():
120140
sys.stderr.flush()
121141
"""
122142
)
123-
143+
124144
server_params = StdioServerParameters(
125145
command=sys.executable,
126146
args=["-c", long_running_script],
@@ -386,7 +406,15 @@ async def test_stdio_client_child_process_cleanup():
386406
print("\nStarting child process termination test...")
387407

388408
# Start the parent process directly with process group
389-
proc = await anyio.open_process([sys.executable, "-c", parent_script], start_new_session=True)
409+
if sys.platform == "win32":
410+
# Windows: Use subprocess.Popen with CREATE_NEW_PROCESS_GROUP flag
411+
popen = subprocess.Popen(
412+
[sys.executable, "-c", parent_script], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
413+
)
414+
proc = WindowsProcessWrapper(popen)
415+
else:
416+
# Unix: Use start_new_session for process group creation
417+
proc = await anyio.open_process([sys.executable, "-c", parent_script], start_new_session=True)
390418

391419
# Wait for processes to start
392420
await anyio.sleep(0.5)
@@ -492,7 +520,15 @@ async def test_stdio_client_nested_process_tree():
492520
)
493521

494522
# Start parent process directly
495-
proc = await anyio.open_process([sys.executable, "-c", parent_script], start_new_session=True)
523+
if sys.platform == "win32":
524+
# Windows: Use subprocess.Popen with CREATE_NEW_PROCESS_GROUP flag
525+
popen = subprocess.Popen(
526+
[sys.executable, "-c", parent_script], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
527+
)
528+
proc = WindowsProcessWrapper(popen)
529+
else:
530+
# Unix: Use start_new_session for process group creation
531+
proc = await anyio.open_process([sys.executable, "-c", parent_script], start_new_session=True)
496532

497533
# Let all processes start
498534
await anyio.sleep(1.0)
@@ -575,7 +611,15 @@ def handle_term(sig, frame):
575611
)
576612

577613
# Start the parent process
578-
proc = await anyio.open_process([sys.executable, "-c", parent_script], start_new_session=True)
614+
if sys.platform == "win32":
615+
# Windows: Use subprocess.Popen with CREATE_NEW_PROCESS_GROUP flag
616+
popen = subprocess.Popen(
617+
[sys.executable, "-c", parent_script], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
618+
)
619+
proc = WindowsProcessWrapper(popen)
620+
else:
621+
# Unix: Use start_new_session for process group creation
622+
proc = await anyio.open_process([sys.executable, "-c", parent_script], start_new_session=True)
579623

580624
# Let child start writing
581625
await anyio.sleep(0.5)

0 commit comments

Comments
 (0)