%PDF- %PDF-
Direktori : /lib/python3/dist-packages/fs/ |
Current File : //lib/python3/dist-packages/fs/error_tools.py |
"""Tools for managing OS errors. """ from __future__ import print_function from __future__ import unicode_literals import errno import platform import sys import typing from contextlib import contextmanager from six import reraise from . import errors if typing.TYPE_CHECKING: from types import TracebackType from typing import Iterator, Optional, Text, Type, Union try: from collections.abc import Mapping except ImportError: from collections import Mapping # noqa: E811 _WINDOWS_PLATFORM = platform.system() == "Windows" class _ConvertOSErrors(object): """Context manager to convert OSErrors in to FS Errors. """ FILE_ERRORS = { 64: errors.RemoteConnectionError, # ENONET errno.EACCES: errors.PermissionDenied, errno.ENOENT: errors.ResourceNotFound, errno.EFAULT: errors.ResourceNotFound, errno.ESRCH: errors.ResourceNotFound, errno.ENOTEMPTY: errors.DirectoryNotEmpty, errno.EEXIST: errors.FileExists, 183: errors.DirectoryExists, # errno.ENOTDIR: errors.DirectoryExpected, errno.ENOTDIR: errors.ResourceNotFound, errno.EISDIR: errors.FileExpected, errno.EINVAL: errors.FileExpected, errno.ENOSPC: errors.InsufficientStorage, errno.EPERM: errors.PermissionDenied, errno.ENETDOWN: errors.RemoteConnectionError, errno.ECONNRESET: errors.RemoteConnectionError, errno.ENAMETOOLONG: errors.PathError, errno.EOPNOTSUPP: errors.Unsupported, errno.ENOSYS: errors.Unsupported, } DIR_ERRORS = FILE_ERRORS.copy() DIR_ERRORS[errno.ENOTDIR] = errors.DirectoryExpected DIR_ERRORS[errno.EEXIST] = errors.DirectoryExists DIR_ERRORS[errno.EINVAL] = errors.DirectoryExpected if _WINDOWS_PLATFORM: # pragma: no cover DIR_ERRORS[13] = errors.DirectoryExpected DIR_ERRORS[267] = errors.DirectoryExpected FILE_ERRORS[13] = errors.FileExpected def __init__(self, opname, path, directory=False): # type: (Text, Text, bool) -> None self._opname = opname self._path = path self._directory = directory def __enter__(self): # type: () -> _ConvertOSErrors return self def __exit__( self, exc_type, # type: Optional[Type[BaseException]] exc_value, # type: Optional[BaseException] traceback, # type: Optional[TracebackType] ): # type: (...) -> None os_errors = self.DIR_ERRORS if self._directory else self.FILE_ERRORS if exc_type and isinstance(exc_value, EnvironmentError): _errno = exc_value.errno fserror = os_errors.get(_errno, errors.OperationFailed) if _errno == errno.EACCES and sys.platform == "win32": if getattr(exc_value, "args", None) == 32: # pragma: no cover fserror = errors.ResourceLocked reraise(fserror, fserror(self._path, exc=exc_value), traceback) # Stops linter complaining about invalid class name convert_os_errors = _ConvertOSErrors @contextmanager def unwrap_errors(path_replace): # type: (Union[Text, Mapping[Text, Text]]) -> Iterator[None] """Get a context to map OS errors to their `fs.errors` counterpart. The context will re-write the paths in resource exceptions to be in the same context as the wrapped filesystem. The only parameter may be the path from the parent, if only one path is to be unwrapped. Or it may be a dictionary that maps wrapped paths on to unwrapped paths. """ try: yield except errors.ResourceError as e: if hasattr(e, "path"): if isinstance(path_replace, Mapping): e.path = path_replace.get(e.path, e.path) else: e.path = path_replace raise