Skip to content

Commit 930cff1

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 3625807 commit 930cff1

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
@@ -274,7 +274,7 @@ class OMCPathReal(pathlib.PurePosixPath):
274274
OMCSessionZMQ session object.
275275
"""
276276

277-
def __init__(self, *path, session: OMCSessionZMQ):
277+
def __init__(self, *path, session: OMCSessionZMQ) -> None:
278278
super().__init__(*path)
279279
self._session = session
280280

@@ -286,27 +286,28 @@ def with_segments(self, *pathsegments):
286286
"""
287287
return type(self)(*pathsegments, session=self._session)
288288

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

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

301-
def read_text(self, encoding=None, errors=None) -> str:
301+
def read_text(self, encoding=None, errors=None, newline=None) -> str:
302302
"""
303303
Read the content of the file represented by this path as text.
304304
305-
The additional arguments `encoding` and `errors` are only defined for compatibility with Path() definitions.
305+
The additional arguments `encoding`, `errors` and `newline` are only defined for compatibility with Path()
306+
definition.
306307
"""
307308
return self._session.sendExpression(f'readFile("{self.as_posix()}")')
308309

309-
def write_text(self, data: str, encoding=None, errors=None, newline=None) -> bool:
310+
def write_text(self, data: str, encoding=None, errors=None, newline=None):
310311
"""
311312
Write text data to the file represented by this path.
312313
@@ -337,16 +338,15 @@ def cwd(self):
337338
cwd_str = self._session.sendExpression('cd()')
338339
return OMCPath(cwd_str, session=self._session)
339340

340-
def unlink(self, missing_ok: bool = False) -> bool:
341+
def unlink(self, missing_ok: bool = False) -> None:
341342
"""
342343
Unlink (delete) the file or directory represented by this path.
343344
"""
344345
res = self._session.sendExpression(f'deleteFile("{self.as_posix()}")')
345346
if not res and not missing_ok:
346347
raise FileNotFoundError(f"Cannot delete file {self.as_posix()} - it does not exists!")
347-
return res
348348

349-
def resolve(self, strict: bool = False) -> OMCPath:
349+
def resolve(self, strict: bool = False):
350350
"""
351351
Resolve the path to an absolute path. This is done based on available OMC functions.
352352
"""
@@ -362,7 +362,7 @@ def resolve(self, strict: bool = False) -> OMCPath:
362362

363363
return omcpath
364364

365-
def _omc_resolve(self, pathstr: str) -> OMCPath:
365+
def _omc_resolve(self, pathstr: str):
366366
"""
367367
Internal function to resolve the path of the OMCPath object using OMC functions *WITHOUT* changing the cwd
368368
within OMC.
@@ -386,7 +386,7 @@ def _omc_resolve(self, pathstr: str) -> OMCPath:
386386

387387
return omcpath_resolved
388388

389-
def absolute(self) -> OMCPath:
389+
def absolute(self):
390390
"""
391391
Resolve the path to an absolute path. This is done by calling resolve() as it is the best we can do
392392
using OMC functions.
@@ -414,18 +414,42 @@ def size(self) -> int:
414414

415415

416416
if sys.version_info < (3, 12):
417-
warnings.warn(
418-
message="Python < 3.12 - using a limited compatibility class as OMCPath replacement.",
419-
category=DeprecationWarning,
420-
stacklevel=1,
421-
)
422417

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

425437
def size(self) -> int:
438+
"""
439+
Needed compatibility function to have the same interface as OMCPathReal
440+
"""
426441
return self.stat().st_size
427442

428-
OMCPath = OMCPathCompatibility # noqa: F811
443+
444+
class OMCPathCompatibilityPosix(pathlib.PosixPath, OMCPathCompatibility):
445+
pass
446+
447+
448+
class OMCPathCompatibilityWindows(pathlib.WindowsPath, OMCPathCompatibility):
449+
pass
450+
451+
452+
OMCPath = OMCPathCompatibility
429453

430454
else:
431455
OMCPath = OMCPathReal
@@ -492,19 +516,30 @@ def omcpath(self, *path) -> OMCPath:
492516

493517
# fallback solution for Python < 3.12; a modified pathlib.Path object is used as OMCPath replacement
494518
if sys.version_info < (3, 12):
495-
# noinspection PyArgumentList
496-
return OMCPath(*path)
519+
if isinstance(self.omc_process, OMCProcessLocal):
520+
# noinspection PyArgumentList
521+
return OMCPath(*path)
522+
else:
523+
raise OMCSessionException("OMCPath is supported for Python < 3.12 only if OMCProcessLocal is used!")
497524
else:
498525
return OMCPath(*path, session=self)
499526

500-
def omcpath_tempdir(self) -> OMCPath:
527+
def omcpath_tempdir(self, tempdir_base: Optional[OMCPath] = None) -> OMCPath:
501528
"""
502529
Get a temporary directory using OMC.
503530
"""
531+
# fallback solution for Python < 3.12; a modified pathlib.Path object is used as OMCPath replacement
532+
if sys.version_info < (3, 12):
533+
tempdir_str = tempfile.gettempdir()
534+
# noinspection PyArgumentList
535+
return OMCPath(tempdir_str)
536+
504537
names = [str(uuid.uuid4()) for _ in range(100)]
505538

506-
tempdir_str = self.sendExpression("getTempDirectoryPath()")
507-
tempdir_base = self.omcpath(tempdir_str)
539+
if tempdir_base is None:
540+
tempdir_str = self.sendExpression("getTempDirectoryPath()")
541+
tempdir_base = self.omcpath(tempdir_str)
542+
508543
tempdir: Optional[OMCPath] = None
509544
for name in names:
510545
# create a unique temporary directory name

0 commit comments

Comments
 (0)