Skip to content

Commit

Permalink
Fixed to_process.run_sync() sometimes failing to initialize on Windows (
Browse files Browse the repository at this point in the history
#744)

Fixes #696.
  • Loading branch information
agronholm committed Jun 16, 2024
1 parent 7b4f94e commit 60cd80e
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ This library adheres to `Semantic Versioning 2.0 <http:https://semver.org/>`_.
in ``anyio.Path``, newly added in Python 3.13
- Changed the ``ResourceWarning`` from an unclosed memory object stream to include its
address for easier identification
- Fixed ``to_process.run_sync()`` failing to initialize if ``__main__.__file__`` pointed
to a file in a nonexistent directory
(`#696 <https://github.com/agronholm/anyio/issues/696>`_)

**4.4.0**

Expand Down
3 changes: 1 addition & 2 deletions src/anyio/to_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def process_worker() -> None:
main_module_path: str | None
sys.path, main_module_path = args
del sys.modules["__main__"]
if main_module_path:
if main_module_path and os.path.isfile(main_module_path):
# Load the parent's main module but as __mp_main__ instead of
# __main__ (like multiprocessing does) to avoid infinite recursion
try:
Expand All @@ -234,7 +234,6 @@ def process_worker() -> None:
sys.modules["__main__"] = main
except BaseException as exc:
exception = exc

try:
if exception is not None:
status = b"EXCEPTION"
Expand Down
16 changes: 16 additions & 0 deletions tests/test_to_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import sys
import time
from functools import partial
from pathlib import Path
from unittest.mock import Mock

import pytest
from pytest import MonkeyPatch

from anyio import (
CancelScope,
Expand Down Expand Up @@ -113,3 +115,17 @@ async def test_exec_while_pruning() -> None:
assert idle_workers[0][0] is real_worker
finally:
workers.discard(fake_idle_process)


async def test_nonexistent_main_module(
monkeypatch: MonkeyPatch, tmp_path: Path
) -> None:
"""
Test that worker process creation won't fail if the detected path to the `__main__`
module doesn't exist. Regression test for #696.
"""

script_path = tmp_path / "badscript"
script_path.touch()
monkeypatch.setattr("__main__.__file__", str(script_path / "__main__.py"))
await to_process.run_sync(os.getpid)

0 comments on commit 60cd80e

Please sign in to comment.