Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions ndrect/_is_aligned.py → ndrect/_ndrect_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""IsAligned interface for N-dimensional rectangles with defined shapes."""
"""Base class for N-dimensional rectangles."""

from __future__ import annotations

Expand All @@ -14,8 +14,8 @@
from ndrect.ndrect_complex import NDRectComplex


class IsAligned[TSingular: NDRect, TComplex: NDRectComplex](ABC):
"""An interface for N-dimensional rectangles that have a defined shape."""
class NDRectBase[TSingular: NDRect, TComplex: NDRectComplex](ABC):
"""Base class for N-dimensional rectangles."""

@property
@abstractmethod
Expand Down Expand Up @@ -83,7 +83,7 @@ def _as_sequence_object(
return tuple(self.rects)
raise TypeError

def then(self, other: IsAligned) -> TComplex:
def then(self, other: NDRectBase) -> TComplex:
"""Sequences the other rectangle after this one.

Args:
Expand Down Expand Up @@ -161,7 +161,7 @@ def __mul__(self, n: int) -> TComplex:
"""
return self.repeat(n)

def __add__(self, other: IsAligned) -> TComplex:
def __add__(self, other: NDRectBase) -> TComplex:
"""Shorthand for :meth:`then`.

Sequences the other rectangle after this one.
Expand Down
4 changes: 2 additions & 2 deletions ndrect/ndrect.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@

from attrs import define, field

from ndrect._is_aligned import IsAligned
from ndrect._ndrect_base import NDRectBase
from ndrect._typing import DimensionLength, DimensionName

if TYPE_CHECKING:
from ndrect.ndrect_complex import NDRectComplex


@define(repr=False)
class NDRect(IsAligned["NDRect", "NDRectComplex"]):
class NDRect(NDRectBase["NDRect", "NDRectComplex"]):
"""An n-dim rectangle defined by its shape."""

shape: Mapping[DimensionName, DimensionLength] = field(
Expand Down
4 changes: 2 additions & 2 deletions ndrect/ndrect_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from attrs import define, field

from ndrect._is_aligned import IsAligned
from ndrect._ndrect_base import NDRectBase
from ndrect._typing import DimensionLength, DimensionName

if TYPE_CHECKING:
Expand All @@ -28,7 +28,7 @@ class UnalignedError(Exception):


@define(repr=False, frozen=True)
class NDRectComplex(IsAligned["NDRect", "NDRectComplex"]):
class NDRectComplex(NDRectBase["NDRect", "NDRectComplex"]):
"""Aligned complex n-dim rectangle of multiple rectangles in sequence."""

rects: Sequence[NDRect | NDRectComplex] = field(converter=tuple)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
from attrs import define

from ndrect import NDRect
from ndrect._is_aligned import IsAligned
from ndrect._ndrect_base import NDRectBase
from ndrect._typing import DimensionLength, DimensionName
from ndrect.ndrect_complex import NDRectComplex


class MockIsAligned(IsAligned):
class MockNDRectBase(NDRectBase):
@property
def shape(self) -> MappingProxyType[DimensionName, DimensionLength]:
return ...
Expand Down Expand Up @@ -49,9 +49,9 @@ def _complex_type(self) -> type[MockNDRectComplex]:
return MockNDRectComplex


@patch.object(MockIsAligned, "shape", new_callable=PropertyMock)
@patch.object(MockNDRectBase, "shape", new_callable=PropertyMock)
def test_ndim_is_len_of_shape(mock_shape: PropertyMock) -> None:
obj = MockIsAligned()
obj = MockNDRectBase()
ndim = obj.ndim
mock_shape.assert_called_once()
assert ndim == len(obj.shape)
Expand Down Expand Up @@ -131,31 +131,31 @@ def test_along_creates_complex_with_align_dim_using_as_sequence_object(


def test___add__calls_then() -> None:
with patch.object(MockIsAligned, "then") as mock_then:
obj_a = MockIsAligned()
obj_b = MockIsAligned()
with patch.object(MockNDRectBase, "then") as mock_then:
obj_a = MockNDRectBase()
obj_b = MockNDRectBase()
assert obj_a + obj_b == mock_then.return_value
mock_then.assert_called_once_with(obj_b)


def test___mul__calls_repeat() -> None:
with patch.object(MockIsAligned, "repeat") as mock_repeat:
obj = MockIsAligned()
with patch.object(MockNDRectBase, "repeat") as mock_repeat:
obj = MockNDRectBase()
n = MagicMock()
assert obj * n == mock_repeat.return_value
mock_repeat.assert_called_once_with(n)


def test__pos__calls_elevate() -> None:
with patch.object(MockIsAligned, "elevate") as mock_elevate:
obj = MockIsAligned()
with patch.object(MockNDRectBase, "elevate") as mock_elevate:
obj = MockNDRectBase()
assert +obj == mock_elevate.return_value
mock_elevate.assert_called_once()


def test__matmul__calls_along() -> None:
with patch.object(MockIsAligned, "along") as mock_along:
obj = MockIsAligned()
with patch.object(MockNDRectBase, "along") as mock_along:
obj = MockNDRectBase()
dim = MagicMock()
assert obj @ dim == mock_along.return_value
mock_along.assert_called_once_with(align_dim=dim)
Expand Down