Skip to content

Commit

Permalink
Merge pull request #453 from byllyfish/childwatcher
Browse files Browse the repository at this point in the history
Make clear that DefaultChildWatcher is experimental.
  • Loading branch information
byllyfish authored Jul 18, 2023
2 parents d45bbc4 + cde3148 commit 902da6e
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 17 deletions.
5 changes: 0 additions & 5 deletions shellous/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
from .result import Result, ResultError
from .runner import PipeRunner, Runner

if sys.platform != "win32":
from .watcher import DefaultChildWatcher


if sys.version_info[:3] in [(3, 10, 9), (3, 11, 1)]:
# Warn about these specific Python releases: 3.10.9 and 3.11.1
# These releases have a known race condition.
Expand Down Expand Up @@ -55,6 +51,5 @@
"ResultError",
"Runner",
"PipeRunner",
"DefaultChildWatcher",
"AuditEventInfo",
]
5 changes: 4 additions & 1 deletion shellous/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ class _UnsetEnum(enum.Enum):


class AuditEventInfo(TypedDict):
"Info attached to each Audit Event."
"""Info attached to each audit callback event.
See `audit_callback` in `Command.set` for more information.
"""

runner: Runner
"Reference to the Runner object."
Expand Down
9 changes: 6 additions & 3 deletions shellous/watcher.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
"""Implements DefaultChildWatcher.
Design Goals:
1. Independent of any running event loop.
2. Zero-cost until used.
DefaultChildWatcher is an experimental child watcher implementation. With the
the asyncio child watcher API being deprecated in Python 3.12, this code should
not be relied upon other than for testing purposes.
DefaultChildWatcher uses pidfd's on Linux and KQueue on MacOS/FreeBSD. If
neither is available, it falls back to blocking on waitpid in a thread.
References:
- https://developer.apple.com/library/archive/technotes/tn2050/_index.html
Expand Down
12 changes: 5 additions & 7 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

import pytest

import shellous
from shellous import sh

if sys.platform != "win32":
from shellous.watcher import DefaultChildWatcher

_PYPY = platform.python_implementation() == "PyPy"

# Close any file descriptors >= 3. The tests will log file descriptors passed
Expand Down Expand Up @@ -81,11 +83,7 @@ def _init_child_watcher():
asyncio.set_child_watcher(asyncio.PidfdChildWatcher())
elif childwatcher_type == "default":
thread_strategy = os.environ.get("SHELLOUS_THREADSTRATEGY") is not None
asyncio.set_child_watcher(
shellous.DefaultChildWatcher(
thread_strategy=thread_strategy,
)
)
asyncio.set_child_watcher(DefaultChildWatcher(thread_strategy=thread_strategy))


@pytest.fixture(autouse=True)
Expand All @@ -100,7 +98,7 @@ async def report_orphan_tasks():
# Close the childwatcher *before* checking for open fd's.
if sys.platform != "win32":
cw = asyncio.get_child_watcher()
if isinstance(cw, shellous.DefaultChildWatcher):
if isinstance(cw, DefaultChildWatcher):
cw.close()

# Check if any other tasks are still running. Ignore the current task.
Expand Down
2 changes: 1 addition & 1 deletion tests/unix/test_threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from shellous.log import log_method

if sys.platform != "win32":
from shellous import DefaultChildWatcher
from shellous.watcher import DefaultChildWatcher

pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="Unix")

Expand Down

0 comments on commit 902da6e

Please sign in to comment.