improve some more type annotations using TypeVar
This commit is contained in:
parent
eb11f31960
commit
2bc03cbbf4
4 changed files with 60 additions and 49 deletions
|
|
@ -3,7 +3,7 @@
|
|||
"""
|
||||
|
||||
from typing import List, Callable, Tuple, Dict, Union, Set, Sequence, Optional, Type, overload
|
||||
from typing import MutableMapping, Iterable
|
||||
from typing import MutableMapping, Iterable, TypeVar, Any
|
||||
import copy
|
||||
import pickle
|
||||
from itertools import chain
|
||||
|
|
@ -24,6 +24,9 @@ from .traits import LockableImpl, AnnotatableImpl, Scalable
|
|||
visitor_function_t = Callable[['Pattern', Tuple['Pattern'], Dict, numpy.ndarray], 'Pattern']
|
||||
|
||||
|
||||
P = TypeVar('P', bound='Pattern')
|
||||
|
||||
|
||||
class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
||||
"""
|
||||
2D layout consisting of some set of shapes, labels, and references to other Pattern objects
|
||||
|
|
@ -56,7 +59,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
subpatterns: Sequence[SubPattern] = (),
|
||||
annotations: Optional[annotations_t] = None,
|
||||
locked: bool = False,
|
||||
):
|
||||
) -> None:
|
||||
"""
|
||||
Basic init; arguments get assigned to member variables.
|
||||
Non-list inputs for shapes and subpatterns get converted to lists.
|
||||
|
|
@ -112,11 +115,11 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
locked=self.locked)
|
||||
return new
|
||||
|
||||
def rename(self, name: str) -> 'Pattern':
|
||||
def rename(self: P, name: str) -> P:
|
||||
self.name = name
|
||||
return self
|
||||
|
||||
def append(self, other_pattern: 'Pattern') -> 'Pattern':
|
||||
def append(self: P, other_pattern: P) -> P:
|
||||
"""
|
||||
Appends all shapes, labels and subpatterns from other_pattern to self's shapes,
|
||||
labels, and supbatterns.
|
||||
|
|
@ -220,13 +223,13 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
pat = memo[pat_id]
|
||||
return pat
|
||||
|
||||
def dfs(self,
|
||||
def dfs(self: P,
|
||||
visit_before: visitor_function_t = None,
|
||||
visit_after: visitor_function_t = None,
|
||||
transform: Union[numpy.ndarray, bool, None] = False,
|
||||
memo: Optional[Dict] = None,
|
||||
hierarchy: Tuple['Pattern', ...] = (),
|
||||
) -> 'Pattern':
|
||||
hierarchy: Tuple[P, ...] = (),
|
||||
) -> P:
|
||||
"""
|
||||
Experimental convenience function.
|
||||
Performs a depth-first traversal of this pattern and its subpatterns.
|
||||
|
|
@ -305,10 +308,10 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
pat = visit_after(pat, hierarchy=hierarchy, memo=memo, transform=transform) # type: ignore
|
||||
return pat
|
||||
|
||||
def polygonize(self,
|
||||
def polygonize(self: P,
|
||||
poly_num_points: Optional[int] = None,
|
||||
poly_max_arclen: Optional[float] = None,
|
||||
) -> 'Pattern':
|
||||
) -> P:
|
||||
"""
|
||||
Calls `.to_polygons(...)` on all the shapes in this Pattern and any referenced patterns,
|
||||
replacing them with the returned polygons.
|
||||
|
|
@ -333,10 +336,10 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
subpat.pattern.polygonize(poly_num_points, poly_max_arclen)
|
||||
return self
|
||||
|
||||
def manhattanize(self,
|
||||
def manhattanize(self: P,
|
||||
grid_x: numpy.ndarray,
|
||||
grid_y: numpy.ndarray,
|
||||
) -> 'Pattern':
|
||||
) -> P:
|
||||
"""
|
||||
Calls `.polygonize()` and `.flatten()` on the pattern, then calls `.manhattanize()` on all the
|
||||
resulting shapes, replacing them with the returned Manhattan polygons.
|
||||
|
|
@ -355,11 +358,11 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
(shape.manhattanize(grid_x, grid_y) for shape in old_shapes)))
|
||||
return self
|
||||
|
||||
def subpatternize(self,
|
||||
def subpatternize(self: P,
|
||||
recursive: bool = True,
|
||||
norm_value: int = int(1e6),
|
||||
exclude_types: Tuple[Type] = (Polygon,)
|
||||
) -> 'Pattern':
|
||||
) -> P:
|
||||
"""
|
||||
Iterates through this `Pattern` and all referenced `Pattern`s. Within each `Pattern`, it iterates
|
||||
over all shapes, calling `.normalized_form(norm_value)` on them to retrieve a scale-,
|
||||
|
|
@ -476,7 +479,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
ids.update(pat.referenced_patterns_by_id())
|
||||
return ids
|
||||
|
||||
def referenced_patterns_by_name(self, **kwargs) -> List[Tuple[Optional[str], Optional['Pattern']]]:
|
||||
def referenced_patterns_by_name(self, **kwargs: Any) -> List[Tuple[Optional[str], Optional['Pattern']]]:
|
||||
"""
|
||||
Create a list of `(pat.name, pat)` tuples for all Pattern objects referenced by this
|
||||
Pattern (operates recursively on all referenced Patterns as well).
|
||||
|
|
@ -544,7 +547,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
else:
|
||||
return numpy.vstack((min_bounds, max_bounds))
|
||||
|
||||
def flatten(self) -> 'Pattern':
|
||||
def flatten(self: P) -> P:
|
||||
"""
|
||||
Removes all subpatterns and adds equivalent shapes.
|
||||
|
||||
|
|
@ -580,10 +583,10 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
self.append(p)
|
||||
return self
|
||||
|
||||
def wrap_repeated_shapes(self,
|
||||
def wrap_repeated_shapes(self: P,
|
||||
name_func: Callable[['Pattern', Union[Shape, Label]], str] = lambda p, s: '_repetition',
|
||||
recursive: bool = True,
|
||||
) -> 'Pattern':
|
||||
) -> P:
|
||||
"""
|
||||
Wraps all shapes and labels with a non-`None` `repetition` attribute
|
||||
into a `SubPattern`/`Pattern` combination, and applies the `repetition`
|
||||
|
|
@ -625,7 +628,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
|
||||
return self
|
||||
|
||||
def translate_elements(self, offset: vector2) -> 'Pattern':
|
||||
def translate_elements(self: P, offset: vector2) -> P:
|
||||
"""
|
||||
Translates all shapes, label, and subpatterns by the given offset.
|
||||
|
||||
|
|
@ -639,7 +642,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
entry.translate(offset)
|
||||
return self
|
||||
|
||||
def scale_elements(self, c: float) -> 'Pattern':
|
||||
def scale_elements(self: P, c: float) -> P:
|
||||
""""
|
||||
Scales all shapes and subpatterns by the given value.
|
||||
|
||||
|
|
@ -653,7 +656,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
entry.scale_by(c)
|
||||
return self
|
||||
|
||||
def scale_by(self, c: float) -> 'Pattern':
|
||||
def scale_by(self: P, c: float) -> P:
|
||||
"""
|
||||
Scale this Pattern by the given value
|
||||
(all shapes and subpatterns and their offsets are scaled)
|
||||
|
|
@ -672,7 +675,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
label.offset *= c
|
||||
return self
|
||||
|
||||
def rotate_around(self, pivot: vector2, rotation: float) -> 'Pattern':
|
||||
def rotate_around(self: P, pivot: vector2, rotation: float) -> P:
|
||||
"""
|
||||
Rotate the Pattern around the a location.
|
||||
|
||||
|
|
@ -690,7 +693,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
self.translate_elements(+pivot)
|
||||
return self
|
||||
|
||||
def rotate_element_centers(self, rotation: float) -> 'Pattern':
|
||||
def rotate_element_centers(self: P, rotation: float) -> P:
|
||||
"""
|
||||
Rotate the offsets of all shapes, labels, and subpatterns around (0, 0)
|
||||
|
||||
|
|
@ -704,7 +707,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
entry.offset = numpy.dot(rotation_matrix_2d(rotation), entry.offset)
|
||||
return self
|
||||
|
||||
def rotate_elements(self, rotation: float) -> 'Pattern':
|
||||
def rotate_elements(self: P, rotation: float) -> P:
|
||||
"""
|
||||
Rotate each shape and subpattern around its center (offset)
|
||||
|
||||
|
|
@ -718,7 +721,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
entry.rotate(rotation)
|
||||
return self
|
||||
|
||||
def mirror_element_centers(self, axis: int) -> 'Pattern':
|
||||
def mirror_element_centers(self: P, axis: int) -> P:
|
||||
"""
|
||||
Mirror the offsets of all shapes, labels, and subpatterns across an axis
|
||||
|
||||
|
|
@ -733,7 +736,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
entry.offset[axis - 1] *= -1
|
||||
return self
|
||||
|
||||
def mirror_elements(self, axis: int) -> 'Pattern':
|
||||
def mirror_elements(self: P, axis: int) -> P:
|
||||
"""
|
||||
Mirror each shape and subpattern across an axis, relative to its
|
||||
offset
|
||||
|
|
@ -749,7 +752,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
entry.mirror(axis)
|
||||
return self
|
||||
|
||||
def mirror(self, axis: int) -> 'Pattern':
|
||||
def mirror(self: P, axis: int) -> P:
|
||||
"""
|
||||
Mirror the Pattern across an axis
|
||||
|
||||
|
|
@ -764,7 +767,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
self.mirror_element_centers(axis)
|
||||
return self
|
||||
|
||||
def scale_element_doses(self, c: float) -> 'Pattern':
|
||||
def scale_element_doses(self: P, c: float) -> P:
|
||||
"""
|
||||
Multiply all shape and subpattern doses by a factor
|
||||
|
||||
|
|
@ -778,7 +781,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
entry.dose *= c
|
||||
return self
|
||||
|
||||
def copy(self) -> 'Pattern':
|
||||
def copy(self: P) -> P:
|
||||
"""
|
||||
Return a copy of the Pattern, deep-copying shapes and copying subpattern
|
||||
entries, but not deep-copying any referenced patterns.
|
||||
|
|
@ -790,7 +793,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
"""
|
||||
return copy.copy(self)
|
||||
|
||||
def deepcopy(self) -> 'Pattern':
|
||||
def deepcopy(self: P) -> P:
|
||||
"""
|
||||
Convenience method for `copy.deepcopy(pattern)`
|
||||
|
||||
|
|
@ -808,7 +811,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
and len(self.shapes) == 0
|
||||
and len(self.labels) == 0)
|
||||
|
||||
def lock(self) -> 'Pattern':
|
||||
def lock(self: P) -> P:
|
||||
"""
|
||||
Lock the pattern, raising an exception if it is modified.
|
||||
Also see `deeplock()`.
|
||||
|
|
@ -823,7 +826,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
LockableImpl.lock(self)
|
||||
return self
|
||||
|
||||
def unlock(self) -> 'Pattern':
|
||||
def unlock(self: P) -> P:
|
||||
"""
|
||||
Unlock the pattern
|
||||
|
||||
|
|
@ -837,7 +840,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
self.subpatterns = list(self.subpatterns)
|
||||
return self
|
||||
|
||||
def deeplock(self) -> 'Pattern':
|
||||
def deeplock(self: P) -> P:
|
||||
"""
|
||||
Recursively lock the pattern, all referenced shapes, subpatterns, and labels.
|
||||
|
||||
|
|
@ -851,7 +854,7 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
sp.deeplock()
|
||||
return self
|
||||
|
||||
def deepunlock(self) -> 'Pattern':
|
||||
def deepunlock(self: P) -> P:
|
||||
"""
|
||||
Recursively unlock the pattern, all referenced shapes, subpatterns, and labels.
|
||||
|
||||
|
|
@ -902,7 +905,8 @@ class Pattern(LockableImpl, AnnotatableImpl, metaclass=AutoSlots):
|
|||
offset: vector2 = (0., 0.),
|
||||
line_color: str = 'k',
|
||||
fill_color: str = 'none',
|
||||
overdraw: bool = False):
|
||||
overdraw: bool = False,
|
||||
) -> None:
|
||||
"""
|
||||
Draw a picture of the Pattern and wait for the user to inspect it
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue