Skip to content

Commit

Permalink
use PathWrapperException more, fix typo, fix test; close #20
Browse files Browse the repository at this point in the history
  • Loading branch information
vreuter committed Mar 13, 2024
1 parent 6ee2e02 commit 0e54100
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 25 deletions.
22 changes: 6 additions & 16 deletions gertils/pathtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
PW = TypeVar("PW", bound="PathWrapper")


@dataclass
@dataclass(frozen=True)
class PathWrapper(ABC):
"""A Wrapper around a path that does some sort of validation"""

Expand All @@ -28,18 +28,10 @@ def __post_init__(self) -> None:
raise TypeError(f"Not a path, but {type(self.path).__name__}: {self.path}")
self._invalidate()

def __setattr__(self, __name: str, __value: Any) -> None: # type: ignore[misc]
result = super().__setattr__(__name, __value)
self.__post_init__()
return result

@classmethod
def from_string(cls: Type[PW], rawpath: str) -> PW:
"""Attempt to parse an instance from a raw string."""
try:
return cls(Path(rawpath))
except Exception as exc:
raise PathWrapperException(exc) from exc
return cls(Path(rawpath))

def to_string(self) -> str:
"""Return a string representation of this wrapped value."""
Expand All @@ -49,30 +41,28 @@ def to_string(self) -> str:
class PathWrapperException(Exception):
"""Exception subtype for working with paths with a particular property"""

def __init__(self, original_exception: Exception) -> None:
super().__init__(str(original_exception))
self.original = original_exception
pass


class ExtantFile(PathWrapper):
"""Wrapper around a path that validates it as a file which exists"""

def _invalidate(self) -> None:
if not self.path.is_file():
raise TypeError(f"Not an extant file: {self.path}")
raise PathWrapperException(f"Not an extant file: {self.path}")


class ExtantFolder(PathWrapper):
"""Wrapper around a path that validates it as a folder which exists"""

def _invalidate(self) -> None:
if not self.path.is_dir():
raise TypeError(f"Not an extant folder: {self.path}")
raise PathWrapperException(f"Not an extant folder: {self.path}")


class NonExtantPath(PathWrapper):
"""Wrapper around a path that validates it as nonexistent"""

def _invalidate(self) -> None:
if self.path.exists():
raise TypeError(f"Path already exists: {self.path}")
raise PathWrapperException(f"Path already exists: {self.path}")
15 changes: 6 additions & 9 deletions tests/test_pathtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

"""Tests for core utilities for working with paths"""

from dataclasses import dataclass
from dataclasses import dataclass, FrozenInstanceError
from pathlib import Path
from typing import *

Expand Down Expand Up @@ -61,7 +61,7 @@ def test_path_wrapper_cannot_be_instantiated(wrapper):
)
def test_path_wrapper_subtypes_invalidation(tmp_path, parameterisation):
path = parameterisation.from_tmp_path(tmp_path)
with pytest.raises(TypeError) as error_context:
with pytest.raises(pathtools.PathWrapperException) as error_context:
parameterisation.wrap_type(path)
assert str(error_context.value) == f"{parameterisation.exp_err_msg_prefix}: {path}"

Expand All @@ -76,12 +76,9 @@ def test_path_wrapper_immutability(tmp_path, parameterisation):
good_path = tmp_path / "my-awesome-path"
prepare_path(good_path)
wrapper = parameterisation.wrap_type(good_path)
bad_path = parameterisation.from_tmp_path(tmp_path)
with pytest.raises(TypeError) as error_context:
wrapper.path = bad_path
assert (
str(error_context.value) == f"{parameterisation.exp_err_msg_prefix}: {bad_path}"
)
with pytest.raises(FrozenInstanceError) as error_context:
wrapper.path = wrapper.path
assert str(error_context.value) == f"cannot assign to field 'path'"


@pytest.mark.parametrize(["wrap_type", "prepare_path"], PATH_PREPARATIONS.items())
Expand All @@ -96,7 +93,7 @@ def test_path_wrapper_subtypes_provide_path_attribute_access(


@pytest.mark.parametrize(["wrap_type", "prepare_path"], PATH_PREPARATIONS.items())
def test_path_wrapper_subtypes_rountrip_through_string(
def test_path_wrapper_subtypes_roundtrip_through_string(
tmp_path, prepare_path, wrap_type
):
path = tmp_path / "my-awesome-path"
Expand Down

0 comments on commit 0e54100

Please sign in to comment.