From 284c7e4fd0f3671d538e38e91fcea1d4be5b087b Mon Sep 17 00:00:00 2001 From: jan Date: Tue, 15 Apr 2025 17:25:56 -0700 Subject: [PATCH] Use quoted first arg for cast() ruff rule TC006 --- masque/builder/utils.py | 8 ++++---- masque/file/dxf.py | 2 +- masque/file/gdsii.py | 2 +- masque/file/oasis.py | 18 +++++++++--------- masque/library.py | 12 ++++++------ masque/pattern.py | 28 ++++++++++++++-------------- masque/repetition.py | 4 ++-- masque/shapes/arc.py | 8 ++++---- masque/shapes/circle.py | 2 +- masque/shapes/ellipse.py | 2 +- masque/shapes/path.py | 4 ++-- masque/shapes/polygon.py | 10 ++++++---- masque/shapes/text.py | 2 +- masque/traits/rotatable.py | 11 ++++++----- 14 files changed, 58 insertions(+), 55 deletions(-) diff --git a/masque/builder/utils.py b/masque/builder/utils.py index 6e3334d..3109f46 100644 --- a/masque/builder/utils.py +++ b/masque/builder/utils.py @@ -169,11 +169,11 @@ def ell( 'emax', 'max_extension', 'min_past_furthest',): if numpy.size(bound) == 2: - bound = cast(Sequence[float], bound) + bound = cast('Sequence[float]', bound) rot_bound = (rot_matrix @ ((bound[0], 0), (0, bound[1])))[0, :] else: - bound = cast(float, bound) + bound = cast('float', bound) rot_bound = numpy.array(bound) if rot_bound < 0: @@ -185,10 +185,10 @@ def ell( offsets += rot_bound.min() - offsets.max() else: if numpy.size(bound) == 2: - bound = cast(Sequence[float], bound) + bound = cast('Sequence[float]', bound) rot_bound = (rot_matrix @ bound)[0] else: - bound = cast(float, bound) + bound = cast('float', bound) neg = (direction + pi / 4) % (2 * pi) > pi rot_bound = -bound if neg else bound diff --git a/masque/file/dxf.py b/masque/file/dxf.py index dc3d6f3..1cf5e88 100644 --- a/masque/file/dxf.py +++ b/masque/file/dxf.py @@ -132,7 +132,7 @@ def writefile( with tmpfile(path) as base_stream: streams: tuple[Any, ...] = (base_stream,) if path.suffix == '.gz': - gz_stream = cast(IO[bytes], gzip.GzipFile(filename='', mtime=0, fileobj=base_stream, mode='wb')) + gz_stream = cast('IO[bytes]', gzip.GzipFile(filename='', mtime=0, fileobj=base_stream, mode='wb')) streams = (gz_stream,) + streams else: gz_stream = base_stream diff --git a/masque/file/gdsii.py b/masque/file/gdsii.py index 71ea94f..c323ecf 100644 --- a/masque/file/gdsii.py +++ b/masque/file/gdsii.py @@ -145,7 +145,7 @@ def writefile( with tmpfile(path) as base_stream: streams: tuple[Any, ...] = (base_stream,) if path.suffix == '.gz': - stream = cast(IO[bytes], gzip.GzipFile(filename='', mtime=0, fileobj=base_stream, mode='wb', compresslevel=6)) + stream = cast('IO[bytes]', gzip.GzipFile(filename='', mtime=0, fileobj=base_stream, mode='wb', compresslevel=6)) streams = (stream,) + streams else: stream = base_stream diff --git a/masque/file/oasis.py b/masque/file/oasis.py index 0e2305a..e64bb4c 100644 --- a/masque/file/oasis.py +++ b/masque/file/oasis.py @@ -190,7 +190,7 @@ def writefile( with tmpfile(path) as base_stream: streams: tuple[Any, ...] = (base_stream,) if path.suffix == '.gz': - stream = cast(IO[bytes], gzip.GzipFile(filename='', mtime=0, fileobj=base_stream, mode='wb')) + stream = cast('IO[bytes]', gzip.GzipFile(filename='', mtime=0, fileobj=base_stream, mode='wb')) streams += (stream,) else: stream = base_stream @@ -551,7 +551,7 @@ def _shapes_to_elements( circle = fatrec.Circle( layer=layer, datatype=datatype, - radius=cast(int, radius), + radius=cast('int', radius), x=offset[0], y=offset[1], properties=properties, @@ -568,8 +568,8 @@ def _shapes_to_elements( path = fatrec.Path( layer=layer, datatype=datatype, - point_list=cast(Sequence[Sequence[int]], deltas), - half_width=cast(int, half_width), + point_list=cast('Sequence[Sequence[int]]', deltas), + half_width=cast('int', half_width), x=xy[0], y=xy[1], extension_start=extension_start, # TODO implement multiple cap types? @@ -587,7 +587,7 @@ def _shapes_to_elements( datatype=datatype, x=xy[0], y=xy[1], - point_list=cast(list[list[int]], points), + point_list=cast('list[list[int]]', points), properties=properties, repetition=repetition, )) @@ -651,10 +651,10 @@ def repetition_masq2fata( a_count = rint_cast(rep.a_count) b_count = rint_cast(rep.b_count) if rep.b_count is not None else None frep = fatamorgana.GridRepetition( - a_vector=cast(list[int], a_vector), - b_vector=cast(list[int] | None, b_vector), - a_count=cast(int, a_count), - b_count=cast(int | None, b_count), + a_vector=cast('list[int]', a_vector), + b_vector=cast('list[int] | None', b_vector), + a_count=cast('int', a_count), + b_count=cast('int | None', b_count), ) offset = (0, 0) elif isinstance(rep, Arbitrary): diff --git a/masque/library.py b/masque/library.py index 90202dc..e41d27f 100644 --- a/masque/library.py +++ b/masque/library.py @@ -211,7 +211,7 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta): if isinstance(tops, str): tops = (tops,) - keep = cast(set[str], self.referenced_patterns(tops) - {None}) + keep = cast('set[str]', self.referenced_patterns(tops) - {None}) keep |= set(tops) filtered = {kk: vv for kk, vv in self.items() if kk in keep} @@ -314,7 +314,7 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta): flatten_single(top) assert None not in flattened.values() - return cast(dict[str, 'Pattern'], flattened) + return cast('dict[str, Pattern]', flattened) def get_name( self, @@ -504,7 +504,7 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta): raise LibraryError('visit_* functions returned a new `Pattern` object' ' but no top-level name was provided in `hierarchy`') - cast(ILibrary, self)[name] = pattern + cast('ILibrary', self)[name] = pattern return self @@ -542,7 +542,7 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta): Return: Topologically sorted list of pattern names. """ - return cast(list[str], list(TopologicalSorter(self.child_graph()).static_order())) + return cast('list[str]', list(TopologicalSorter(self.child_graph()).static_order())) def find_refs_local( self, @@ -827,7 +827,7 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta): for old_name in temp: new_name = rename_map.get(old_name, old_name) pat = self[new_name] - pat.refs = map_targets(pat.refs, lambda tt: cast(dict[str | None, str | None], rename_map).get(tt, tt)) + pat.refs = map_targets(pat.refs, lambda tt: cast('dict[str | None, str | None]', rename_map).get(tt, tt)) return rename_map @@ -1047,7 +1047,7 @@ class ILibrary(ILibraryView, MutableMapping[str, 'Pattern'], metaclass=ABCMeta): if isinstance(tops, str): tops = (tops,) - keep = cast(set[str], self.referenced_patterns(tops) - {None}) + keep = cast('set[str]', self.referenced_patterns(tops) - {None}) keep |= set(tops) new = type(self)() diff --git a/masque/pattern.py b/masque/pattern.py index afd73fc..5bf030a 100644 --- a/masque/pattern.py +++ b/masque/pattern.py @@ -491,7 +491,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): """ pat = self.deepcopy().polygonize().flatten(library=library) polys = [ - cast(Polygon, shape).vertices + cast(Polygon, shape).offset + cast('Polygon', shape).vertices + cast('Polygon', shape).offset for shape in chain_elements(pat.shapes) ] return polys @@ -533,7 +533,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): n_elems = sum(1 for _ in chain_elements(self.shapes, self.labels)) ebounds = numpy.full((n_elems, 2, 2), nan) for ee, entry in enumerate(chain_elements(self.shapes, self.labels)): - maybe_ebounds = cast(Bounded, entry).get_bounds() + maybe_ebounds = cast('Bounded', entry).get_bounds() if maybe_ebounds is not None: ebounds[ee] = maybe_ebounds mask = ~numpy.isnan(ebounds[:, 0, 0]) @@ -631,7 +631,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self """ for entry in chain(chain_elements(self.shapes, self.labels, self.refs), self.ports.values()): - cast(Positionable, entry).translate(offset) + cast('Positionable', entry).translate(offset) return self def scale_elements(self, c: float) -> Self: @@ -645,7 +645,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self """ for entry in chain_elements(self.shapes, self.refs): - cast(Scalable, entry).scale_by(c) + cast('Scalable', entry).scale_by(c) return self def scale_by(self, c: float, scale_refs: bool = True) -> Self: @@ -664,18 +664,18 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self """ for entry in chain_elements(self.shapes, self.refs): - cast(Positionable, entry).offset *= c + cast('Positionable', entry).offset *= c if scale_refs or not isinstance(entry, Ref): - cast(Scalable, entry).scale_by(c) + cast('Scalable', entry).scale_by(c) - rep = cast(Repeatable, entry).repetition + rep = cast('Repeatable', entry).repetition if rep: rep.scale_by(c) for label in chain_elements(self.labels): - cast(Positionable, label).offset *= c + cast('Positionable', label).offset *= c - rep = cast(Repeatable, label).repetition + rep = cast('Repeatable', label).repetition if rep: rep.scale_by(c) @@ -712,8 +712,8 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self """ for entry in chain(chain_elements(self.shapes, self.refs, self.labels), self.ports.values()): - old_offset = cast(Positionable, entry).offset - cast(Positionable, entry).offset = numpy.dot(rotation_matrix_2d(rotation), old_offset) + old_offset = cast('Positionable', entry).offset + cast('Positionable', entry).offset = numpy.dot(rotation_matrix_2d(rotation), old_offset) return self def rotate_elements(self, rotation: float) -> Self: @@ -727,7 +727,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self """ for entry in chain(chain_elements(self.shapes, self.refs), self.ports.values()): - cast(Rotatable, entry).rotate(rotation) + cast('Rotatable', entry).rotate(rotation) return self def mirror_element_centers(self, across_axis: int = 0) -> Self: @@ -742,7 +742,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self """ for entry in chain(chain_elements(self.shapes, self.refs, self.labels), self.ports.values()): - cast(Positionable, entry).offset[across_axis - 1] *= -1 + cast('Positionable', entry).offset[across_axis - 1] *= -1 return self def mirror_elements(self, across_axis: int = 0) -> Self: @@ -758,7 +758,7 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable): self """ for entry in chain(chain_elements(self.shapes, self.refs), self.ports.values()): - cast(Mirrorable, entry).mirror(across_axis) + cast('Mirrorable', entry).mirror(across_axis) return self def mirror(self, across_axis: int = 0) -> Self: diff --git a/masque/repetition.py b/masque/repetition.py index a365909..e6d00fc 100644 --- a/masque/repetition.py +++ b/masque/repetition.py @@ -294,7 +294,7 @@ class Grid(Repetition): def __le__(self, other: Repetition) -> bool: if type(self) is not type(other): return repr(type(self)) < repr(type(other)) - other = cast(Grid, other) + other = cast('Grid', other) if self.a_count != other.a_count: return self.a_count < other.a_count if self.b_count != other.b_count: @@ -357,7 +357,7 @@ class Arbitrary(Repetition): def __le__(self, other: Repetition) -> bool: if type(self) is not type(other): return repr(type(self)) < repr(type(other)) - other = cast(Arbitrary, other) + other = cast('Arbitrary', other) if self.displacements.size != other.displacements.size: return self.displacements.size < other.displacements.size diff --git a/masque/shapes/arc.py b/masque/shapes/arc.py index b3a9b7d..f3f4e1e 100644 --- a/masque/shapes/arc.py +++ b/masque/shapes/arc.py @@ -206,7 +206,7 @@ class Arc(Shape): if repr(type(self)) != repr(type(other)): return repr(type(self)) < repr(type(other)) return id(type(self)) < id(type(other)) - other = cast(Arc, other) + other = cast('Arc', other) if self.width != other.width: return self.width < other.width if not numpy.array_equal(self.radii, other.radii): @@ -233,7 +233,7 @@ class Arc(Shape): r0, r1 = self.radii # Convert from polar angle to ellipse parameter (for [rx*cos(t), ry*sin(t)] representation) - a_ranges = cast(_array2x2_t, self._angles_to_parameters()) + a_ranges = cast('_array2x2_t', self._angles_to_parameters()) # Approximate perimeter via numerical integration @@ -321,7 +321,7 @@ class Arc(Shape): If the extrema are innaccessible due to arc constraints, check the arc endpoints instead. """ - a_ranges = cast(_array2x2_t, self._angles_to_parameters()) + a_ranges = cast('_array2x2_t', self._angles_to_parameters()) mins = [] maxs = [] @@ -432,7 +432,7 @@ class Arc(Shape): [[x2, y2], [x3, y3]]], would create this arc from its corresponding ellipse. ``` """ - a_ranges = cast(_array2x2_t, self._angles_to_parameters()) + a_ranges = cast('_array2x2_t', self._angles_to_parameters()) mins = [] maxs = [] diff --git a/masque/shapes/circle.py b/masque/shapes/circle.py index 5f8ebe0..2d403b4 100644 --- a/masque/shapes/circle.py +++ b/masque/shapes/circle.py @@ -84,7 +84,7 @@ class Circle(Shape): if repr(type(self)) != repr(type(other)): return repr(type(self)) < repr(type(other)) return id(type(self)) < id(type(other)) - other = cast(Circle, other) + other = cast('Circle', other) if not self.radius == other.radius: return self.radius < other.radius if not numpy.array_equal(self.offset, other.offset): diff --git a/masque/shapes/ellipse.py b/masque/shapes/ellipse.py index 9c671d6..0d6a6c5 100644 --- a/masque/shapes/ellipse.py +++ b/masque/shapes/ellipse.py @@ -134,7 +134,7 @@ class Ellipse(Shape): if repr(type(self)) != repr(type(other)): return repr(type(self)) < repr(type(other)) return id(type(self)) < id(type(other)) - other = cast(Ellipse, other) + other = cast('Ellipse', other) if not numpy.array_equal(self.radii, other.radii): return tuple(self.radii) < tuple(other.radii) if not numpy.array_equal(self.offset, other.offset): diff --git a/masque/shapes/path.py b/masque/shapes/path.py index 717e59f..93e85ea 100644 --- a/masque/shapes/path.py +++ b/masque/shapes/path.py @@ -223,7 +223,7 @@ class Path(Shape): if repr(type(self)) != repr(type(other)): return repr(type(self)) < repr(type(other)) return id(type(self)) < id(type(other)) - other = cast(Path, other) + other = cast('Path', other) if self.width != other.width: return self.width < other.width if self.cap != other.cap: @@ -405,7 +405,7 @@ class Path(Shape): x_min = rotated_vertices[:, 0].argmin() if not is_scalar(x_min): y_min = rotated_vertices[x_min, 1].argmin() - x_min = cast(Sequence, x_min)[y_min] + x_min = cast('Sequence', x_min)[y_min] reordered_vertices = numpy.roll(rotated_vertices, -x_min, axis=0) width0 = self.width / norm_value diff --git a/masque/shapes/polygon.py b/masque/shapes/polygon.py index cbcbe63..10fd522 100644 --- a/masque/shapes/polygon.py +++ b/masque/shapes/polygon.py @@ -1,5 +1,4 @@ -from typing import Any, cast -from collections.abc import Sequence +from typing import Any, cast, TYPE_CHECKING import copy import functools @@ -13,6 +12,9 @@ from ..repetition import Repetition from ..utils import is_scalar, rotation_matrix_2d, annotations_lt, annotations_eq, rep2key from ..utils import remove_colinear_vertices, remove_duplicate_vertices, annotations_t +if TYPE_CHECKING: + from collections.abc import Sequence + @functools.total_ordering class Polygon(Shape): @@ -129,7 +131,7 @@ class Polygon(Shape): if repr(type(self)) != repr(type(other)): return repr(type(self)) < repr(type(other)) return id(type(self)) < id(type(other)) - other = cast(Polygon, other) + other = cast('Polygon', other) if not numpy.array_equal(self.vertices, other.vertices): min_len = min(self.vertices.shape[0], other.vertices.shape[0]) eq_mask = self.vertices[:min_len] != other.vertices[:min_len] @@ -395,7 +397,7 @@ class Polygon(Shape): x_min = rotated_vertices[:, 0].argmin() if not is_scalar(x_min): y_min = rotated_vertices[x_min, 1].argmin() - x_min = cast(Sequence, x_min)[y_min] + x_min = cast('Sequence', x_min)[y_min] reordered_vertices = numpy.roll(rotated_vertices, -x_min, axis=0) # TODO: normalize mirroring? diff --git a/masque/shapes/text.py b/masque/shapes/text.py index e936796..69318ac 100644 --- a/masque/shapes/text.py +++ b/masque/shapes/text.py @@ -115,7 +115,7 @@ class Text(RotatableImpl, Shape): if repr(type(self)) != repr(type(other)): return repr(type(self)) < repr(type(other)) return id(type(self)) < id(type(other)) - other = cast(Text, other) + other = cast('Text', other) if not self.height == other.height: return self.height < other.height if not self.string == other.string: diff --git a/masque/traits/rotatable.py b/masque/traits/rotatable.py index f873ce4..04816f1 100644 --- a/masque/traits/rotatable.py +++ b/masque/traits/rotatable.py @@ -1,14 +1,15 @@ -from typing import Self, cast, Any +from typing import Self, cast, Any, TYPE_CHECKING from abc import ABCMeta, abstractmethod import numpy from numpy import pi from numpy.typing import ArrayLike -from .positionable import Positionable from ..error import MasqueError from ..utils import rotation_matrix_2d +if TYPE_CHECKING: + from .positionable import Positionable _empty_slots = () # Workaround to get mypy to ignore intentionally empty slots for superclass @@ -113,9 +114,9 @@ class PivotableImpl(Pivotable, metaclass=ABCMeta): def rotate_around(self, pivot: ArrayLike, rotation: float) -> Self: pivot = numpy.asarray(pivot, dtype=float) - cast(Positionable, self).translate(-pivot) - cast(Rotatable, self).rotate(rotation) + cast('Positionable', self).translate(-pivot) + cast('Rotatable', self).rotate(rotation) self.offset = numpy.dot(rotation_matrix_2d(rotation), self.offset) # type: ignore # mypy#3004 - cast(Positionable, self).translate(+pivot) + cast('Positionable', self).translate(+pivot) return self