Coverage for procpath/treefarm.py: 97%

96 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2026-02-24 19:20 +0000

1import asyncio.subprocess 

2import contextlib 

3import logging 

4import os 

5import signal 

6import sys 

7from typing import Dict, List 

8 

9from . import procfile, proctree 

10 

11 

12__all__ = 'process_exists', 'TreeFarm', 

13 

14logger = logging.getLogger(__package__) 

15 

16 

17class TreeFarm: 

18 """ 

19 An asynchronous process collection manager. 

20 

21 Each watched command is spawned in a separate shell in a separate 

22 process group [#]_ [#]_. Without separate process groups the 

23 behaviour would have been different in foreground and background 

24 cases, from getpgrp(2): 

25 

26 A session can have a controlling terminal. At any time, one 

27 (and only one) of the process groups in the session can be the 

28 foreground process group for the terminal; the remaining 

29 process groups are in the background. If a signal is generated 

30 from the terminal (e.g., typing the interrupt key to generate 

31 SIGINT), that signal is sent to the foreground process group. 

32 

33 Thus without separate process groups in the foreground case 

34 ``watch`` process would only get control in its ``SIGINT`` handler 

35 at the same time (there's race but the handler usually loses it) 

36 as its shell processes. And in background ``SIGINT`` would only 

37 terminate the outer sessions leaving the command trees orphaned. 

38 

39 .. [#] https://pymotw.com/2/subprocess/#process-groups-sessions 

40 .. [#] https://stackoverflow.com/q/1046933 

41 """ 

42 

43 _stop_signal: signal.Signals 

44 _kill_after: float 

45 _read_buffer_size: int 

46 

47 _process_list: List[asyncio.subprocess.Process] 

48 

49 def __init__(self, stop_signal: str, kill_after: float, read_buffer_size: int = 2**16): 

50 self._stop_signal = signal.Signals[stop_signal] (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

51 self._kill_after = kill_after (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

52 self._read_buffer_size = read_buffer_size (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

53 

54 self._process_list = [] (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

55 

56 async def _forward_stream(self, stream_reader: asyncio.StreamReader, number: int, level: int): 

57 while True: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

58 try: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

59 async for line in stream_reader: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

60 logger.log(level, '№%d: %s', number, line.strip().decode()) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

61 except ValueError as ex: procpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

62 if isinstance(ex.__context__, asyncio.exceptions.LimitOverrunError): 62 ↛ 65line 62 didn't jump to line 65, because the condition on line 62 was never falseprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

63 logger.exception(str(ex.__context__)) procpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

64 else: 

65 raise 

66 else: 

67 break (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

68 

69 async def _spawn(self, cmd: str, number: int, env: dict) -> asyncio.subprocess.Process: 

70 logger.debug('Starting №%d: %s', number, cmd) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

71 process = await asyncio.create_subprocess_shell( (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

72 cmd, 

73 env=dict(os.environ, **env), 

74 stdout=asyncio.subprocess.PIPE, 

75 stderr=asyncio.subprocess.PIPE, 

76 limit=self._read_buffer_size, 

77 # Start each shell in its own process group and be the 

78 # group leader. "start_new_session=True" or 

79 # "preexec_fn=os.setsid" would have achieved the same 

80 # result (new process group created), but the session is 

81 # not needed here. In Python 3.11+ there's "process_group" 

82 # argument that is recommended instead of "preexec_fn". 

83 preexec_fn=os.setpgrp, 

84 ) 

85 logger.debug('Started №%d shell as PID %s', number, process.pid) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

86 asyncio.ensure_future(self._forward_stream(process.stdout, number, logging.INFO)) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

87 asyncio.ensure_future(self._forward_stream(process.stderr, number, logging.WARNING)) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

88 return process (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

89 

90 async def spawn_at(self, number: int, cmd: str, shell_env: Dict[str, str]) -> int: 

91 try: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

92 process = self._process_list[number - 1] (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

93 except IndexError: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

94 process = await self._spawn(cmd, number, shell_env) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

95 self._process_list.append(process) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

96 else: 

97 if process.returncode is not None: (empty)procpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposed

98 logger.info('№%d exited with code %d, restarting', number, process.returncode) (empty)procpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposed

99 process = await self._spawn(cmd, number, shell_env) (empty)procpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposed

100 self._process_list[number - 1] = process (empty)procpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposed

101 

102 return process.pid (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

103 

104 def is_terminated(self) -> bool: 

105 return all(p.returncode is not None for p in self._process_list) procpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

106 

107 async def terminate(self): 

108 """ 

109 Interrupt shell processes by sending stop signal, then SIGKILL. 

110 

111 Interruption is done in two phases. First, all top-level shell 

112 process groups receive the stop signal and are given 

113 ``kill_after`` seconds to terminate, hopefully with all their 

114 descendants. Second, each process of the forest that existed at 

115 the start of the call, that is still alive, is killed. 

116 """ 

117 

118 forest = proctree.Forest({'stat': procfile.registry['stat']}, skip_self=False) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

119 query = '$..children[?(@.stat.ppid == {})]..stat.pid'.format(os.getpid()) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

120 forest_pids = proctree.query(forest.get_roots(), query) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

121 logger.debug('Forest PIDs to terminate: %s', ', '.join(map(str, forest_pids))) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

122 

123 await self._destroy_shells() (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

124 

125 for pid in [p for p in forest_pids if process_exists(p)]: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

126 logger.debug('Killing unterminated descendant PID %s', pid) 

127 with contextlib.suppress(ProcessLookupError): # in case it has just terminated 

128 os.kill(pid, signal.SIGKILL) 

129 

130 def _is_kill_on_tight_loop(self): 

131 """ 

132 Workaround tight `.asyncio` loop after process killing. 

133 

134 Asyncio subprocess functionality hasn't been stable recently: 

135 GH-88050, GH-100133, GH-109490, GH-109538, GH-114177. Here it 

136 manifests with the ``shell_proc.wait()`` not cleaning up itself 

137 after the process has just been killed. Python 3.10 and earlier 

138 are good, whereas newer ones seem suffice with a bit of space 

139 on the loop as a workaround. 

140 """ 

141 

142 return (3, 11) <= sys.version_info < (3, 15) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

143 

144 async def _destroy_shells(self): 

145 for shell_proc in self._process_list: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

146 logger.debug('Sending %s to shell PGRP %s', self._stop_signal.name, shell_proc.pid) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

147 with contextlib.suppress(ProcessLookupError): (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

148 os.killpg(shell_proc.pid, self._stop_signal) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

149 

150 if self._is_kill_on_tight_loop(): 150 ↛ 153line 150 didn't jump to line 153, because the condition on line 150 was never false(empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

151 await asyncio.sleep(0.001) # <= 0 is a short-circuited sleep (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

152 

153 shell_wait = asyncio.gather(*[sp.wait() for sp in self._process_list]) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

154 try: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

155 await asyncio.wait_for(shell_wait, timeout=self._kill_after) (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

156 except asyncio.TimeoutError: 

157 logger.debug('Not all shell processes terminated after stop signal') 

158 with contextlib.suppress(asyncio.CancelledError): 

159 await shell_wait 

160 else: 

161 shell_pids = [sp.pid for sp in self._process_list] (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

162 logger.debug( (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

163 'Shell processes successfully terminated: %s', ', '.join(map(str, shell_pids)) 

164 ) 

165 

166 for shell_proc in self._process_list: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

167 if shell_proc.returncode is None: (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

168 logger.debug('Killing unterminated shell PID %s', shell_proc.pid) 

169 with contextlib.suppress(ProcessLookupError): # in case it has just terminated 

170 shell_proc.kill() 

171 

172 if self._is_kill_on_tight_loop(): 172 ↛ 175line 172 didn't jump to line 175, because the condition on line 172 was never false

173 await asyncio.sleep(0.001) # <= 0 is a short-circuited sleep 

174 

175 await shell_proc.wait() 

176 

177 async def __aenter__(self): 

178 return self (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

179 

180 async def __aexit__(self, *args): 

181 await self.terminate() (empty)procpath.test.cmd.TestPlayCommand.test_play_watchprocpath.test.cmd.TestPlayCommand.test_play_watch_overrideprocpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_no_restart_no_reevalprocpath.test.cmd.TestWatchCommand.test_watch_process_pids_exposedprocpath.test.cmd.TestWatchCommand.test_watch_query_errorprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_loggingprocpath.test.cmd.TestWatchCommand.test_watch_std_stream_write_after_stopprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_resume_after_overrunprocpath.test.cmd.TestWatchCommand.test_watch_stream_read_buffer_size

182 

183 

184def process_exists(pid: int) -> bool: 

185 try: (empty)procpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_environmentprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_queryprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_by_sigtermprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_errorprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_repeat_endprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigintprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_firstprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_killprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_ptyprocpath.test.cmd.TestWatchCommand.test_watch_verbatim_commandsprocpath.test.unit.TestTreeFarm.test_process_exists

186 os.kill(pid, 0) (empty)procpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_environmentprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_queryprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_by_sigtermprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_errorprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_repeat_endprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigintprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_firstprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_killprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_ptyprocpath.test.cmd.TestWatchCommand.test_watch_verbatim_commandsprocpath.test.unit.TestTreeFarm.test_process_exists

187 except OSError: (empty)procpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_environmentprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_queryprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_by_sigtermprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_errorprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_repeat_endprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigintprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_firstprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_killprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_ptyprocpath.test.cmd.TestWatchCommand.test_watch_verbatim_commandsprocpath.test.unit.TestTreeFarm.test_process_exists

188 return False (empty)procpath.test.cmd.TestWatchCommand.test_watch_empty_env_command_resultprocpath.test.cmd.TestWatchCommand.test_watch_empty_query_resultprocpath.test.cmd.TestWatchCommand.test_watch_environmentprocpath.test.cmd.TestWatchCommand.test_watch_no_restartprocpath.test.cmd.TestWatchCommand.test_watch_queryprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_by_sigtermprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_errorprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_repeat_endprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigintprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_firstprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_killprocpath.test.cmd.TestWatchCommand.test_watch_tree_cleanup_on_sigint_shell_first_ptyprocpath.test.cmd.TestWatchCommand.test_watch_verbatim_commandsprocpath.test.unit.TestTreeFarm.test_process_exists

189 else: 

190 return True (empty)procpath.test.unit.TestTreeFarm.test_process_exists