Source code for fmeTestSupport.Paths
# Copyright (c) Fraunhofer MEVIS, Germany. All rights reserved.
# **InsertLicense** code
import os, shutil, tempfile
from contextlib import contextmanager
from pathlib import PurePath, Path
from fmeTestSupport.Context import Context
from typing import ContextManager
[docs]@contextmanager
def GuaranteedTemporaryPath( path:str, removeOnError=True ) -> ContextManager[None]:
"""
Context manager to return a "guaranteed" temporary path, that is reused if existing, or created and afterwards
deleted if not.
:param removeOnError: If set, the directory is NOT removed if an exception occurred within the context manager body, even if it was previously created.
:yields: None
"""
#
def ___do( memory ):
if not os.path.exists( path ):
os.mkdir( path )
memory[ "didCreatePath" ] = True
else:
memory[ "didCreatePath" ] = False
#
def ___undo( _, memory ):
if memory[ "didCreatePath" ]:
shutil.rmtree( path )
#
with Context( ___do, ___undo, undoOnError=removeOnError, memory={} ):
yield
[docs]@contextmanager
def TemporaryDirectory( removeOnError=True ) -> ContextManager[str]:
"""
Creates a temporary directory and removes it automatically afterwards.
:param removeOnError: If set, the directory is NOT removed if an exception occurred within the context manager body.
:yields: Path to the created temporary directory
"""
#
def ___do():
return tempfile.mkdtemp()
#
def ___undo( createdPath ):
shutil.rmtree( createdPath )
#
with Context( ___do, ___undo, undoOnError=removeOnError ) as path:
yield path
[docs]def isSubPath( path: [str, Path], baseFolder: [str, Path] ) -> bool:
"""
Returns True if path is a sub-path of baseFolder, i.e. if path starts with baseFolder,
e.g. IsSubPath("a/b/c", "a/b") == True. Will not do anything on the file system, just does a plain comparison
that compensates for slash/backslash and, under Windows, case differences.
:param path: Path to check if it is a sub directory of path
:param baseFolder: Expected base directory of path
:returns: True if *path* is identical to or a true sub-path of *baseFolder*
"""
path_normalized = normalizedPath( path )
root_normalized = normalizedPath( baseFolder )
return ( root_normalized == path_normalized or
root_normalized in path_normalized.parents )
[docs]def isTrueSubPath( path: [str, Path], baseFolder: [str, Path] ) -> bool:
"""
Returns True if path is a true sub-path of baseFolder, i.e. if path starts with baseFolder,
e.g. IsSubPath("a/b/c", "a/b") == True, but path is not identical to baseFolder.
Will not do anything on the file system, just does a plain comparison
that compensates for slash/backslash and, under Windows, case differences.
:param path: Path to check if it is a sub directory of path
:param baseFolder: Expected base directory of path
:returns: True if *path* is a true sub-path of *baseFolder*
"""
return normalizedPath( baseFolder ) in normalizedPath( path ).parents
[docs]def areIdenticalPaths( path1: [str, Path], path2: [str, Path] ) -> bool:
"""
:returns: True if the two given path strings point to identical paths.
"""
return normalizedPath( path1 ) == normalizedPath( path2 )
[docs]def normalizedPath( path: [str, Path] ) -> PurePath:
"""
Apply to normalize a path before comparing for equality or similar.
:returns: Normalized path as PurePath
"""
return PurePath( str( os.path.normpath( str( path ).replace( "\\", "/" ) ) ) )