From dcc7a5f302af485516295d6838575573429c15c2 Mon Sep 17 00:00:00 2001 From: Nicholas Devenish Date: Thu, 28 Sep 2023 16:04:29 +0100 Subject: [PATCH] Update run_job.run_job This now uses subprocess.run, which takes some of the complexity away of properly running subprocesses. Also, raise an exception if this fails or if the executable can not be found. Fixes #55. --- fast_dp/run_job.py | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/fast_dp/run_job.py b/fast_dp/run_job.py index 84610c2..48cafb2 100644 --- a/fast_dp/run_job.py +++ b/fast_dp/run_job.py @@ -1,46 +1,37 @@ from __future__ import annotations import os +import shutil import subprocess -def run_job(executable, arguments=[], stdin=[], working_directory=None): +def run_job( + executable: str, + arguments: list[str] = [], + stdin=[], + working_directory: str | None = None, +) -> list[str]: """Run a program with some command-line arguments and some input, then return the standard output when it is finished. """ if working_directory is None: working_directory = os.getcwd() - command_line = "%s" % executable - for arg in arguments: - command_line += ' "%s"' % arg + command_line = [shutil.which(executable)] + arguments + if command_line[0] is None: + raise RuntimeError(f"Cannot find executable {executable!r}") - popen = subprocess.Popen( + proc = subprocess.run( command_line, bufsize=1, - stdin=subprocess.PIPE, + input="\n".join(stdin), + text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - cwd=working_directory, - universal_newlines=True, - shell=True, + check=True, ) - for record in stdin: - popen.stdin.write("%s\n" % record) - - popen.stdin.close() - - output = [] - - while True: - record = popen.stdout.readline() - if not record: - break - - output.append(record) - - return output + return proc.stdout.splitlines() if __name__ == "__main__":