Skip to content
2 changes: 1 addition & 1 deletion .github/workflows/Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# test for:
# * oldest supported version
# * latest available Python version
python-version: ['3.10', '3.14']
python-version: ['3.12', '3.14']
# * Linux using ubuntu-latest
# * Windows using windows-latest
os: ['ubuntu-latest', 'windows-latest']
Expand Down
12 changes: 6 additions & 6 deletions OMPython/ModelicaSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,15 +1185,15 @@ def simulate(
cmd_definition = om_cmd.definition()
returncode = self._session.run_model_executable(cmd_run_data=cmd_definition)
# and check returncode *AND* resultfile
if returncode != 0 and self._result_file.is_file():
if returncode != 0:
# check for an empty (=> 0B) result file which indicates a crash of the model executable
# see: https://github.com/OpenModelica/OMPython/issues/261
# https://github.com/OpenModelica/OpenModelica/issues/13829
if self._result_file.size() == 0:
if self._result_file.is_file() and self._result_file.size() == 0:
self._result_file.unlink()
raise ModelicaSystemError("Empty result file - this indicates a crash of the model executable!")

logger.warning(f"Return code = {returncode} but result file exists!")
logger.warning(f"Return code = {returncode} but result file was created!")

self._simulated = True

Expand Down Expand Up @@ -2188,9 +2188,9 @@ def worker(worker_id, task_queue):
try:
returncode = self.get_session().run_model_executable(cmd_run_data=cmd_definition)
logger.info(f"[Worker {worker_id}] Simulation {resultpath.name} "
f"finished with return code: {returncode}")
except ModelicaSystemError as ex:
logger.warning(f"Simulation error for {resultpath.name}: {ex}")
f"finished with return code {returncode}")
except OMCSessionException as ex:
logger.warning(f"Error executing {repr(cmd_definition.get_cmd())}: {ex}")

# Mark the task as done
task_queue.task_done()
Expand Down
58 changes: 2 additions & 56 deletions OMPython/OMCSession.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def getClassNames(self, className=None, recursive=False, qualified=False, sort=F
return self._ask(question='getClassNames', opt=opt)


class OMCPathReal(pathlib.PurePosixPath):
class OMCPath(pathlib.PurePosixPath):
"""
Implementation of a basic (PurePosix)Path object which uses OMC as backend. The connection to OMC is provided via an
instances of OMCSession* classes.
Expand Down Expand Up @@ -415,49 +415,6 @@ def stat(self):
"use size() to get the file size.")


if sys.version_info < (3, 12):

class OMCPathCompatibility(pathlib.Path):
"""
Compatibility class for OMCPath in Python < 3.12. This allows to run all code which uses OMCPath (mainly
ModelicaSystem) on these Python versions. There is one remaining limitation: only OMCProcessLocal will work as
OMCPathCompatibility is based on the standard pathlib.Path implementation.
"""

# modified copy of pathlib.Path.__new__() definition
def __new__(cls, *args, **kwargs):
logger.warning("Python < 3.12 - using a version of class OMCPath "
"based on pathlib.Path for local usage only.")

if cls is OMCPathCompatibility:
cls = OMCPathCompatibilityWindows if os.name == 'nt' else OMCPathCompatibilityPosix
self = cls._from_parts(args)
if not self._flavour.is_supported:
raise NotImplementedError(f"cannot instantiate {cls.__name__} on your system")
return self

def size(self) -> int:
"""
Needed compatibility function to have the same interface as OMCPathReal
"""
return self.stat().st_size

class OMCPathCompatibilityPosix(pathlib.PosixPath, OMCPathCompatibility):
"""
Compatibility class for OMCPath on Posix systems (Python < 3.12)
"""

class OMCPathCompatibilityWindows(pathlib.WindowsPath, OMCPathCompatibility):
"""
Compatibility class for OMCPath on Windows systems (Python < 3.12)
"""

OMCPath = OMCPathCompatibility

else:
OMCPath = OMCPathReal


@dataclasses.dataclass
class OMCSessionRunData:
"""
Expand Down Expand Up @@ -770,13 +727,6 @@ def omcpath(self, *path) -> OMCPath:
"""
Create an OMCPath object based on the given path segments and the current OMCSession* class.
"""

# fallback solution for Python < 3.12; a modified pathlib.Path object is used as OMCPath replacement
if sys.version_info < (3, 12):
if isinstance(self, OMCSessionLocal):
# noinspection PyArgumentList
return OMCPath(*path)
raise OMCSessionException("OMCPath is supported for Python < 3.12 only if OMCSessionLocal is used!")
return OMCPath(*path, session=self)

def omcpath_tempdir(self, tempdir_base: Optional[OMCPath] = None) -> OMCPath:
Expand All @@ -787,11 +737,7 @@ def omcpath_tempdir(self, tempdir_base: Optional[OMCPath] = None) -> OMCPath:
names = [str(uuid.uuid4()) for _ in range(100)]

if tempdir_base is None:
# fallback solution for Python < 3.12; a modified pathlib.Path object is used as OMCPath replacement
if sys.version_info < (3, 12):
tempdir_str = tempfile.gettempdir()
else:
tempdir_str = self.sendExpression("getTempDirectoryPath()")
tempdir_str = self.sendExpression(command="getTempDirectoryPath()")
tempdir_base = self.omcpath(tempdir_str)

tempdir: Optional[OMCPath] = None
Expand Down
Loading