From a0202f571c3ff73c44f6346ce0b382ad59d0fd23 Mon Sep 17 00:00:00 2001 From: Roberto Arista Date: Tue, 24 Sep 2024 16:55:52 +0200 Subject: [PATCH 1/5] ignore virtual environment --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c1b881ff..e9e36ace 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ build/* dist/* .eggs/ .vscode +.venv documentation/build/* documentation/.sass-cache/* From fa29d20c40b7a9c4a6e6f045b57e1b90baac7ea9 Mon Sep 17 00:00:00 2001 From: Roberto Arista Date: Fri, 27 Sep 2024 10:36:09 +0200 Subject: [PATCH 2/5] Add annotations --- Lib/fontParts/base/annotations.py | 39 +++++++++++ Lib/fontParts/base/bPoint.py | 110 ++++++++++++++++-------------- 2 files changed, 98 insertions(+), 51 deletions(-) create mode 100644 Lib/fontParts/base/annotations.py diff --git a/Lib/fontParts/base/annotations.py b/Lib/fontParts/base/annotations.py new file mode 100644 index 00000000..0ed3b214 --- /dev/null +++ b/Lib/fontParts/base/annotations.py @@ -0,0 +1,39 @@ +# pylint: disable=C0103, C0114 + +from __future__ import annotations + +from typing import Dict, List, Tuple, TypeVar, Union + +from fontTools.pens.basePen import AbstractPen +from fontTools.pens.pointPen import AbstractPointPen + +# ------------ +# Type Aliases +# ------------ + +# Builtins + +T = TypeVar('T') +CollectionType = Union[List[T], Tuple[T, ...]] +IntFloatType = Union[int, float] + +# FontTools + +PenType = AbstractPen +PointPenType = AbstractPointPen + +# FontParts + +BoundsType = Tuple[IntFloatType, IntFloatType, IntFloatType, IntFloatType] +CharacterMappingType = Dict[int, Tuple[str, ...]] +ColorType = Tuple[IntFloatType, IntFloatType, IntFloatType, IntFloatType] +CoordinateType = Tuple[IntFloatType, IntFloatType] +FactorType = Union[IntFloatType, Tuple[float, float]] +KerningKeyType = Tuple[str, str] +KerningDictType = Dict[KerningKeyType, IntFloatType] +ReverseComponentMappingType = Dict[str, Tuple[str, ...]] +ScaleType = Tuple[IntFloatType, IntFloatType] +TransformationMatrixType = Tuple[ + IntFloatType, IntFloatType, IntFloatType, + IntFloatType, IntFloatType, IntFloatType +] diff --git a/Lib/fontParts/base/bPoint.py b/Lib/fontParts/base/bPoint.py index 2bb10005..aaa64216 100644 --- a/Lib/fontParts/base/bPoint.py +++ b/Lib/fontParts/base/bPoint.py @@ -1,16 +1,24 @@ -from fontTools.misc import transform -from fontParts.base.base import ( - BaseObject, - TransformationMixin, - SelectionMixin, - IdentifierMixin, - dynamicProperty, - reference -) -from fontParts.base.errors import FontPartsError +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, List, Optional, Tuple + from fontParts.base import normalizers +from fontParts.base.base import (BaseObject, IdentifierMixin, SelectionMixin, + TransformationMixin, dynamicProperty, + reference) from fontParts.base.deprecated import DeprecatedBPoint, RemovedBPoint +from fontParts.base.errors import FontPartsError +from fontTools.misc import transform +if TYPE_CHECKING: + from fontParts.base.annotations import (CoordinateType, IntFloatType, + TransformationMatrixType) + from fontParts.base.contour import BaseContour + from fontParts.base.font import BaseFont + from fontParts.base.glyph import BaseGlyph + from fontParts.base.layer import BaseLayer + from fontParts.base.point import BasePoint + from fontParts.base.segment import BaseSegment class BaseBPoint( BaseObject, @@ -21,14 +29,14 @@ class BaseBPoint( RemovedBPoint ): - def _reprContents(self): + def _reprContents(self) -> List[str]: contents = [ "%s" % self.type, "anchor='({x}, {y})'".format(x=self.anchor[0], y=self.anchor[1]), ] return contents - def _setPoint(self, point): + def _setPoint(self, point: BasePoint) -> None: if hasattr(self, "_point"): raise AssertionError("point for bPoint already set") self._point = point @@ -63,17 +71,18 @@ def _getIdentifier(self): # Segment - _segment = dynamicProperty("base_segment") + _segment: dynamicProperty = dynamicProperty("base_segment") - def _get_base_segment(self): + def _get_base_segment(self) -> Optional[BaseSegment]: point = self._point for segment in self.contour.segments: if segment.onCurve == point: return segment + return None - _nextSegment = dynamicProperty("base_nextSegment") + _nextSegment: dynamicProperty = dynamicProperty("base_nextSegment") - def _get_base_nextSegment(self): + def _get_base_nextSegment(self) -> Optional[BaseSegment]: contour = self.contour if contour is None: return None @@ -87,16 +96,16 @@ def _get_base_nextSegment(self): # Contour - _contour = None + _contour: Optional[BaseContour] = None contour = dynamicProperty("contour", "The bPoint's parent contour.") - def _get_contour(self): + def _get_contour(self) -> Optional[BaseContour]: if self._contour is None: return None return self._contour() - def _set_contour(self, contour): + def _set_contour(self, contour: BaseContour) -> None: if self._contour is not None: raise AssertionError("contour for bPoint already set") if contour is not None: @@ -105,27 +114,27 @@ def _set_contour(self, contour): # Glyph - glyph = dynamicProperty("glyph", "The bPoint's parent glyph.") + glyph: dynamicProperty = dynamicProperty("glyph", "The bPoint's parent glyph.") - def _get_glyph(self): + def _get_glyph(self) -> Optional[BaseGlyph]: if self._contour is None: return None return self.contour.glyph # Layer - layer = dynamicProperty("layer", "The bPoint's parent layer.") + layer: dynamicProperty = dynamicProperty("layer", "The bPoint's parent layer.") - def _get_layer(self): + def _get_layer(self) -> Optional[BaseLayer]: if self._contour is None: return None return self.glyph.layer # Font - font = dynamicProperty("font", "The bPoint's parent font.") + font: dynamicProperty = dynamicProperty("font", "The bPoint's parent font.") - def _get_font(self): + def _get_font(self) -> Optional[BaseFont]: if self._contour is None: return None return self.glyph.font @@ -136,7 +145,7 @@ def _get_font(self): # anchor - anchor = dynamicProperty("base_anchor", "The anchor point.") + anchor: dynamicProperty = dynamicProperty("base_anchor", "The anchor point.") def _get_base_anchor(self): value = self._get_anchor() @@ -166,18 +175,18 @@ def _set_anchor(self, value): # bcp in - bcpIn = dynamicProperty("base_bcpIn", "The incoming off curve.") + bcpIn: dynamicProperty = dynamicProperty("base_bcpIn", "The incoming off curve.") - def _get_base_bcpIn(self): + def _get_base_bcpIn(self) -> CoordinateType: value = self._get_bcpIn() value = normalizers.normalizeCoordinateTuple(value) return value - def _set_base_bcpIn(self, value): + def _set_base_bcpIn(self, value: CoordinateType) -> None: value = normalizers.normalizeCoordinateTuple(value) self._set_bcpIn(value) - def _get_bcpIn(self): + def _get_bcpIn(self) -> CoordinateType: """ Subclasses may override this method. """ @@ -190,7 +199,7 @@ def _get_bcpIn(self): x = y = 0 return (x, y) - def _set_bcpIn(self, value): + def _set_bcpIn(self, value: CoordinateType) -> None: """ Subclasses may override this method. """ @@ -219,18 +228,18 @@ def _set_bcpIn(self, value): # bcp out - bcpOut = dynamicProperty("base_bcpOut", "The outgoing off curve.") + bcpOut: dynamicProperty = dynamicProperty("base_bcpOut", "The outgoing off curve.") - def _get_base_bcpOut(self): + def _get_base_bcpOut(self) -> CoordinateType: value = self._get_bcpOut() value = normalizers.normalizeCoordinateTuple(value) return value - def _set_base_bcpOut(self, value): + def _set_base_bcpOut(self, value: CoordinateType) -> None: value = normalizers.normalizeCoordinateTuple(value) self._set_bcpOut(value) - def _get_bcpOut(self): + def _get_bcpOut(self) -> CoordinateType: """ Subclasses may override this method. """ @@ -243,7 +252,7 @@ def _get_bcpOut(self): x = y = 0 return (x, y) - def _set_bcpOut(self, value): + def _set_bcpOut(self, value: CoordinateType) -> None: """ Subclasses may override this method. """ @@ -273,18 +282,18 @@ def _set_bcpOut(self, value): # type - type = dynamicProperty("base_type", "The bPoint type.") + type: dynamicProperty = dynamicProperty("base_type", "The bPoint type.") - def _get_base_type(self): + def _get_base_type(self) -> Optional[str]: value = self._get_type() value = normalizers.normalizeBPointType(value) return value - def _set_base_type(self, value): + def _set_base_type(self, value: str) -> None: value = normalizers.normalizeBPointType(value) self._set_type(value) - def _get_type(self): + def _get_type(self) -> Optional[str]: """ Subclasses may override this method. """ @@ -308,7 +317,7 @@ def _get_type(self): % typ) return bType - def _set_type(self, value): + def _set_type(self, value: str) -> None: """ Subclasses may override this method. """ @@ -331,20 +340,20 @@ def _set_type(self, value): # Identification # -------------- - index = dynamicProperty("index", + index: dynamicProperty = dynamicProperty("index", ("The index of the bPoint within the ordered " "list of the parent contour's bPoints. None " "if the bPoint does not belong to a contour.") ) - def _get_base_index(self): + def _get_base_index(self) -> Optional[int]: if self.contour is None: return None value = self._get_index() value = normalizers.normalizeIndex(value) return value - def _get_index(self): + def _get_index(self) -> Optional[int]: """ Subclasses may override this method. """ @@ -355,8 +364,7 @@ def _get_index(self): # -------------- # Transformation # -------------- - - def _transformBy(self, matrix, **kwargs): + def _transformBy(self, matrix: TransformationMatrixType, **kwargs: Any) -> None: """ Subclasses may override this method. """ @@ -376,7 +384,7 @@ def _transformBy(self, matrix, **kwargs): # Misc # ---- - def round(self): + def round(self) -> None: """ Round coordinates. """ @@ -391,21 +399,21 @@ def round(self): normalizers.normalizeVisualRounding(y)) -def relativeBCPIn(anchor, BCPIn): +def relativeBCPIn(anchor: CoordinateType, BCPIn: CoordinateType) -> CoordinateType: """convert absolute incoming bcp value to a relative value""" return (BCPIn[0] - anchor[0], BCPIn[1] - anchor[1]) -def absoluteBCPIn(anchor, BCPIn): +def absoluteBCPIn(anchor: CoordinateType, BCPIn: CoordinateType) -> CoordinateType: """convert relative incoming bcp value to an absolute value""" return (BCPIn[0] + anchor[0], BCPIn[1] + anchor[1]) -def relativeBCPOut(anchor, BCPOut): +def relativeBCPOut(anchor: CoordinateType, BCPOut: CoordinateType) -> CoordinateType: """convert absolute outgoing bcp value to a relative value""" return (BCPOut[0] - anchor[0], BCPOut[1] - anchor[1]) -def absoluteBCPOut(anchor, BCPOut): +def absoluteBCPOut(anchor: CoordinateType, BCPOut: CoordinateType) -> CoordinateType: """convert relative outgoing bcp value to an absolute value""" return (BCPOut[0] + anchor[0], BCPOut[1] + anchor[1]) From c10f1d6b5375d66f48e620c29c4818d3b36e14e6 Mon Sep 17 00:00:00 2001 From: Roberto Arista Date: Fri, 27 Sep 2024 11:05:18 +0200 Subject: [PATCH 3/5] Add annotations for identifier --- Lib/fontParts/base/bPoint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/fontParts/base/bPoint.py b/Lib/fontParts/base/bPoint.py index aaa64216..35e001d5 100644 --- a/Lib/fontParts/base/bPoint.py +++ b/Lib/fontParts/base/bPoint.py @@ -57,13 +57,13 @@ def __eq__(self, other): # identifier - def _get_identifier(self): + def _get_identifier(self) -> Optional[str]: """ Subclasses may override this method. """ return self._point.identifier - def _getIdentifier(self): + def _getIdentifier(self) -> Optional[str]: """ Subclasses may override this method. """ From e8e4e0ae575d648cc43625dddf7bedcfd4b9b522 Mon Sep 17 00:00:00 2001 From: Roberto Arista Date: Thu, 3 Oct 2024 09:23:52 +0200 Subject: [PATCH 4/5] Improve import style --- Lib/fontParts/base/bPoint.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Lib/fontParts/base/bPoint.py b/Lib/fontParts/base/bPoint.py index 35e001d5..44f6a676 100644 --- a/Lib/fontParts/base/bPoint.py +++ b/Lib/fontParts/base/bPoint.py @@ -1,18 +1,25 @@ from __future__ import annotations from typing import TYPE_CHECKING, Any, List, Optional, Tuple - +from fontTools.misc import transform +from fontParts.base.base import ( + BaseObject, + TransformationMixin, + SelectionMixin, + IdentifierMixin, + dynamicProperty, + reference +) +from fontParts.base.errors import FontPartsError from fontParts.base import normalizers -from fontParts.base.base import (BaseObject, IdentifierMixin, SelectionMixin, - TransformationMixin, dynamicProperty, - reference) from fontParts.base.deprecated import DeprecatedBPoint, RemovedBPoint -from fontParts.base.errors import FontPartsError -from fontTools.misc import transform if TYPE_CHECKING: - from fontParts.base.annotations import (CoordinateType, IntFloatType, - TransformationMatrixType) + from fontParts.base.annotations import ( + CoordinateType, + IntFloatType, + TransformationMatrixType + ) from fontParts.base.contour import BaseContour from fontParts.base.font import BaseFont from fontParts.base.glyph import BaseGlyph From b8586eca0faad4ba0863597a341e042400e7106b Mon Sep 17 00:00:00 2001 From: Roberto Arista Date: Thu, 3 Oct 2024 09:25:48 +0200 Subject: [PATCH 5/5] Remove `Optional` --- Lib/fontParts/base/bPoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/fontParts/base/bPoint.py b/Lib/fontParts/base/bPoint.py index 44f6a676..ee2bf1e5 100644 --- a/Lib/fontParts/base/bPoint.py +++ b/Lib/fontParts/base/bPoint.py @@ -64,7 +64,7 @@ def __eq__(self, other): # identifier - def _get_identifier(self) -> Optional[str]: + def _get_identifier(self) -> str: """ Subclasses may override this method. """