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 type annotations, conform to protocols #136

Merged
merged 16 commits into from
Dec 13, 2023
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
8 changes: 8 additions & 0 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,28 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install . --no-deps
python -m pip install -r requirements.txt
python -m pip install -r requirements-dev.txt

- name: Run pre-commit
uses: pre-commit/action@v3.0.0
with:
extra_args: --all-files --verbose --show-diff-on-failure

- name: Test with pytest
run: |
pytest -vv

- name: Run mypy
run: |
mypy src/ tests/
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,19 @@ testpaths = [
"tests",
]
asyncio_mode = "auto"

[[tool.mypy.overrides]]
module = "fontTools.*"
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "glyphsLib.glyphdata"
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "urllib3"
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "requests"
ignore_missing_imports = true
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mypy==1.7.1
pre-commit==3.5.0
pytest==7.4.3
pytest-asyncio==0.23.2
Expand Down
5 changes: 0 additions & 5 deletions setup.py

This file was deleted.

48 changes: 31 additions & 17 deletions src/fontra_rcjk/backend_fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@
import pathlib
import shutil
from functools import cached_property
from os import PathLike
from typing import Any

import watchfiles
from fontra.backends.designspace import cleanupWatchFilesChanges
from fontra.backends.ufo_utils import extractGlyphNameAndUnicodes
from fontra.core.classes import unstructure
from fontra.core.classes import (
GlobalAxis,
GlobalDiscreteAxis,
VariableGlyph,
unstructure,
)
from fontra.core.instancer import mapLocationFromUserToSource
from fontra.core.protocols import WritableFontBackend
from fontTools.ufoLib.filenames import userNameToFileName

from .base import (
Expand All @@ -33,14 +41,14 @@

class RCJKBackend:
@classmethod
def fromPath(cls, path):
def fromPath(cls, path: PathLike) -> WritableFontBackend:
return cls(path)

@classmethod
def createFromPath(cls, path):
def createFromPath(cls, path: PathLike) -> WritableFontBackend:
return cls(path, create=True)

def __init__(self, path, *, create=False):
def __init__(self, path: PathLike, *, create: bool = False):
self.path = pathlib.Path(path).resolve()
if create:
if self.path.is_dir():
Expand All @@ -49,9 +57,7 @@ def __init__(self, path, *, create=False):
self.path.unlink()
cgPath = self.path / "characterGlyph"
cgPath.mkdir(exist_ok=True, parents=True)
self.characterGlyphGlyphSet = (
RCJKGlyphSet(cgPath, self.registerWrittenPath),
)
self.characterGlyphGlyphSet = RCJKGlyphSet(cgPath, self.registerWrittenPath)

for name in glyphSetNames:
setattr(
Expand All @@ -69,7 +75,7 @@ def __init__(self, path, *, create=False):
else:
self.designspace = {}

self._glyphMap = {}
self._glyphMap: dict[str, list[int]] = {}
for gs, hasEncoding in self._iterGlyphSets():
glyphMap = gs.getGlyphMap(not hasEncoding)
for glyphName, unicodes in glyphMap.items():
Expand All @@ -78,7 +84,7 @@ def __init__(self, path, *, create=False):
assert not unicodes
self._glyphMap[glyphName] = unicodes

self._recentlyWrittenPaths = {}
self._recentlyWrittenPaths: dict[str, Any] = {}
self._tempGlyphCache = TimedCache()

def close(self):
Expand Down Expand Up @@ -111,13 +117,16 @@ def _defaultLocation(self):
}
return mapLocationFromUserToSource(userLoc, axes)

async def getGlyphMap(self):
async def getGlyphMap(self) -> dict[str, list[int]]:
return dict(self._glyphMap)

async def getGlobalAxes(self):
async def putGlyphMap(self, glyphMap: dict[str, list[int]]) -> None:
pass

async def getGlobalAxes(self) -> list[GlobalAxis | GlobalDiscreteAxis]:
return unpackAxes(self.designspace.get("axes", ()))

async def putGlobalAxes(self, axes):
async def putGlobalAxes(self, axes: list[GlobalAxis | GlobalDiscreteAxis]) -> None:
self.designspace["axes"] = unstructure(axes)
if hasattr(self, "_defaultLocation"):
del self._defaultLocation
Expand All @@ -129,10 +138,13 @@ def _writeDesignSpaceFile(self):
json.dumps(self.designspace, indent=2), encoding="utf-8"
)

async def getUnitsPerEm(self):
async def getUnitsPerEm(self) -> int:
return 1000

async def getGlyph(self, glyphName):
async def putUnitsPerEm(self, value: int) -> None:
pass

async def getGlyph(self, glyphName: str) -> VariableGlyph | None:
layerGlyphs = self._getLayerGlyphs(glyphName)
return buildVariableGlyphFromLayerGlyphs(layerGlyphs)

Expand Down Expand Up @@ -168,7 +180,9 @@ def _getLayerGLIFData(self, glyphName):
return gs.getGlyphLayerData(glyphName)
return None

async def putGlyph(self, glyphName, glyph, unicodes):
async def putGlyph(
self, glyphName: str, glyph: VariableGlyph, unicodes: list[int]
) -> None:
if glyphName not in self._glyphMap:
existingLayerGlyphs = {}
else:
Expand All @@ -194,14 +208,14 @@ async def deleteGlyph(self, glyphName):

del self._glyphMap[glyphName]

async def getCustomData(self):
async def getCustomData(self) -> dict[str, Any]:
customData = {}
customDataPath = self.path / FONTLIB_FILENAME
if customDataPath.is_file():
customData = json.loads(customDataPath.read_text(encoding="utf-8"))
return customData | standardCustomDataItems

async def putCustomData(self, customData):
async def putCustomData(self, customData: dict[str, Any]) -> None:
customDataPath = self.path / FONTLIB_FILENAME
customData = {
k: v
Expand Down
Loading
Loading