Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add abstract members. #803

Merged
merged 18 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 89 additions & 10 deletions Lib/fontParts/base/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pylint: disable=C0103, C0114
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import (
TYPE_CHECKING,
Any,
Expand Down Expand Up @@ -188,7 +189,7 @@ def interpolate(
# ------------


class BaseObject:
class BaseObject(Generic[BaseObjectType]):
r"""Provide common base functionality to objects.

This class is intended to serve as a foundation for other classes, supplying
Expand Down Expand Up @@ -994,7 +995,7 @@ def _clear(self) -> None:
del self[key]


class TransformationMixin:
class TransformationMixin(ABC):
"""Provide objects transformation-related functionality."""

# ---------------
Expand Down Expand Up @@ -1252,8 +1253,16 @@ def _skewBy(
t = transform.Identity.skew(x=x, y=y)
self.transformBy(tuple(t), origin=origin, **kwargs)

# ----------------
# Abstract members
# ----------------

class InterpolationMixin:
@abstractmethod
def raiseNotImplementedError(self):
pass


class InterpolationMixin(ABC):
"""Provide objects with interpolation-related functionality.

:cvar compatibilityReporterClass: A class used for reporting interpolation
Expand Down Expand Up @@ -1307,8 +1316,16 @@ def _isCompatible(self, other: Any, reporter: Any) -> None:
"""
self.raiseNotImplementedError()

# ----------------
# Abstract members
# ----------------

@abstractmethod
def raiseNotImplementedError(self):
pass

class SelectionMixin:

class SelectionMixin(ABC):
"""Provide objects with selection-related functionality."""

# -------------
Expand Down Expand Up @@ -1382,19 +1399,25 @@ def _set_selected(self, value: bool) -> None:
# Sub-Objects
# -----------
@classmethod
def _getSelectedSubObjects(cls, subObjects: CollectionType[Any]) -> Tuple[Any]:
def _getSelectedSubObjects(cls, subObjects: Any) -> Tuple[Any]:
selected = tuple(obj for obj in subObjects if obj.selected)
return selected

@classmethod
def _setSelectedSubObjects(
cls, subObjects: CollectionType[Any], selected: CollectionType[Any]
) -> None:
def _setSelectedSubObjects(cls, subObjects: Any, selected: Any) -> None:
for obj in subObjects:
obj.selected = obj in selected

# ----------------
# Abstract members
# ----------------

@abstractmethod
def raiseNotImplementedError(self):
pass


class PointPositionMixin:
class PointPositionMixin(ABC):
"""Provide objects with the ability to determine point position.

This class adds a `position` attribute as a :class:`dyanmicProperty`, for
Expand Down Expand Up @@ -1460,8 +1483,56 @@ def _set_position(self, value: PairCollectionType[IntFloatType]) -> None:
dY = y - pY
self.moveBy((dX, dY))

# ----------------
# Abstract members
# ----------------

x: dynamicProperty = dynamicProperty("base_x")

@abstractmethod
def _get_base_x(self) -> IntFloatType:
pass

@abstractmethod
def _set_base_x(self, value: IntFloatType) -> None:
pass

@abstractmethod
def _get_x(self) -> IntFloatType:
pass

@abstractmethod
def _set_x(self, value: IntFloatType) -> None:
pass

y: dynamicProperty = dynamicProperty("base_y")

@abstractmethod
def _get_base_y(self) -> IntFloatType:
pass

@abstractmethod
def _set_base_y(self, value: IntFloatType) -> None:
pass

@abstractmethod
def _get_y(self) -> IntFloatType:
pass

@abstractmethod
def _set_y(self, value: IntFloatType) -> None:
pass

@abstractmethod
def moveBy(self, value):
pass

@abstractmethod
def raiseNotImplementedError(self):
pass

class IdentifierMixin:

class IdentifierMixin(ABC):
"""Provide objects with a unique identifier."""

# identifier
Expand Down Expand Up @@ -1552,6 +1623,14 @@ def _setIdentifier(self, value: str) -> None:
"""
pass

# ----------------
# Abstract members
# ----------------

@abstractmethod
def raiseNotImplementedError(self):
pass


def reference(obj: Callable[[], Any]) -> Callable[[], Any]:
"""
Expand Down
15 changes: 13 additions & 2 deletions Lib/fontParts/base/contour.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
from __future__ import annotations
from typing import TYPE_CHECKING, cast, Any, Iterator, List, Optional, Tuple, Union
from typing import (
TYPE_CHECKING,
cast,
Any,
Iterator,
List,
Optional,
Tuple,
TypeVar,
Union,
)

from fontParts.base.errors import FontPartsError
from fontParts.base.base import (
Expand Down Expand Up @@ -32,6 +42,7 @@
from fontParts.base.layer import BaseLayer
from fontParts.base.font import BaseFont

BaseContourType = TypeVar("BaseContourType", bound="BaseContour")
PointCollectionType = CollectionType[PairCollectionType[IntFloatType]]


Expand Down Expand Up @@ -65,7 +76,7 @@ def _reprContents(self) -> List[str]:
contents += self.glyph._reprContents()
return contents

def copyData(self, source: BaseContour) -> None:
def copyData(self, source: BaseContourType) -> None:
"""Copy data from another contour instance.

This will copy the contents of the following attributes from `source`
Expand Down
30 changes: 15 additions & 15 deletions Lib/fontParts/base/font.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def _get_base_path(self) -> Optional[str]:
path = normalizers.normalizeFilePath(path)
return path

def _get_path(self, **kwargs: Any) -> Optional[str]:
def _get_path(self, **kwargs: Any) -> Optional[str]: # type: ignore[return]
r"""Get the path to the native font file.

This method is the environment implementation
Expand Down Expand Up @@ -574,7 +574,7 @@ def _get_base_info(self) -> BaseInfo:
info.font = self
return info

def _get_info(self) -> BaseInfo:
def _get_info(self) -> BaseInfo: # type: ignore[return]
"""Get the native font's info object.

This is the environment implementation of :attr:`BaseFont.info`.
Expand Down Expand Up @@ -613,7 +613,7 @@ def _get_base_groups(self) -> BaseGroups:
groups.font = self
return groups

def _get_groups(self) -> BaseGroups:
def _get_groups(self) -> BaseGroups: # type: ignore[return]
"""Get the native font's groups object.

This is the environment implementation
Expand Down Expand Up @@ -653,7 +653,7 @@ def _get_base_kerning(self) -> BaseKerning:
kerning.font = self
return kerning

def _get_kerning(self) -> BaseKerning:
def _get_kerning(self) -> BaseKerning: # type: ignore[return]
"""Get the native font's kerning object.

This is the environment implementation
Expand Down Expand Up @@ -752,7 +752,7 @@ def _get_base_features(self) -> BaseFeatures:
features.font = self
return features

def _get_features(self) -> BaseFeatures:
def _get_features(self) -> BaseFeatures: # type: ignore[return]
"""Get the native font's features object.

This is the environment implementation of
Expand Down Expand Up @@ -792,7 +792,7 @@ def _get_base_lib(self) -> BaseLib:
lib.font = self
return lib

def _get_lib(self) -> BaseLib:
def _get_lib(self) -> BaseLib: # type: ignore[return]
"""Get the native font's lib object.

This is the environment implementation of :attr:`BaseFont.lib`.
Expand Down Expand Up @@ -837,7 +837,7 @@ def _get_base_tempLib(self) -> BaseLib:
lib.font = self
return lib

def _get_tempLib(self) -> BaseLib:
def _get_tempLib(self) -> BaseLib: # type: ignore[return]
"""Get the native font's temporary lib object.

This is the environment implementation
Expand Down Expand Up @@ -883,7 +883,7 @@ def _get_base_layers(self) -> Tuple[BaseLayer, ...]:
self._setFontInLayer(layer)
return tuple(layers)

def _get_layers(self, **kwargs: Any) -> Tuple[BaseLayer, ...]:
def _get_layers(self, **kwargs: Any) -> Tuple[BaseLayer, ...]: # type: ignore[return]
r"""Get the native font's layer objects.

This is the environment implementation of
Expand Down Expand Up @@ -932,7 +932,7 @@ def _set_base_layerOrder(self, value: CollectionType[str]) -> None:
value = normalizers.normalizeLayerOrder(value, self)
self._set_layerOrder(value)

def _get_layerOrder(self, **kwargs: Any) -> Tuple[str, ...]:
def _get_layerOrder(self, **kwargs: Any) -> Tuple[str, ...]: # type: ignore[return]
r"""Get the order of the layers in the native font.

This is the environment implementation of the
Expand Down Expand Up @@ -1006,7 +1006,7 @@ def _set_base_defaultLayerName(self, value: str) -> None:
value = normalizers.normalizeDefaultLayerName(value, self)
self._set_defaultLayerName(value)

def _get_defaultLayerName(self) -> str:
def _get_defaultLayerName(self) -> str: # type: ignore[return]
"""Get the name of the native font's default layer.

This is the environment implementation of
Expand Down Expand Up @@ -1181,7 +1181,7 @@ def newLayer(
self._setFontInLayer(layer)
return layer

def _newLayer(
def _newLayer( # type: ignore[return]
self,
name: str,
color: Optional[QuadrupleCollectionType[IntFloatType]],
Expand Down Expand Up @@ -1577,7 +1577,7 @@ def _set_base_glyphOrder(self, value: CollectionType[str]) -> None:
value = normalizers.normalizeGlyphOrder(value)
self._set_glyphOrder(value)

def _get_glyphOrder(self) -> Tuple[str, ...]:
def _get_glyphOrder(self) -> Tuple[str, ...]: # type: ignore[return]
r"""Get the order of the glyphs in the native font.

This is the environment implementation of the
Expand Down Expand Up @@ -1732,7 +1732,7 @@ def _get_guidelines(self) -> Tuple[BaseGuideline, ...]:
def _len__guidelines(self) -> int:
return self._lenGuidelines()

def _lenGuidelines(self, **kwargs: Any) -> int:
def _lenGuidelines(self, **kwargs: Any) -> int: # type: ignore[return]
r"""Return the number of font-level guidelines in the native font.

:param \**kwargs: Additional keyword arguments.
Expand All @@ -1754,7 +1754,7 @@ def _getitem__guidelines(self, index: int) -> BaseGuideline:
self._setFontInGuideline(guideline)
return guideline

def _getGuideline(self, index: int, **kwargs: Any) -> BaseGuideline:
def _getGuideline(self, index: int, **kwargs: Any) -> BaseGuideline: # type: ignore[return]
r"""Return the guideline at the given index.

:param index: The index of the guideline.
Expand Down Expand Up @@ -1846,7 +1846,7 @@ def appendGuideline(
newGuideline.font = self
return newGuideline

def _appendGuideline(
def _appendGuideline( # type: ignore[return]
self,
position: Optional[PairCollectionType[IntFloatType]],
angle: Optional[float],
Expand Down
2 changes: 0 additions & 2 deletions Lib/fontParts/base/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from fontParts.base.base import (
BaseObject,
TransformationMixin,
PointPositionMixin,
SelectionMixin,
dynamicProperty,
reference,
Expand All @@ -15,7 +14,6 @@
class BaseImage(
BaseObject,
TransformationMixin,
PointPositionMixin,
SelectionMixin,
DeprecatedImage,
RemovedImage,
Expand Down
Loading
Loading