Skip to content

Commit 60cd80e

Browse files
authored
Fixed to_process.run_sync() sometimes failing to initialize on Windows (#744)
Fixes #696.
1 parent 7b4f94e commit 60cd80e

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

docs/versionhistory.rst

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
99
in ``anyio.Path``, newly added in Python 3.13
1010
- Changed the ``ResourceWarning`` from an unclosed memory object stream to include its
1111
address for easier identification
12+
- Fixed ``to_process.run_sync()`` failing to initialize if ``__main__.__file__`` pointed
13+
to a file in a nonexistent directory
14+
(`#696 <https://github.com/agronholm/anyio/issues/696>`_)
1215

1316
**4.4.0**
1417

src/anyio/to_process.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ def process_worker() -> None:
223223
main_module_path: str | None
224224
sys.path, main_module_path = args
225225
del sys.modules["__main__"]
226-
if main_module_path:
226+
if main_module_path and os.path.isfile(main_module_path):
227227
# Load the parent's main module but as __mp_main__ instead of
228228
# __main__ (like multiprocessing does) to avoid infinite recursion
229229
try:
@@ -234,7 +234,6 @@ def process_worker() -> None:
234234
sys.modules["__main__"] = main
235235
except BaseException as exc:
236236
exception = exc
237-
238237
try:
239238
if exception is not None:
240239
status = b"EXCEPTION"

tests/test_to_process.py

+16
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
import sys
55
import time
66
from functools import partial
7+
from pathlib import Path
78
from unittest.mock import Mock
89

910
import pytest
11+
from pytest import MonkeyPatch
1012

1113
from anyio import (
1214
CancelScope,
@@ -113,3 +115,17 @@ async def test_exec_while_pruning() -> None:
113115
assert idle_workers[0][0] is real_worker
114116
finally:
115117
workers.discard(fake_idle_process)
118+
119+
120+
async def test_nonexistent_main_module(
121+
monkeypatch: MonkeyPatch, tmp_path: Path
122+
) -> None:
123+
"""
124+
Test that worker process creation won't fail if the detected path to the `__main__`
125+
module doesn't exist. Regression test for #696.
126+
"""
127+
128+
script_path = tmp_path / "badscript"
129+
script_path.touch()
130+
monkeypatch.setattr("__main__.__file__", str(script_path / "__main__.py"))
131+
await to_process.run_sync(os.getpid)

0 commit comments

Comments
 (0)