Improve type annotations based on mypy errors
This commit is contained in:
parent
bd4085365f
commit
157df47884
13 changed files with 151 additions and 117 deletions
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Tuple, Dict
|
||||
from typing import List, Tuple, Dict, Optional, Sequence
|
||||
import copy
|
||||
import math
|
||||
import numpy
|
||||
|
|
@ -32,10 +32,10 @@ class Arc(Shape):
|
|||
_width: float
|
||||
""" Width of the arc """
|
||||
|
||||
poly_num_points: int
|
||||
poly_num_points: Optional[int]
|
||||
""" Sets the default number of points for `.polygonize()` """
|
||||
|
||||
poly_max_arclen: float
|
||||
poly_max_arclen: Optional[float]
|
||||
""" Sets the default max segement length for `.polygonize()` """
|
||||
|
||||
# radius properties
|
||||
|
|
@ -77,7 +77,7 @@ class Arc(Shape):
|
|||
|
||||
# arc start/stop angle properties
|
||||
@property
|
||||
def angles(self) -> vector2:
|
||||
def angles(self) -> numpy.ndarray: #ndarray[float]
|
||||
"""
|
||||
Return the start and stop angles `[a_start, a_stop]`.
|
||||
Angles are measured from x-axis after rotation
|
||||
|
|
@ -150,11 +150,11 @@ class Arc(Shape):
|
|||
radii: vector2,
|
||||
angles: vector2,
|
||||
width: float,
|
||||
poly_num_points: int = DEFAULT_POLY_NUM_POINTS,
|
||||
poly_max_arclen: float = None,
|
||||
poly_num_points: Optional[int] = DEFAULT_POLY_NUM_POINTS,
|
||||
poly_max_arclen: Optional[float] = None,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
locked: bool = False):
|
||||
|
|
@ -182,8 +182,8 @@ class Arc(Shape):
|
|||
return new
|
||||
|
||||
def to_polygons(self,
|
||||
poly_num_points: int = None,
|
||||
poly_max_arclen: float = None,
|
||||
poly_num_points: Optional[int] = None,
|
||||
poly_max_arclen: Optional[float] = None,
|
||||
) -> List[Polygon]:
|
||||
if poly_num_points is None:
|
||||
poly_num_points = self.poly_num_points
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Dict
|
||||
from typing import List, Dict, Optional
|
||||
import copy
|
||||
import numpy
|
||||
from numpy import pi
|
||||
|
|
@ -16,10 +16,10 @@ class Circle(Shape):
|
|||
_radius: float
|
||||
""" Circle radius """
|
||||
|
||||
poly_num_points: int
|
||||
poly_num_points: Optional[int]
|
||||
""" Sets the default number of points for `.polygonize()` """
|
||||
|
||||
poly_max_arclen: float
|
||||
poly_max_arclen: Optional[float]
|
||||
""" Sets the default max segement length for `.polygonize()` """
|
||||
|
||||
# radius property
|
||||
|
|
@ -40,8 +40,8 @@ class Circle(Shape):
|
|||
|
||||
def __init__(self,
|
||||
radius: float,
|
||||
poly_num_points: int = DEFAULT_POLY_NUM_POINTS,
|
||||
poly_max_arclen: float = None,
|
||||
poly_num_points: Optional[int] = DEFAULT_POLY_NUM_POINTS,
|
||||
poly_max_arclen: Optional[float] = None,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
|
|
@ -64,8 +64,8 @@ class Circle(Shape):
|
|||
return new
|
||||
|
||||
def to_polygons(self,
|
||||
poly_num_points: int = None,
|
||||
poly_max_arclen: float = None,
|
||||
poly_num_points: Optional[int] = None,
|
||||
poly_max_arclen: Optional[float] = None,
|
||||
) -> List[Polygon]:
|
||||
if poly_num_points is None:
|
||||
poly_num_points = self.poly_num_points
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Tuple, Dict
|
||||
from typing import List, Tuple, Dict, Sequence, Optional
|
||||
import copy
|
||||
import math
|
||||
import numpy
|
||||
|
|
@ -22,10 +22,10 @@ class Ellipse(Shape):
|
|||
_rotation: float
|
||||
""" Angle from x-axis to first radius (ccw, radians) """
|
||||
|
||||
poly_num_points: int
|
||||
poly_num_points: Optional[int]
|
||||
""" Sets the default number of points for `.polygonize()` """
|
||||
|
||||
poly_max_arclen: float
|
||||
poly_max_arclen: Optional[float]
|
||||
""" Sets the default max segement length for `.polygonize()` """
|
||||
|
||||
# radius properties
|
||||
|
|
@ -85,11 +85,11 @@ class Ellipse(Shape):
|
|||
|
||||
def __init__(self,
|
||||
radii: vector2,
|
||||
poly_num_points: int = DEFAULT_POLY_NUM_POINTS,
|
||||
poly_max_arclen: float = None,
|
||||
poly_num_points: Optional[int] = DEFAULT_POLY_NUM_POINTS,
|
||||
poly_max_arclen: Optional[float] = None,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
locked: bool = False):
|
||||
|
|
@ -114,8 +114,8 @@ class Ellipse(Shape):
|
|||
return new
|
||||
|
||||
def to_polygons(self,
|
||||
poly_num_points: int = None,
|
||||
poly_max_arclen: float = None,
|
||||
poly_num_points: Optional[int] = None,
|
||||
poly_max_arclen: Optional[float] = None,
|
||||
) -> List[Polygon]:
|
||||
if poly_num_points is None:
|
||||
poly_num_points = self.poly_num_points
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Tuple, Dict
|
||||
from typing import List, Tuple, Dict, Optional, Sequence
|
||||
import copy
|
||||
from enum import Enum
|
||||
import numpy
|
||||
|
|
@ -28,8 +28,8 @@ class Path(Shape):
|
|||
__slots__ = ('_vertices', '_width', '_cap', '_cap_extensions')
|
||||
_vertices: numpy.ndarray
|
||||
_width: float
|
||||
_cap_extensions: numpy.ndarray or None
|
||||
_cap: PathCap
|
||||
_cap_extensions: Optional[numpy.ndarray]
|
||||
|
||||
Cap = PathCap
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ class Path(Shape):
|
|||
|
||||
# cap_extensions property
|
||||
@property
|
||||
def cap_extensions(self) -> numpy.ndarray or None:
|
||||
def cap_extensions(self) -> Optional[numpy.ndarray]:
|
||||
"""
|
||||
Path end-cap extension
|
||||
|
||||
|
|
@ -144,11 +144,11 @@ class Path(Shape):
|
|||
cap_extensions: numpy.ndarray = None,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
locked: bool = False,
|
||||
) -> 'Path':
|
||||
):
|
||||
self.unlock()
|
||||
self._cap_extensions = None # Since .cap setter might access it
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ class Path(Shape):
|
|||
cap_extensions = None,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
) -> 'Path':
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Tuple, Dict
|
||||
from typing import List, Tuple, Dict, Optional, Sequence
|
||||
import copy
|
||||
import numpy
|
||||
from numpy import pi
|
||||
|
|
@ -71,7 +71,7 @@ class Polygon(Shape):
|
|||
vertices: numpy.ndarray,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
rotation: float = 0.0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
locked: bool = False,
|
||||
|
|
@ -86,7 +86,7 @@ class Polygon(Shape):
|
|||
[self.mirror(a) for a, do in enumerate(mirrored) if do]
|
||||
self.locked = locked
|
||||
|
||||
def __deepcopy__(self, memo: Dict = None) -> 'Polygon':
|
||||
def __deepcopy__(self, memo: Optional[Dict] = None) -> 'Polygon':
|
||||
memo = {} if memo is None else memo
|
||||
new = copy.copy(self).unlock()
|
||||
new._offset = self._offset.copy()
|
||||
|
|
@ -154,14 +154,14 @@ class Polygon(Shape):
|
|||
return poly
|
||||
|
||||
@staticmethod
|
||||
def rect(xmin: float = None,
|
||||
xctr: float = None,
|
||||
xmax: float = None,
|
||||
lx: float = None,
|
||||
ymin: float = None,
|
||||
yctr: float = None,
|
||||
ymax: float = None,
|
||||
ly: float = None,
|
||||
def rect(xmin: Optional[float] = None,
|
||||
xctr: Optional[float] = None,
|
||||
xmax: Optional[float] = None,
|
||||
lx: Optional[float] = None,
|
||||
ymin: Optional[float] = None,
|
||||
yctr: Optional[float] = None,
|
||||
ymax: Optional[float] = None,
|
||||
ly: Optional[float] = None,
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
) -> 'Polygon':
|
||||
|
|
@ -188,11 +188,17 @@ class Polygon(Shape):
|
|||
"""
|
||||
if lx is None:
|
||||
if xctr is None:
|
||||
assert(xmin is not None)
|
||||
assert(xmax is not None)
|
||||
xctr = 0.5 * (xmax + xmin)
|
||||
lx = xmax - xmin
|
||||
elif xmax is None:
|
||||
assert(xmin is not None)
|
||||
assert(xctr is not None)
|
||||
lx = 2 * (xctr - xmin)
|
||||
elif xmin is None:
|
||||
assert(xctr is not None)
|
||||
assert(xmax is not None)
|
||||
lx = 2 * (xmax - xctr)
|
||||
else:
|
||||
raise PatternError('Two of xmin, xctr, xmax, lx must be None!')
|
||||
|
|
@ -200,19 +206,29 @@ class Polygon(Shape):
|
|||
if xctr is not None:
|
||||
pass
|
||||
elif xmax is None:
|
||||
assert(xmin is not None)
|
||||
assert(lx is not None)
|
||||
xctr = xmin + 0.5 * lx
|
||||
elif xmin is None:
|
||||
assert(xmax is not None)
|
||||
assert(lx is not None)
|
||||
xctr = xmax - 0.5 * lx
|
||||
else:
|
||||
raise PatternError('Two of xmin, xctr, xmax, lx must be None!')
|
||||
|
||||
if ly is None:
|
||||
if yctr is None:
|
||||
assert(ymin is not None)
|
||||
assert(ymax is not None)
|
||||
yctr = 0.5 * (ymax + ymin)
|
||||
ly = ymax - ymin
|
||||
elif ymax is None:
|
||||
assert(ymin is not None)
|
||||
assert(yctr is not None)
|
||||
ly = 2 * (yctr - ymin)
|
||||
elif ymin is None:
|
||||
assert(yctr is not None)
|
||||
assert(ymax is not None)
|
||||
ly = 2 * (ymax - yctr)
|
||||
else:
|
||||
raise PatternError('Two of ymin, yctr, ymax, ly must be None!')
|
||||
|
|
@ -220,8 +236,12 @@ class Polygon(Shape):
|
|||
if yctr is not None:
|
||||
pass
|
||||
elif ymax is None:
|
||||
assert(ymin is not None)
|
||||
assert(ly is not None)
|
||||
yctr = ymin + 0.5 * ly
|
||||
elif ymin is None:
|
||||
assert(ly is not None)
|
||||
assert(ymax is not None)
|
||||
yctr = ymax - 0.5 * ly
|
||||
else:
|
||||
raise PatternError('Two of ymin, yctr, ymax, ly must be None!')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Tuple, Callable
|
||||
from typing import List, Tuple, Callable, TypeVar, Optional, TYPE_CHECKING
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import copy
|
||||
import numpy
|
||||
|
|
@ -6,6 +6,8 @@ import numpy
|
|||
from ..error import PatternError, PatternLockedError
|
||||
from ..utils import is_scalar, rotation_matrix_2d, vector2, layer_t
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import Polygon
|
||||
|
||||
|
||||
# Type definitions
|
||||
|
|
@ -18,6 +20,9 @@ normalized_shape_tuple = Tuple[Tuple,
|
|||
DEFAULT_POLY_NUM_POINTS = 24
|
||||
|
||||
|
||||
T = TypeVar('T', bound='Shape')
|
||||
|
||||
|
||||
class Shape(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class specifying functions common to all shapes.
|
||||
|
|
@ -53,7 +58,10 @@ class Shape(metaclass=ABCMeta):
|
|||
|
||||
# --- Abstract methods
|
||||
@abstractmethod
|
||||
def to_polygons(self, num_vertices: int, max_arclen: float) -> List['Polygon']:
|
||||
def to_polygons(self,
|
||||
num_vertices: Optional[int] = None,
|
||||
max_arclen: Optional[float] = None,
|
||||
) -> List['Polygon']:
|
||||
"""
|
||||
Returns a list of polygons which approximate the shape.
|
||||
|
||||
|
|
@ -77,7 +85,7 @@ class Shape(metaclass=ABCMeta):
|
|||
pass
|
||||
|
||||
@abstractmethod
|
||||
def rotate(self, theta: float) -> 'Shape':
|
||||
def rotate(self: T, theta: float) -> T:
|
||||
"""
|
||||
Rotate the shape around its origin (0, 0), ignoring its offset.
|
||||
|
||||
|
|
@ -90,7 +98,7 @@ class Shape(metaclass=ABCMeta):
|
|||
pass
|
||||
|
||||
@abstractmethod
|
||||
def mirror(self, axis: int) -> 'Shape':
|
||||
def mirror(self: T, axis: int) -> T:
|
||||
"""
|
||||
Mirror the shape across an axis.
|
||||
|
||||
|
|
@ -104,7 +112,7 @@ class Shape(metaclass=ABCMeta):
|
|||
pass
|
||||
|
||||
@abstractmethod
|
||||
def scale_by(self, c: float) -> 'Shape':
|
||||
def scale_by(self: T, c: float) -> T:
|
||||
"""
|
||||
Scale the shape's size (eg. radius, for a circle) by a constant factor.
|
||||
|
||||
|
|
@ -117,7 +125,7 @@ class Shape(metaclass=ABCMeta):
|
|||
pass
|
||||
|
||||
@abstractmethod
|
||||
def normalized_form(self, norm_value: int) -> normalized_shape_tuple:
|
||||
def normalized_form(self: T, norm_value: int) -> normalized_shape_tuple:
|
||||
"""
|
||||
Writes the shape in a standardized notation, with offset, scale, rotation, and dose
|
||||
information separated out from the remaining values.
|
||||
|
|
@ -187,7 +195,7 @@ class Shape(metaclass=ABCMeta):
|
|||
self._dose = val
|
||||
|
||||
# ---- Non-abstract methods
|
||||
def copy(self) -> 'Shape':
|
||||
def copy(self: T) -> T:
|
||||
"""
|
||||
Returns a deep copy of the shape.
|
||||
|
||||
|
|
@ -196,7 +204,7 @@ class Shape(metaclass=ABCMeta):
|
|||
"""
|
||||
return copy.deepcopy(self)
|
||||
|
||||
def translate(self, offset: vector2) -> 'Shape':
|
||||
def translate(self: T, offset: vector2) -> T:
|
||||
"""
|
||||
Translate the shape by the given offset
|
||||
|
||||
|
|
@ -209,7 +217,7 @@ class Shape(metaclass=ABCMeta):
|
|||
self.offset += offset
|
||||
return self
|
||||
|
||||
def rotate_around(self, pivot: vector2, rotation: float) -> 'Shape':
|
||||
def rotate_around(self: T, pivot: vector2, rotation: float) -> T:
|
||||
"""
|
||||
Rotate the shape around a point.
|
||||
|
||||
|
|
@ -428,7 +436,7 @@ class Shape(metaclass=ABCMeta):
|
|||
|
||||
return manhattan_polygons
|
||||
|
||||
def lock(self) -> 'Shape':
|
||||
def lock(self: T) -> T:
|
||||
"""
|
||||
Lock the Shape, disallowing further changes
|
||||
|
||||
|
|
@ -438,7 +446,7 @@ class Shape(metaclass=ABCMeta):
|
|||
object.__setattr__(self, 'locked', True)
|
||||
return self
|
||||
|
||||
def unlock(self) -> 'Shape':
|
||||
def unlock(self: T) -> T:
|
||||
"""
|
||||
Unlock the Shape
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Tuple, Dict
|
||||
from typing import List, Tuple, Dict, Sequence, Optional, MutableSequence
|
||||
import copy
|
||||
import numpy
|
||||
from numpy import pi, inf
|
||||
|
|
@ -21,7 +21,7 @@ class Text(Shape):
|
|||
_string: str
|
||||
_height: float
|
||||
_rotation: float
|
||||
_mirrored: List[str]
|
||||
_mirrored: numpy.ndarray #ndarray[bool]
|
||||
font_path: str
|
||||
|
||||
# vertices property
|
||||
|
|
@ -57,11 +57,11 @@ class Text(Shape):
|
|||
|
||||
# Mirrored property
|
||||
@property
|
||||
def mirrored(self) -> List[bool]:
|
||||
def mirrored(self) -> numpy.ndarray: #ndarray[bool]
|
||||
return self._mirrored
|
||||
|
||||
@mirrored.setter
|
||||
def mirrored(self, val: List[bool]):
|
||||
def mirrored(self, val: Sequence[bool]):
|
||||
if is_scalar(val):
|
||||
raise PatternError('Mirrored must be a 2-element list of booleans')
|
||||
self._mirrored = numpy.ndarray(val, dtype=bool, copy=True)
|
||||
|
|
@ -72,7 +72,7 @@ class Text(Shape):
|
|||
font_path: str,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
rotation: float = 0.0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
mirrored: Tuple[bool, bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
dose: float = 1.0,
|
||||
locked: bool = False,
|
||||
|
|
@ -98,11 +98,11 @@ class Text(Shape):
|
|||
return new
|
||||
|
||||
def to_polygons(self,
|
||||
poly_num_points: int = None, # unused
|
||||
poly_max_arclen: float = None, # unused
|
||||
poly_num_points: Optional[int] = None, # unused
|
||||
poly_max_arclen: Optional[float] = None, # unused
|
||||
) -> List[Polygon]:
|
||||
all_polygons = []
|
||||
total_advance = 0
|
||||
total_advance = 0.0
|
||||
for char in self.string:
|
||||
raw_polys, advance = get_char_as_polygons(self.font_path, char)
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ def get_char_as_polygons(font_path: str,
|
|||
tags = outline.tags[start:end + 1]
|
||||
tags.append(tags[0])
|
||||
|
||||
segments = []
|
||||
segments: List[List[List[float]]] = []
|
||||
for j, point in enumerate(points):
|
||||
# If we already have a segment, add this point to it
|
||||
if j > 0:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue