Skip to content

Commit

Permalink
style(format): reformat with black
Browse files Browse the repository at this point in the history
  • Loading branch information
matfax authored Aug 22, 2020
1 parent 894f640 commit 996d9f1
Showing 10 changed files with 251 additions and 90 deletions.
2 changes: 1 addition & 1 deletion docs/attributes.py
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ def __init__(self, *args) -> None:
if isinstance(self.object, mutapath.Path):
for member in dir(mutapath.Path):
if member not in self.options.get("members") and not member.startswith(
"_"
"_"
):
LOG.info(f"[attributes] adding wrapped member {member}")
self.options["members"].append(member)
87 changes: 72 additions & 15 deletions mutapath/decorator.py
Original file line number Diff line number Diff line change
@@ -15,16 +15,67 @@
import mutapath

__EXCLUDE_FROM_WRAPPING = [
"__dir__", "__eq__", "__format__", "__repr__", "__str__", "__sizeof__", "__init__", "__getattribute__",
"__delattr__", "__setattr__", "__getattr__", "joinpath", "clone", "__exit__", "__fspath__",
"'_Path__wrap_attribute'", "__wrap_decorator", "_op_context", "__hash__", "__enter__", "_norm", "open", "lock",
"getcwd", "dirname", "owner", "uncshare", "posix_format", "posix_string", "__add__", "__radd__", "_set_contained",
"with_poxis_enabled", "_hash_cache", "_serialize", "_deserialize", "string_repr_enabled", "_shorten_duplicates",
"text", "bytes"
"__dir__",
"__eq__",
"__format__",
"__repr__",
"__str__",
"__sizeof__",
"__init__",
"__getattribute__",
"__delattr__",
"__setattr__",
"__getattr__",
"joinpath",
"clone",
"__exit__",
"__fspath__",
"'_Path__wrap_attribute'",
"__wrap_decorator",
"_op_context",
"__hash__",
"__enter__",
"_norm",
"open",
"lock",
"getcwd",
"dirname",
"owner",
"uncshare",
"posix_format",
"posix_string",
"__add__",
"__radd__",
"_set_contained",
"with_poxis_enabled",
"_hash_cache",
"_serialize",
"_deserialize",
"string_repr_enabled",
"_shorten_duplicates",
"text",
"bytes",
]

__MUTABLE_FUNCTIONS = {"rename", "renames", "copy", "copy2", "copyfile", "copymode", "copystat", "copytree", "move",
"basename", "abspath", "join", "joinpath", "normpath", "relpath", "realpath", "relpathto"}
__MUTABLE_FUNCTIONS = {
"rename",
"renames",
"copy",
"copy2",
"copyfile",
"copymode",
"copystat",
"copytree",
"move",
"basename",
"abspath",
"join",
"joinpath",
"normpath",
"relpath",
"realpath",
"relpathto",
}


def __is_mbm(member):
@@ -77,7 +128,9 @@ def __wrap_decorator(self, *args, **kwargs):
converter = __path_converter(self.clone)
if isinstance(result, List) and not isinstance(result, (str, bytes, bytearray)):
return list(map(converter, result))
if isinstance(result, Iterable) and not isinstance(result, (str, bytes, bytearray)):
if isinstance(result, Iterable) and not isinstance(
result, (str, bytes, bytearray)
):
return (converter(g) for g in result)
return __path_converter(self.clone)(result)

@@ -94,17 +147,21 @@ def path_wrapper(cls):
setattr(cls, name, __path_func(method))
member_names.append(name)
for name, _ in inspect.getmembers(path.Path, __is_mbm):
if not name.startswith("_") \
and name not in __EXCLUDE_FROM_WRAPPING \
and name not in member_names:
if (
not name.startswith("_")
and name not in __EXCLUDE_FROM_WRAPPING
and name not in member_names
):
method = getattr(path.Path, name)
if not hasattr(cls, name):
setattr(cls, name, wrap_attribute(method))
member_names.append(name)
for name, _ in inspect.getmembers(pathlib.Path, __is_mbm):
if not name.startswith("_") \
and name not in __EXCLUDE_FROM_WRAPPING \
and name not in member_names:
if (
not name.startswith("_")
and name not in __EXCLUDE_FROM_WRAPPING
and name not in member_names
):
method = getattr(pathlib.Path, name)
if not hasattr(cls, name):
setattr(cls, name, wrap_attribute(method, pathlib.Path))
100 changes: 72 additions & 28 deletions mutapath/immutapath.py
Original file line number Diff line number Diff line change
@@ -33,14 +33,19 @@
@path_wrapper
class Path(SerializableType):
"""Immutable Path"""

_contained: Union[path.Path, pathlib.PurePath, str] = path.Path("")
__always_posix_format: bool
__string_repr: bool
__mutable: object

def __init__(self, contained: Union[Path, path.Path, pathlib.PurePath, str] = "", *,
posix: Optional[bool] = None,
string_repr: Optional[bool] = None):
def __init__(
self,
contained: Union[Path, path.Path, pathlib.PurePath, str] = "",
*,
posix: Optional[bool] = None,
string_repr: Optional[bool] = None,
):
if posix is None:
posix = PathDefaults().posix
self.__always_posix_format = posix
@@ -52,7 +57,11 @@ def __init__(self, contained: Union[Path, path.Path, pathlib.PurePath, str] = ""
self._set_contained(contained, posix)
super().__init__()

def _set_contained(self, contained: Union[Path, path.Path, pathlib.PurePath, str], posix: Optional[bool] = None):
def _set_contained(
self,
contained: Union[Path, path.Path, pathlib.PurePath, str],
posix: Optional[bool] = None,
):
if contained:
if isinstance(contained, Path):
contained = contained._contained
@@ -85,15 +94,21 @@ def __setattr__(self, key, value):
if self.lock.is_locked:
self.lock.release()
Path(self.lock.lock_file).remove_p()
del self.__dict__['lock']
del self.__dict__["lock"]

if isinstance(value, Path):
value = value._contained
self._set_contained(value)
elif key in ["_Path__mutable", "_Path__always_posix_format", "_Path__string_repr"]:
elif key in [
"_Path__mutable",
"_Path__always_posix_format",
"_Path__string_repr",
]:
super(Path, self).__setattr__(key, value)
else:
raise AttributeError(f"attribute {key} can not be set because mutapath.Path is an immutable class.")
raise AttributeError(
f"attribute {key} can not be set because mutapath.Path is an immutable class."
)

def __repr__(self):
if self.__string_repr:
@@ -126,9 +141,11 @@ def __eq__(self, other):
return str(self) == str(other)

def __hash__(self):
warnings.warn(f"It is not advised to hash mutable path objects or to use them in sets or dicts. "
f"Please use hash(str(path)) instead to make the actual hashing input transparent.",
category=SyntaxWarning)
warnings.warn(
f"It is not advised to hash mutable path objects or to use them in sets or dicts. "
f"Please use hash(str(path)) instead to make the actual hashing input transparent.",
category=SyntaxWarning,
)
return self._hash_cache

@cached_property
@@ -191,6 +208,7 @@ def __fspath__(self):
def __invert__(self):
"""Create a cloned :class:`~mutapath.MutaPath` from this immutable Path."""
from mutapath import MutaPath

return MutaPath(self._contained, posix=self.posix_enabled)

def _serialize(self) -> str:
@@ -214,13 +232,15 @@ def clone(self, contained) -> Path:
:param contained: the new contained path element
:return: the cloned path
"""
return Path(contained, posix=self.__always_posix_format, string_repr=self.__string_repr)
return Path(
contained, posix=self.__always_posix_format, string_repr=self.__string_repr
)

@path.multimethod
def _shorten_duplicates(self, input_path: str = "") -> str:
if isinstance(input_path, Path):
input_path = input_path._contained
return input_path.replace('\\\\', '\\')
return input_path.replace("\\\\", "\\")

@path.multimethod
def posix_string(self, input_path: str = "") -> str:
@@ -233,7 +253,7 @@ def posix_string(self, input_path: str = "") -> str:
"""
if isinstance(input_path, Path):
input_path = input_path._contained
return input_path.replace('\\\\', '\\').replace('\\', '/')
return input_path.replace("\\\\", "\\").replace("\\", "/")

def with_poxis_enabled(self, enable: bool = True) -> Path:
"""
@@ -425,15 +445,15 @@ def startfile(self):
"""
if self.isfile():
secure_path = self.abspath()
if ' ' in secure_path:
if " " in secure_path:
return
if os.name == "nt":
os.startfile(secure_path)
else:
if sys.platform == "darwin":
args = ['open', secure_path]
args = ["open", secure_path]
else:
args = ['xdg-open', secure_path]
args = ["xdg-open", secure_path]
subprocess.call(args, shell=False)

@cached_property
@@ -494,9 +514,16 @@ def mutate(self):
self._contained = self.__mutable._contained

@contextmanager
def _op_context(self, name: str, timeout: float, lock: bool,
operation:
Callable[[Union[os.PathLike, path.Path], Union[os.PathLike, path.Path]], Union[str, path.Path]]):
def _op_context(
self,
name: str,
timeout: float,
lock: bool,
operation: Callable[
[Union[os.PathLike, path.Path], Union[os.PathLike, path.Path]],
Union[str, path.Path],
],
):
"""
Acquire a file mutation context that is bound to a file.
@@ -507,15 +534,18 @@ def _op_context(self, name: str, timeout: float, lock: bool,
"""
if not self._contained.exists():
raise PathException(f"{name.capitalize()} {self._contained} failed because the file does not exist.")
raise PathException(
f"{name.capitalize()} {self._contained} failed because the file does not exist."
)

try:
if lock:
try:
self.lock.acquire(timeout)
except filelock.Timeout as t:
raise PathException(
f"{name.capitalize()} {self._contained} failed because the file could not be locked.") from t
f"{name.capitalize()} {self._contained} failed because the file could not be locked."
) from t

self.__mutable = mutapath.MutaPath(self)
yield self.__mutable
@@ -529,20 +559,24 @@ def _op_context(self, name: str, timeout: float, lock: bool,
except FileExistsError as e:
raise PathException(
f"{name.capitalize()} to {current_file.normpath()} failed because the file already exists. "
f"Falling back to original value {self._contained}.") from e
f"Falling back to original value {self._contained}."
) from e

if not current_file.exists():
raise PathException(
f"{name.capitalize()} to {current_file.normpath()} failed because it can not be found. "
f"Falling back to original value {self._contained}.")
f"Falling back to original value {self._contained}."
)

self._contained = current_file

finally:
if self.lock.is_locked:
self.lock.release()

def renaming(self, lock=True, timeout=1, method: Callable[[str, str], None] = os.rename):
def renaming(
self, lock=True, timeout=1, method: Callable[[str, str], None] = os.rename
):
"""
Create a renaming context for this immutable path.
The external value is only changed if the renaming succeeds.
@@ -565,7 +599,8 @@ def checked_rename(cls: path.Path, target: path.Path):
target_lock.acquire(timeout)
except filelock.Timeout as t:
raise PathException(
f"Renaming {self._contained} failed because the target {target} could not be locked.") from t
f"Renaming {self._contained} failed because the target {target} could not be locked."
) from t
try:
if target.exists():
raise FileExistsError(f"{target.name} already exists.")
@@ -576,9 +611,16 @@ def checked_rename(cls: path.Path, target: path.Path):
target_lock_file.remove_p()
return target

return self._op_context("Renaming", lock=lock, timeout=timeout, operation=checked_rename)
return self._op_context(
"Renaming", lock=lock, timeout=timeout, operation=checked_rename
)

def moving(self, lock=True, timeout=1, method: Callable[[os.PathLike, os.PathLike], str] = shutil.move):
def moving(
self,
lock=True,
timeout=1,
method: Callable[[os.PathLike, os.PathLike], str] = shutil.move,
):
"""
Create a moving context for this immutable path.
The external value is only changed if the moving succeeds.
@@ -594,7 +636,9 @@ def moving(self, lock=True, timeout=1, method: Callable[[os.PathLike, os.PathLik
"""
return self._op_context("Moving", operation=method, lock=lock, timeout=timeout)

def copying(self, lock=True, timeout=1, method: Callable[[Path, Path], Path] = shutil.copy):
def copying(
self, lock=True, timeout=1, method: Callable[[Path, Path], Path] = shutil.copy
):
"""
Create a copying context for this immutable path.
The external value is only changed if the copying succeeds.
1 change: 0 additions & 1 deletion mutapath/lock_dummy.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@


class DummyFileLock(BaseFileLock):

def release(self, force=False):
"""Doing nothing"""

12 changes: 9 additions & 3 deletions mutapath/mutapath.py
Original file line number Diff line number Diff line change
@@ -13,9 +13,15 @@
class MutaPath(mutapath.Path):
"""Mutable Path"""

def __init__(self, contained: Union[MutaPath, mutapath.Path, path.Path, pathlib.PurePath, str] = "", *,
posix: Optional[bool] = None,
string_repr: Optional[bool] = None):
def __init__(
self,
contained: Union[
MutaPath, mutapath.Path, path.Path, pathlib.PurePath, str
] = "",
*,
posix: Optional[bool] = None,
string_repr: Optional[bool] = None,
):
if isinstance(contained, MutaPath):
contained = contained._contained
super(MutaPath, self).__init__(contained, posix=posix, string_repr=string_repr)
Loading

0 comments on commit 996d9f1

Please sign in to comment.