Skip to content

Commit 7ffdfb7

Browse files
syntronadeas31
andauthored
Use subprocess.run (#273)
* [ModelicaSystem] simplify subprocess.Popen() => use subprocess.run() * [ModelicaSystem] add timeout to subprocess.run() in _run_cmd() * [ModelicaSystem._run_cmd()] differentiate between OM error and nonzero return code * [ModelicaSystem.linearize()] fix docstring / add description for timeout * [ModelicaSystem] provide return code in log message --------- Co-authored-by: Adeel Asghar <adeel.asghar@liu.se>
1 parent 1ff0843 commit 7ffdfb7

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

OMPython/ModelicaSystem.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def setTempDirectory(self, customBuildDirectory):
287287
def getWorkDirectory(self):
288288
return self.tempdir
289289

290-
def _run_cmd(self, cmd: list):
290+
def _run_cmd(self, cmd: list, timeout: Optional[int] = None):
291291
logger.debug("Run OM command %s in %s", cmd, self.tempdir)
292292

293293
if platform.system() == "Windows":
@@ -310,19 +310,18 @@ def _run_cmd(self, cmd: list):
310310
my_env = None
311311

312312
try:
313-
p = subprocess.Popen(cmd, env=my_env, stdout=subprocess.PIPE,
314-
stderr=subprocess.PIPE, cwd=self.tempdir)
315-
stdout, stderr = p.communicate()
316-
317-
stdout = stdout.decode('ascii').strip()
318-
stderr = stderr.decode('ascii').strip()
313+
cmdres = subprocess.run(cmd, capture_output=True, text=True, env=my_env, cwd=self.tempdir,
314+
timeout=timeout)
315+
stdout = cmdres.stdout.strip()
316+
stderr = cmdres.stderr.strip()
317+
if cmdres.returncode != 0:
318+
raise ModelicaSystemError(f"Error running command {cmd}: return code = {cmdres.returncode}")
319319
if stderr:
320320
raise ModelicaSystemError(f"Error running command {cmd}: {stderr}")
321321
if self._verbose and stdout:
322322
logger.info("OM output for command %s:\n%s", cmd, stdout)
323-
# check process returncode, some errors don't print to stderr
324-
if p.wait():
325-
raise ModelicaSystemError(f"Error running command {cmd}: nonzero returncode")
323+
except subprocess.TimeoutExpired:
324+
raise ModelicaSystemError(f"Timeout running command {repr(cmd)}")
326325
except Exception as e:
327326
raise ModelicaSystemError(f"Exception {type(e)} running command {cmd}: {e}")
328327

@@ -675,7 +674,7 @@ def get_exe_file(self) -> pathlib.Path:
675674
else:
676675
return pathlib.Path(self.tempdir) / self.modelName
677676

678-
def simulate(self, resultfile=None, simflags=None): # 11
677+
def simulate(self, resultfile=None, simflags=None, timeout: Optional[int] = None): # 11
679678
"""
680679
This method simulates model according to the simulation options.
681680
usage
@@ -738,7 +737,7 @@ def simulate(self, resultfile=None, simflags=None): # 11
738737

739738
cmd = exe_file.as_posix() + override + csvinput + r + simflags
740739
cmd = [s for s in cmd.split(' ') if s]
741-
self._run_cmd(cmd=cmd)
740+
self._run_cmd(cmd=cmd, timeout=timeout)
742741
self.simulationFlag = True
743742

744743
# to extract simulation results
@@ -1055,13 +1054,15 @@ def optimize(self): # 21
10551054

10561055
return optimizeResult
10571056

1058-
def linearize(self, lintime: Optional[float] = None, simflags: Optional[str] = None) -> LinearizationResult:
1057+
def linearize(self, lintime: Optional[float] = None, simflags: Optional[str] = None,
1058+
timeout: Optional[int] = None) -> LinearizationResult:
10591059
"""Linearize the model according to linearOptions.
10601060
10611061
Args:
10621062
lintime: Override linearOptions["stopTime"] value.
10631063
simflags: A string of extra command line flags for the model
10641064
binary.
1065+
timeout: Possible timeout for the execution of OM.
10651066
10661067
Returns:
10671068
A LinearizationResult object is returned. This allows several
@@ -1116,7 +1117,7 @@ def linearize(self, lintime: Optional[float] = None, simflags: Optional[str] = N
11161117
else:
11171118
cmd = exe_file.as_posix() + linruntime + override + csvinput + simflags
11181119
cmd = [s for s in cmd.split(' ') if s]
1119-
self._run_cmd(cmd=cmd)
1120+
self._run_cmd(cmd=cmd, timeout=timeout)
11201121

11211122
# code to get the matrix and linear inputs, outputs and states
11221123
linearFile = pathlib.Path(self.tempdir) / "linearized_model.py"

0 commit comments

Comments
 (0)