1 from abc import abstractmethod

2 from signal import Signals

3 from typing import Optional

4

5 from ._resources import AsyncResource

6 from ._streams import ByteReceiveStream, ByteSendStream

7

8

9 class Process(AsyncResource):

10 """An asynchronous version of :class:`subprocess.Popen`."""

11

12 @abstractmethod

13 async def wait(self) -> int:

14 """

15 Wait until the process exits.

16

17 :return: the exit code of the process

18 """

19

20 @abstractmethod

21 def terminate(self) -> None:

22 """

23 Terminates the process, gracefully if possible.

24

25 On Windows, this calls ``TerminateProcess()``.

26 On POSIX systems, this sends ``SIGTERM`` to the process.

27

28 .. seealso:: :meth:`subprocess.Popen.terminate`

29 """

30

31 @abstractmethod

32 def kill(self) -> None:

33 """

34 Kills the process.

35

36 On Windows, this calls ``TerminateProcess()``.

37 On POSIX systems, this sends ``SIGKILL`` to the process.

38

39 .. seealso:: :meth:`subprocess.Popen.kill`

40 """

41

42 @abstractmethod

43 def send_signal(self, signal: Signals) -> None:

44 """

45 Send a signal to the subprocess.

46

47 .. seealso:: :meth:`subprocess.Popen.send_signal`

48

49 :param signal: the signal number (e.g. :data:`signal.SIGHUP`)

50 """

51

52 @property

53 @abstractmethod

54 def pid(self) -> int:

55 """The process ID of the process."""

56

57 @property

58 @abstractmethod

59 def returncode(self) -> Optional[int]:

60 """

61 The return code of the process. If the process has not yet terminated, this will be

62 ``None``.

63 """

64

65 @property

66 @abstractmethod

67 def stdin(self) -> Optional[ByteSendStream]:

68 """The stream for the standard input of the process."""

69

70 @property

71 @abstractmethod

72 def stdout(self) -> Optional[ByteReceiveStream]:

73 """The stream for the standard output of the process."""

74

75 @property

76 @abstractmethod

77 def stderr(self) -> Optional[ByteReceiveStream]:

78 """The stream for the standard error output of the process."""