Source code for pharmpy.utils

import os
import shutil
import time
import warnings
import weakref
from pathlib import Path
from tempfile import mkdtemp

import sympy
import sympy.physics.units as units


[docs]class TemporaryDirectoryChanger: def __init__(self, path): self.path = path self.old_path = Path.cwd() def __enter__(self): os.chdir(self.path) return self def __exit__(self, *args): os.chdir(self.old_path)
# This is copied and modified from the python 3.9 implementation # The aim is to be able to handle Permission issues in Windows class TemporaryDirectory: """Create and return a temporary directory. This has the same behavior as mkdtemp but can be used as a context manager. For example: with TemporaryDirectory() as tmpdir: ... Upon exiting the context, the directory and everything contained in it are removed. """ def __init__(self, suffix=None, prefix=None, dir=None): self.name = mkdtemp(suffix, prefix, dir) self._finalizer = weakref.finalize( self, self._cleanup, self.name, warn_message="Implicitly cleaning up {!r}".format(self) ) @classmethod def _rmtree(cls, name): def onerror(func, path, exc_info): if issubclass(exc_info[0], PermissionError): def resetperms(path): try: os.chflags(path, 0) except AttributeError: pass os.chmod(path, 0o700) try: if path != name: resetperms(os.path.dirname(path)) resetperms(path) try: os.unlink(path) # PermissionError is raised on FreeBSD for directories except (IsADirectoryError, PermissionError): time.sleep(0.1) cls._rmtree(path) except FileNotFoundError: pass elif issubclass(exc_info[0], FileNotFoundError): pass else: raise shutil.rmtree(name, onerror=onerror) @classmethod def _cleanup(cls, name, warn_message): cls._rmtree(name) warnings.warn(warn_message, ResourceWarning) def __repr__(self): return "<{} {!r}>".format(self.__class__.__name__, self.name) def __enter__(self): return self.name def __exit__(self, exc, value, tb): self.cleanup() def cleanup(self): if self._finalizer.detach(): self._rmtree(self.name) if os.name != 'nt': # Only use the custom implementation for Windows. from tempfile import TemporaryDirectory # noqa unit_subs = {} for k, v in units.__dict__.items(): if isinstance(v, sympy.Expr) and v.has(units.Unit): unit_subs[sympy.Symbol(k)] = v
[docs]def parse_units(s): if not isinstance(s, str): return s return sympy.sympify(s).subs(unit_subs)