Skip to content

Commit f2cd718

Browse files
committed
[OMCPath] implementation version 3
* differentiate between * Python >= 3.12 uses OMCPath based on OMC for filesystem operation * Python < 3.12 uses a pathlib.Path based implementation which is limited to OMCProcessLocal
1 parent 7f86ff6 commit f2cd718

1 file changed

Lines changed: 58 additions & 23 deletions

File tree

OMPython/OMCSession.py

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ class OMCPathReal(pathlib.PurePosixPath):
277277
OMCSessionZMQ session object.
278278
"""
279279

280-
def __init__(self, *path, session: OMCSessionZMQ):
280+
def __init__(self, *path, session: OMCSessionZMQ) -> None:
281281
super().__init__(*path)
282282
self._session = session
283283

@@ -289,27 +289,28 @@ def with_segments(self, *pathsegments):
289289
"""
290290
return type(self)(*pathsegments, session=self._session)
291291

292-
def is_file(self) -> bool:
292+
def is_file(self, *, follow_symlinks=True) -> bool:
293293
"""
294294
Check if the path is a regular file.
295295
"""
296296
return self._session.sendExpression(f'regularFileExists("{self.as_posix()}")')
297297

298-
def is_dir(self) -> bool:
298+
def is_dir(self, *, follow_symlinks=True) -> bool:
299299
"""
300300
Check if the path is a directory.
301301
"""
302302
return self._session.sendExpression(f'directoryExists("{self.as_posix()}")')
303303

304-
def read_text(self, encoding=None, errors=None) -> str:
304+
def read_text(self, encoding=None, errors=None, newline=None) -> str:
305305
"""
306306
Read the content of the file represented by this path as text.
307307
308-
The additional arguments `encoding` and `errors` are only defined for compatibility with Path() definitions.
308+
The additional arguments `encoding`, `errors` and `newline` are only defined for compatibility with Path()
309+
definition.
309310
"""
310311
return self._session.sendExpression(f'readFile("{self.as_posix()}")')
311312

312-
def write_text(self, data: str, encoding=None, errors=None, newline=None) -> bool:
313+
def write_text(self, data: str, encoding=None, errors=None, newline=None):
313314
"""
314315
Write text data to the file represented by this path.
315316
@@ -340,16 +341,15 @@ def cwd(self):
340341
cwd_str = self._session.sendExpression('cd()')
341342
return OMCPath(cwd_str, session=self._session)
342343

343-
def unlink(self, missing_ok: bool = False) -> bool:
344+
def unlink(self, missing_ok: bool = False) -> None:
344345
"""
345346
Unlink (delete) the file or directory represented by this path.
346347
"""
347348
res = self._session.sendExpression(f'deleteFile("{self.as_posix()}")')
348349
if not res and not missing_ok:
349350
raise FileNotFoundError(f"Cannot delete file {self.as_posix()} - it does not exists!")
350-
return res
351351

352-
def resolve(self, strict: bool = False) -> OMCPath:
352+
def resolve(self, strict: bool = False):
353353
"""
354354
Resolve the path to an absolute path. This is done based on available OMC functions.
355355
"""
@@ -365,7 +365,7 @@ def resolve(self, strict: bool = False) -> OMCPath:
365365

366366
return omcpath
367367

368-
def _omc_resolve(self, pathstr: str) -> OMCPath:
368+
def _omc_resolve(self, pathstr: str):
369369
"""
370370
Internal function to resolve the path of the OMCPath object using OMC functions *WITHOUT* changing the cwd
371371
within OMC.
@@ -389,7 +389,7 @@ def _omc_resolve(self, pathstr: str) -> OMCPath:
389389

390390
return omcpath_resolved
391391

392-
def absolute(self) -> OMCPath:
392+
def absolute(self):
393393
"""
394394
Resolve the path to an absolute path. This is done by calling resolve() as it is the best we can do
395395
using OMC functions.
@@ -417,18 +417,42 @@ def size(self) -> int:
417417

418418

419419
if sys.version_info < (3, 12):
420-
warnings.warn(
421-
message="Python < 3.12 - using a limited compatibility class as OMCPath replacement.",
422-
category=DeprecationWarning,
423-
stacklevel=1,
424-
)
425420

426-
class OMCPathCompatibility(pathlib.PosixPath):
421+
class OMCPathCompatibility:
422+
"""
423+
Compatibility class for OMCPath in Python < 3.12. This allows to run all code which uses OMCPath (mainly
424+
ModelicaSystem) on these Python versions. There is one remaining limitation: only OMCProcessLocal will work as
425+
OMCPathCompatibility is based on the standard pathlib.Path implementation.
426+
"""
427+
428+
# modified copy of pathlib.Path.__new__() definition
429+
def __new__(cls, *args, **kwargs):
430+
logger.warning("Python < 3.12 - using a limited version of class OMCPath.")
431+
432+
if cls is OMCPathCompatibility:
433+
cls = OMCPathCompatibilityWindows if os.name == 'nt' else OMCPathCompatibilityPosix
434+
self = cls._from_parts(args)
435+
if not self._flavour.is_supported:
436+
raise NotImplementedError("cannot instantiate %r on your system"
437+
% (cls.__name__,))
438+
return self
427439

428440
def size(self) -> int:
441+
"""
442+
Needed compatibility function to have the same interface as OMCPathReal
443+
"""
429444
return self.stat().st_size
430445

431-
OMCPath = OMCPathCompatibility # noqa: F811
446+
447+
class OMCPathCompatibilityPosix(pathlib.PosixPath, OMCPathCompatibility):
448+
pass
449+
450+
451+
class OMCPathCompatibilityWindows(pathlib.WindowsPath, OMCPathCompatibility):
452+
pass
453+
454+
455+
OMCPath = OMCPathCompatibility
432456

433457
else:
434458
OMCPath = OMCPathReal
@@ -495,19 +519,30 @@ def omcpath(self, *path) -> OMCPath:
495519

496520
# fallback solution for Python < 3.12; a modified pathlib.Path object is used as OMCPath replacement
497521
if sys.version_info < (3, 12):
498-
# noinspection PyArgumentList
499-
return OMCPath(*path)
522+
if isinstance(self.omc_process, OMCProcessLocal):
523+
# noinspection PyArgumentList
524+
return OMCPath(*path)
525+
else:
526+
raise OMCSessionException("OMCPath is supported for Python < 3.12 only if OMCProcessLocal is used!")
500527
else:
501528
return OMCPath(*path, session=self)
502529

503-
def omcpath_tempdir(self) -> OMCPath:
530+
def omcpath_tempdir(self, tempdir_base: Optional[OMCPath] = None) -> OMCPath:
504531
"""
505532
Get a temporary directory using OMC.
506533
"""
534+
# fallback solution for Python < 3.12; a modified pathlib.Path object is used as OMCPath replacement
535+
if sys.version_info < (3, 12):
536+
tempdir_str = tempfile.gettempdir()
537+
# noinspection PyArgumentList
538+
return OMCPath(tempdir_str)
539+
507540
names = [str(uuid.uuid4()) for _ in range(100)]
508541

509-
tempdir_str = self.sendExpression("getTempDirectoryPath()")
510-
tempdir_base = self.omcpath(tempdir_str)
542+
if tempdir_base is None:
543+
tempdir_str = self.sendExpression("getTempDirectoryPath()")
544+
tempdir_base = self.omcpath(tempdir_str)
545+
511546
tempdir: Optional[OMCPath] = None
512547
for name in names:
513548
# create a unique temporary directory name

0 commit comments

Comments
 (0)