fix resource leak in case need_user_terminal is used
This commit is contained in:
@@ -9,7 +9,7 @@ import sys
|
|||||||
import timeit
|
import timeit
|
||||||
import weakref
|
import weakref
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from contextlib import contextmanager
|
from contextlib import ExitStack, contextmanager
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import IO, Any
|
from typing import IO, Any
|
||||||
@@ -86,6 +86,23 @@ def terminate_process_group(process: subprocess.Popen) -> Iterator[None]:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def terminate_process(process: subprocess.Popen) -> Iterator[None]:
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
process.terminate()
|
||||||
|
try:
|
||||||
|
with contextlib.suppress(subprocess.TimeoutExpired):
|
||||||
|
# give the process time to terminate
|
||||||
|
process.wait(3)
|
||||||
|
finally:
|
||||||
|
process.kill()
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TimeTable:
|
class TimeTable:
|
||||||
"""
|
"""
|
||||||
This class is used to store the time taken by each command
|
This class is used to store the time taken by each command
|
||||||
@@ -146,8 +163,8 @@ def run(
|
|||||||
logger.debug(f"$: {shlex.join(cmd)} \nCaller: {get_caller()}")
|
logger.debug(f"$: {shlex.join(cmd)} \nCaller: {get_caller()}")
|
||||||
start = timeit.default_timer()
|
start = timeit.default_timer()
|
||||||
|
|
||||||
# Start the subprocess
|
with ExitStack() as stack:
|
||||||
with (
|
process = stack.enter_context(
|
||||||
subprocess.Popen(
|
subprocess.Popen(
|
||||||
cmd,
|
cmd,
|
||||||
cwd=str(cwd),
|
cwd=str(cwd),
|
||||||
@@ -155,11 +172,15 @@ def run(
|
|||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
start_new_session=not needs_user_terminal,
|
start_new_session=not needs_user_terminal,
|
||||||
) as process,
|
)
|
||||||
terminate_process_group(process)
|
)
|
||||||
if not needs_user_terminal
|
|
||||||
else contextlib.suppress(), # NOQA: B022
|
if needs_user_terminal:
|
||||||
):
|
# we didn't allocat a new session, so we can't terminate the process group
|
||||||
|
stack.enter_context(terminate_process(process))
|
||||||
|
else:
|
||||||
|
stack.enter_context(terminate_process_group(process))
|
||||||
|
|
||||||
stdout_buf, stderr_buf = handle_output(process, log)
|
stdout_buf, stderr_buf = handle_output(process, log)
|
||||||
|
|
||||||
if input:
|
if input:
|
||||||
|
|||||||
Reference in New Issue
Block a user