Check for descriptor types with hasattr() to allow custom classes that don't inherit the default descriptors
This commit is contained in:
parent
42e4d66184
commit
ec4bcf54c9
@ -8,7 +8,7 @@ import os
|
||||
import posixpath
|
||||
from io import BytesIO, StringIO
|
||||
from textwrap import indent
|
||||
from typing import Any, Dict, List, MutableMapping, Optional, Tuple, Union
|
||||
from typing import Any, Dict, List, MutableMapping, Optional, Tuple, Union, cast
|
||||
|
||||
from fontTools.misc import etree as ET
|
||||
from fontTools.misc import plistlib
|
||||
@ -1352,7 +1352,7 @@ class BaseDocWriter(object):
|
||||
minVersion = self.documentObject.formatTuple
|
||||
if (
|
||||
any(
|
||||
isinstance(axis, DiscreteAxisDescriptor) or
|
||||
hasattr(axis, 'values') or
|
||||
axis.axisOrdering is not None or
|
||||
axis.axisLabels
|
||||
for axis in self.documentObject.axes
|
||||
@ -1445,10 +1445,10 @@ class BaseDocWriter(object):
|
||||
for label in axisObject.axisLabels:
|
||||
self._addAxisLabel(labelsElement, label)
|
||||
axisElement.append(labelsElement)
|
||||
if isinstance(axisObject, AxisDescriptor):
|
||||
if hasattr(axisObject, "minimum"):
|
||||
axisElement.attrib['minimum'] = self.intOrFloat(axisObject.minimum)
|
||||
axisElement.attrib['maximum'] = self.intOrFloat(axisObject.maximum)
|
||||
elif isinstance(axisObject, DiscreteAxisDescriptor):
|
||||
elif hasattr(axisObject, "values"):
|
||||
axisElement.attrib['values'] = " ".join(self.intOrFloat(v) for v in axisObject.values)
|
||||
axisElement.attrib['default'] = self.intOrFloat(axisObject.default)
|
||||
if axisObject.hidden:
|
||||
@ -1682,14 +1682,19 @@ class BaseDocWriter(object):
|
||||
for subset in vf.axisSubsets:
|
||||
subsetElement = ET.Element('axis-subset')
|
||||
subsetElement.attrib['name'] = subset.name
|
||||
if isinstance(subset, RangeAxisSubsetDescriptor):
|
||||
# Mypy doesn't support narrowing union types via hasattr()
|
||||
# https://mypy.readthedocs.io/en/stable/type_narrowing.html
|
||||
# TODO(Python 3.10): use TypeGuard
|
||||
if hasattr(subset, "userMinimum"):
|
||||
subset = cast(RangeAxisSubsetDescriptor, subset)
|
||||
if subset.userMinimum != -math.inf:
|
||||
subsetElement.attrib['userminimum'] = self.intOrFloat(subset.userMinimum)
|
||||
if subset.userMaximum != math.inf:
|
||||
subsetElement.attrib['usermaximum'] = self.intOrFloat(subset.userMaximum)
|
||||
if subset.userDefault is not None:
|
||||
subsetElement.attrib['userdefault'] = self.intOrFloat(subset.userDefault)
|
||||
elif isinstance(subset, ValueAxisSubsetDescriptor):
|
||||
elif hasattr(subset, "userValue"):
|
||||
subset = cast(ValueAxisSubsetDescriptor, subset)
|
||||
subsetElement.attrib['uservalue'] = self.intOrFloat(subset.userValue)
|
||||
subsetsElement.append(subsetElement)
|
||||
vfElement.append(subsetsElement)
|
||||
@ -2904,8 +2909,12 @@ class DesignSpaceDocument(LogMixin, AsDictMixin):
|
||||
discreteAxes = []
|
||||
rangeAxisSubsets: List[Union[RangeAxisSubsetDescriptor, ValueAxisSubsetDescriptor]] = []
|
||||
for axis in self.axes:
|
||||
if isinstance(axis, DiscreteAxisDescriptor):
|
||||
discreteAxes.append(axis)
|
||||
if hasattr(axis, "values"):
|
||||
# Mypy doesn't support narrowing union types via hasattr()
|
||||
# TODO(Python 3.10): use TypeGuard
|
||||
# https://mypy.readthedocs.io/en/stable/type_narrowing.html
|
||||
axis = cast(DiscreteAxisDescriptor, axis)
|
||||
discreteAxes.append(axis) # type: ignore
|
||||
else:
|
||||
rangeAxisSubsets.append(RangeAxisSubsetDescriptor(name=axis.name))
|
||||
valueCombinations = itertools.product(*[axis.values for axis in discreteAxes])
|
||||
|
@ -7,7 +7,7 @@ from __future__ import annotations
|
||||
import itertools
|
||||
import logging
|
||||
import math
|
||||
from typing import Any, Callable, Dict, Iterator, List, Tuple
|
||||
from typing import Any, Callable, Dict, Iterator, List, Tuple, cast
|
||||
|
||||
from fontTools.designspaceLib import (
|
||||
AxisDescriptor,
|
||||
@ -21,9 +21,9 @@ from fontTools.designspaceLib import (
|
||||
)
|
||||
from fontTools.designspaceLib.statNames import StatNames, getStatNames
|
||||
from fontTools.designspaceLib.types import (
|
||||
ConditionSet,
|
||||
Range,
|
||||
Region,
|
||||
ConditionSet,
|
||||
getVFUserRegion,
|
||||
locationInRegion,
|
||||
regionInRegion,
|
||||
@ -87,11 +87,18 @@ def splitInterpolable(
|
||||
discreteAxes = []
|
||||
interpolableUserRegion: Region = {}
|
||||
for axis in doc.axes:
|
||||
if isinstance(axis, DiscreteAxisDescriptor):
|
||||
if hasattr(axis, "values"):
|
||||
# Mypy doesn't support narrowing union types via hasattr()
|
||||
# TODO(Python 3.10): use TypeGuard
|
||||
# https://mypy.readthedocs.io/en/stable/type_narrowing.html
|
||||
axis = cast(DiscreteAxisDescriptor, axis)
|
||||
discreteAxes.append(axis)
|
||||
else:
|
||||
axis = cast(AxisDescriptor, axis)
|
||||
interpolableUserRegion[axis.name] = Range(
|
||||
axis.minimum, axis.maximum, axis.default
|
||||
axis.minimum,
|
||||
axis.maximum,
|
||||
axis.default,
|
||||
)
|
||||
valueCombinations = itertools.product(*[axis.values for axis in discreteAxes])
|
||||
for values in valueCombinations:
|
||||
@ -191,7 +198,11 @@ def _extractSubSpace(
|
||||
|
||||
for axis in doc.axes:
|
||||
range = userRegion[axis.name]
|
||||
if isinstance(range, Range) and isinstance(axis, AxisDescriptor):
|
||||
if isinstance(range, Range) and hasattr(axis, "minimum"):
|
||||
# Mypy doesn't support narrowing union types via hasattr()
|
||||
# TODO(Python 3.10): use TypeGuard
|
||||
# https://mypy.readthedocs.io/en/stable/type_narrowing.html
|
||||
axis = cast(AxisDescriptor, axis)
|
||||
subDoc.addAxis(
|
||||
AxisDescriptor(
|
||||
# Same info
|
||||
|
@ -1,14 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Optional, Union
|
||||
from typing import Dict, List, Optional, Union, cast
|
||||
|
||||
from fontTools.designspaceLib import (
|
||||
AxisDescriptor,
|
||||
DesignSpaceDocument,
|
||||
DesignSpaceDocumentError,
|
||||
DiscreteAxisDescriptor,
|
||||
RangeAxisSubsetDescriptor,
|
||||
SimpleLocationDict,
|
||||
ValueAxisSubsetDescriptor,
|
||||
VariableFontDescriptor,
|
||||
)
|
||||
|
||||
@ -117,18 +118,24 @@ def getVFUserRegion(doc: DesignSpaceDocument, vf: VariableFontDescriptor) -> Reg
|
||||
raise DesignSpaceDocumentError(
|
||||
f"Cannot find axis named '{axisSubset.name}' for variable font '{vf.name}'."
|
||||
)
|
||||
if isinstance(axisSubset, RangeAxisSubsetDescriptor):
|
||||
if isinstance(axis, DiscreteAxisDescriptor):
|
||||
if hasattr(axisSubset, "userMinimum"):
|
||||
# Mypy doesn't support narrowing union types via hasattr()
|
||||
# TODO(Python 3.10): use TypeGuard
|
||||
# https://mypy.readthedocs.io/en/stable/type_narrowing.html
|
||||
axisSubset = cast(RangeAxisSubsetDescriptor, axisSubset)
|
||||
if not hasattr(axis, "minimum"):
|
||||
raise DesignSpaceDocumentError(
|
||||
f"Cannot select a range over '{axis.name}' for variable font '{vf.name}' "
|
||||
"because it's a discrete axis, use only 'userValue' instead."
|
||||
)
|
||||
axis = cast(AxisDescriptor, axis)
|
||||
vfUserRegion[axis.name] = Range(
|
||||
max(axisSubset.userMinimum, axis.minimum),
|
||||
min(axisSubset.userMaximum, axis.maximum),
|
||||
axisSubset.userDefault or axis.default,
|
||||
)
|
||||
else:
|
||||
axisSubset = cast(ValueAxisSubsetDescriptor, axisSubset)
|
||||
vfUserRegion[axis.name] = axisSubset.userValue
|
||||
# Any axis not mentioned explicitly has a single location = default value
|
||||
for axis in doc.axes:
|
||||
|
Loading…
x
Reference in New Issue
Block a user