use Self type
This commit is contained in:
parent
1463535676
commit
4482ede3a7
17 changed files with 142 additions and 205 deletions
|
|
@ -1,4 +1,4 @@
|
|||
from typing import TypeVar
|
||||
from typing import Self
|
||||
#from types import MappingProxyType
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
|
@ -9,10 +9,6 @@ from ..error import MasqueError
|
|||
_empty_slots = () # Workaround to get mypy to ignore intentionally empty slots for superclass
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Annotatable')
|
||||
I = TypeVar('I', bound='AnnotatableImpl')
|
||||
|
||||
|
||||
class Annotatable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for all annotatable entities
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
from typing import TypeVar
|
||||
from typing import Self
|
||||
from abc import ABCMeta
|
||||
import copy
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Copyable')
|
||||
|
||||
|
||||
class Copyable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class which adds .copy() and .deepcopy()
|
||||
|
|
@ -15,7 +12,7 @@ class Copyable(metaclass=ABCMeta):
|
|||
'''
|
||||
---- Non-abstract methods
|
||||
'''
|
||||
def copy(self: T) -> T:
|
||||
def copy(self) -> Self:
|
||||
"""
|
||||
Return a shallow copy of the object.
|
||||
|
||||
|
|
@ -24,7 +21,7 @@ class Copyable(metaclass=ABCMeta):
|
|||
"""
|
||||
return copy.copy(self)
|
||||
|
||||
def deepcopy(self: T) -> T:
|
||||
def deepcopy(self) -> Self:
|
||||
"""
|
||||
Return a deep copy of the object.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import TypeVar
|
||||
from typing import Self
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
from ..utils import layer_t
|
||||
|
|
@ -7,10 +7,6 @@ from ..utils import layer_t
|
|||
_empty_slots = () # Workaround to get mypy to ignore intentionally empty slots for superclass
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Layerable')
|
||||
I = TypeVar('I', bound='LayerableImpl')
|
||||
|
||||
|
||||
class Layerable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for all layerable entities
|
||||
|
|
@ -36,7 +32,7 @@ class Layerable(metaclass=ABCMeta):
|
|||
---- Methods
|
||||
'''
|
||||
@abstractmethod
|
||||
def set_layer(self: T, layer: layer_t) -> T:
|
||||
def set_layer(self, layer: layer_t) -> Self:
|
||||
"""
|
||||
Set the layer
|
||||
|
||||
|
|
@ -72,6 +68,6 @@ class LayerableImpl(Layerable, metaclass=ABCMeta):
|
|||
'''
|
||||
---- Non-abstract methods
|
||||
'''
|
||||
def set_layer(self: I, layer: layer_t) -> I:
|
||||
def set_layer(self, layer: layer_t) -> Self:
|
||||
self.layer = layer
|
||||
return self
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
from typing import TypeVar
|
||||
from typing import Self
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Mirrorable')
|
||||
#I = TypeVar('I', bound='MirrorableImpl')
|
||||
|
||||
|
||||
class Mirrorable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for all mirrorable entities
|
||||
|
|
@ -16,7 +12,7 @@ class Mirrorable(metaclass=ABCMeta):
|
|||
---- Abstract methods
|
||||
'''
|
||||
@abstractmethod
|
||||
def mirror(self: T, axis: int) -> T:
|
||||
def mirror(self, axis: int) -> Self:
|
||||
"""
|
||||
Mirror the entity across an axis.
|
||||
|
||||
|
|
@ -28,7 +24,7 @@ class Mirrorable(metaclass=ABCMeta):
|
|||
"""
|
||||
pass
|
||||
|
||||
def mirror2d(self: T, axes: tuple[bool, bool]) -> T:
|
||||
def mirror2d(self, axes: tuple[bool, bool]) -> Self:
|
||||
"""
|
||||
Optionally mirror the entity across both axes
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# TODO top-level comment about how traits should set __slots__ = (), and how to use AutoSlots
|
||||
|
||||
from typing import TypeVar, Any
|
||||
from typing import Self, Any
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
import numpy
|
||||
|
|
@ -12,10 +12,6 @@ from ..error import MasqueError
|
|||
_empty_slots = () # Workaround to get mypy to ignore intentionally empty slots for superclass
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Positionable')
|
||||
I = TypeVar('I', bound='PositionableImpl')
|
||||
|
||||
|
||||
class Positionable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for all positionable entities
|
||||
|
|
@ -39,7 +35,7 @@ class Positionable(metaclass=ABCMeta):
|
|||
pass
|
||||
|
||||
@abstractmethod
|
||||
def set_offset(self: T, offset: ArrayLike) -> T:
|
||||
def set_offset(self, offset: ArrayLike) -> Self:
|
||||
"""
|
||||
Set the offset
|
||||
|
||||
|
|
@ -52,7 +48,7 @@ class Positionable(metaclass=ABCMeta):
|
|||
pass
|
||||
|
||||
@abstractmethod
|
||||
def translate(self: T, offset: ArrayLike) -> T:
|
||||
def translate(self, offset: ArrayLike) -> Self:
|
||||
"""
|
||||
Translate the entity by the given offset
|
||||
|
||||
|
|
@ -116,10 +112,10 @@ class PositionableImpl(Positionable, metaclass=ABCMeta):
|
|||
'''
|
||||
---- Methods
|
||||
'''
|
||||
def set_offset(self: I, offset: ArrayLike) -> I:
|
||||
def set_offset(self, offset: ArrayLike) -> Self:
|
||||
self.offset = offset
|
||||
return self
|
||||
|
||||
def translate(self: I, offset: ArrayLike) -> I:
|
||||
def translate(self, offset: ArrayLike) -> Self:
|
||||
self._offset += offset # type: ignore # NDArray += ArrayLike should be fine??
|
||||
return self
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import TypeVar, TYPE_CHECKING
|
||||
from typing import Self, TYPE_CHECKING
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
from ..error import MasqueError
|
||||
|
|
@ -11,10 +11,6 @@ if TYPE_CHECKING:
|
|||
from ..repetition import Repetition
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Repeatable')
|
||||
I = TypeVar('I', bound='RepeatableImpl')
|
||||
|
||||
|
||||
class Repeatable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for all repeatable entities
|
||||
|
|
@ -41,7 +37,7 @@ class Repeatable(metaclass=ABCMeta):
|
|||
---- Methods
|
||||
'''
|
||||
@abstractmethod
|
||||
def set_repetition(self: T, repetition: 'Repetition' | None) -> T:
|
||||
def set_repetition(self, repetition: 'Repetition' | None) -> Self:
|
||||
"""
|
||||
Set the repetition
|
||||
|
||||
|
|
@ -80,6 +76,6 @@ class RepeatableImpl(Repeatable, metaclass=ABCMeta):
|
|||
'''
|
||||
---- Non-abstract methods
|
||||
'''
|
||||
def set_repetition(self: I, repetition: 'Repetition' | None) -> I:
|
||||
def set_repetition(self, repetition: 'Repetition' | None) -> Self:
|
||||
self.repetition = repetition
|
||||
return self
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import TypeVar, cast, Any
|
||||
from typing import Self, cast, Any
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
import numpy
|
||||
|
|
@ -13,12 +13,6 @@ from ..utils import rotation_matrix_2d
|
|||
_empty_slots = () # Workaround to get mypy to ignore intentionally empty slots for superclass
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Rotatable')
|
||||
I = TypeVar('I', bound='RotatableImpl')
|
||||
P = TypeVar('P', bound='Pivotable')
|
||||
J = TypeVar('J', bound='PivotableImpl')
|
||||
|
||||
|
||||
class Rotatable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for all rotatable entities
|
||||
|
|
@ -29,7 +23,7 @@ class Rotatable(metaclass=ABCMeta):
|
|||
---- Abstract methods
|
||||
'''
|
||||
@abstractmethod
|
||||
def rotate(self: T, val: float) -> T:
|
||||
def rotate(self, val: float) -> Self:
|
||||
"""
|
||||
Rotate the shape around its origin (0, 0), ignoring its offset.
|
||||
|
||||
|
|
@ -68,11 +62,11 @@ class RotatableImpl(Rotatable, metaclass=ABCMeta):
|
|||
'''
|
||||
---- Methods
|
||||
'''
|
||||
def rotate(self: I, rotation: float) -> I:
|
||||
def rotate(self, rotation: float) -> Self:
|
||||
self.rotation += rotation
|
||||
return self
|
||||
|
||||
def set_rotation(self: I, rotation: float) -> I:
|
||||
def set_rotation(self, rotation: float) -> Self:
|
||||
"""
|
||||
Set the rotation to a value
|
||||
|
||||
|
|
@ -94,7 +88,7 @@ class Pivotable(metaclass=ABCMeta):
|
|||
__slots__ = ()
|
||||
|
||||
@abstractmethod
|
||||
def rotate_around(self: P, pivot: ArrayLike, rotation: float) -> P:
|
||||
def rotate_around(self, pivot: ArrayLike, rotation: float) -> Self:
|
||||
"""
|
||||
Rotate the object around a point.
|
||||
|
||||
|
|
@ -117,7 +111,7 @@ class PivotableImpl(Pivotable, metaclass=ABCMeta):
|
|||
offset: Any # TODO see if we can get around defining `offset` in PivotableImpl
|
||||
""" `[x_offset, y_offset]` """
|
||||
|
||||
def rotate_around(self: J, pivot: ArrayLike, rotation: float) -> J:
|
||||
def rotate_around(self, pivot: ArrayLike, rotation: float) -> Self:
|
||||
pivot = numpy.array(pivot, dtype=float)
|
||||
cast(Positionable, self).translate(-pivot)
|
||||
cast(Rotatable, self).rotate(rotation)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import TypeVar
|
||||
from typing import Self
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
from ..error import MasqueError
|
||||
|
|
@ -8,10 +8,6 @@ from ..utils import is_scalar
|
|||
_empty_slots = () # Workaround to get mypy to ignore intentionally empty slots for superclass
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Scalable')
|
||||
I = TypeVar('I', bound='ScalableImpl')
|
||||
|
||||
|
||||
class Scalable(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for all scalable entities
|
||||
|
|
@ -22,7 +18,7 @@ class Scalable(metaclass=ABCMeta):
|
|||
---- Abstract methods
|
||||
'''
|
||||
@abstractmethod
|
||||
def scale_by(self: T, c: float) -> T:
|
||||
def scale_by(self, c: float) -> Self:
|
||||
"""
|
||||
Scale the entity by a factor
|
||||
|
||||
|
|
@ -62,11 +58,11 @@ class ScalableImpl(Scalable, metaclass=ABCMeta):
|
|||
'''
|
||||
---- Methods
|
||||
'''
|
||||
def scale_by(self: I, c: float) -> I:
|
||||
def scale_by(self, c: float) -> Self:
|
||||
self.scale *= c
|
||||
return self
|
||||
|
||||
def set_scale(self: I, scale: float) -> I:
|
||||
def set_scale(self, scale: float) -> Self:
|
||||
"""
|
||||
Set the sclae to a value
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue