1 from __future__ import annotations 2 3 from abc import abstractmethod 4 from signal import Signals 5 6 from ._resources import AsyncResource 7 from ._streams import ByteReceiveStream, ByteSendStream 8 9 10 class Process(AsyncResource): 11 """An asynchronous version of :class:`subprocess.Popen`.""" 12 13 @abstractmethod 14 async def wait(self) -> int: 15 """ 16 Wait until the process exits. 17 18 :return: the exit code of the process 19 """ 20 21 @abstractmethod 22 def terminate(self) -> None: 23 """ 24 Terminates the process, gracefully if possible. 25 26 On Windows, this calls ``TerminateProcess()``. 27 On POSIX systems, this sends ``SIGTERM`` to the process. 28 29 .. seealso:: :meth:`subprocess.Popen.terminate` 30 """ 31 32 @abstractmethod 33 def kill(self) -> None: 34 """ 35 Kills the process. 36 37 On Windows, this calls ``TerminateProcess()``. 38 On POSIX systems, this sends ``SIGKILL`` to the process. 39 40 .. seealso:: :meth:`subprocess.Popen.kill` 41 """ 42 43 @abstractmethod 44 def send_signal(self, signal: Signals) -> None: 45 """ 46 Send a signal to the subprocess. 47 48 .. seealso:: :meth:`subprocess.Popen.send_signal` 49 50 :param signal: the signal number (e.g. :data:`signal.SIGHUP`) 51 """ 52 53 @property 54 @abstractmethod 55 def pid(self) -> int: 56 """The process ID of the process.""" 57 58 @property 59 @abstractmethod 60 def returncode(self) -> int | None: 61 """ 62 The return code of the process. If the process has not yet terminated, this will 63 be ``None``. 64 """ 65 66 @property 67 @abstractmethod 68 def stdin(self) -> ByteSendStream | None: 69 """The stream for the standard input of the process.""" 70 71 @property 72 @abstractmethod 73 def stdout(self) -> ByteReceiveStream | None: 74 """The stream for the standard output of the process.""" 75 76 @property 77 @abstractmethod 78 def stderr(self) -> ByteReceiveStream | None: 79 """The stream for the standard error output of the process.""" 80