Use kwargs and explicit stack

This commit is contained in:
Simon Cozens 2021-03-19 10:38:15 +00:00
parent 23cb8b989b
commit bfe4bad37b
2 changed files with 49 additions and 81 deletions

View File

@ -12,17 +12,16 @@ class VarLibValidationError(VarLibError):
class VarLibMergeError(VarLibError):
"""Raised when input data cannot be merged into a variable font."""
def __init__(self, merger, args):
def __init__(self, merger, **kwargs):
self.merger = merger
self.args = args
@property
def cause(self):
return self.args[0]
@property
def stack(self):
return self.args[1:]
if not kwargs:
kwargs = {}
if "stack" in kwargs:
self.stack = kwargs["stack"]
del kwargs["stack"]
else:
self.stack = []
self.cause = kwargs
@property
def reason(self):

View File

@ -79,9 +79,9 @@ class Merger(object):
item.ensureDecompiled()
keys = sorted(vars(out).keys())
if not all(keys == sorted(vars(v).keys()) for v in lst):
raise KeysDiffer(self, ({
"expected": keys,
"got": [sorted(vars(v).keys()) for v in lst]},))
raise KeysDiffer(self, expected=keys,
got=[sorted(vars(v).keys()) for v in lst]
)
mergers = self.mergersFor(out)
defaultMerger = mergers.get('*', self.__class__.mergeThings)
try:
@ -92,26 +92,25 @@ class Merger(object):
mergerFunc = mergers.get(key, defaultMerger)
mergerFunc(self, value, values)
except VarLibMergeError as e:
e.args = e.args + ('.'+key,)
e.stack.append('.'+key)
raise
def mergeLists(self, out, lst):
if not allEqualTo(out, lst, len):
raise LengthsDiffer(self, ({
"expected": len(out),
"got": [len(x) for x in lst]},))
raise LengthsDiffer(self, expected=len(out), got=[len(x) for x in lst])
for i,(value,values) in enumerate(zip(out, zip(*lst))):
try:
self.mergeThings(value, values)
except VarLibMergeError as e:
e.args = e.args + ('[%d]' % i,)
e.stack.append('[%d]' % i)
raise
def mergeThings(self, out, lst):
if not allEqualTo(out, lst, type):
raise MismatchedTypes(self, ({
"expected": type(out).__name__,
"got": [type(x).__name__ for x in lst]},))
raise MismatchedTypes(self,
expected=type(out).__name__,
got=[type(x).__name__ for x in lst]
)
mergerFunc = self.mergersFor(out).get(None, None)
if mergerFunc is not None:
mergerFunc(self, out, lst)
@ -121,9 +120,7 @@ class Merger(object):
self.mergeLists(out, lst)
else:
if not allEqualTo(out, lst):
raise ShouldBeConstant(self, ({
"expected": out,
"got": lst},))
raise ShouldBeConstant(self, expected=out, got=lst)
def mergeTables(self, font, master_ttfs, tableTags):
for tag in tableTags:
@ -133,7 +130,7 @@ class Merger(object):
self.mergeThings(font[tag], [m[tag] if tag in m else None
for m in master_ttfs])
except VarLibMergeError as e:
e.args = e.args + (tag,)
e.stack.append(tag)
raise
#
@ -146,10 +143,7 @@ class AligningMerger(Merger):
def merge(merger, self, lst):
if self is None:
if not allNone(lst):
raise NotANone(self, ({
"expected": None,
"got": lst
},))
raise NotANone(self, expected=None, got=lst)
return
lst = [l.classDefs for l in lst]
@ -162,10 +156,7 @@ def merge(merger, self, lst):
for k in allKeys:
allValues = nonNone(l.get(k) for l in lst)
if not allEqual(allValues):
raise ShouldBeConstant(self, ({
"expected": allValues[0],
"got": lst,
}, "."+k))
raise ShouldBeConstant(self, expected=allValues[0], got=lst, stack="."+k)
if not allValues:
self[k] = None
else:
@ -202,8 +193,7 @@ def _merge_GlyphOrders(font, lst, values_lst=None, default=None):
order = sorted(combined, key=sortKey)
# Make sure all input glyphsets were in proper order
if not all(sorted(vs, key=sortKey) == vs for vs in lst):
raise InconsistentGlyphOrder(self, ({
},))
raise InconsistentGlyphOrder(self)
del combined
paddedValues = None
@ -230,9 +220,7 @@ def _Lookup_SinglePos_get_effective_value(subtables, glyph):
elif self.Format == 2:
return self.Value[self.Coverage.glyphs.index(glyph)]
else:
raise UnsupportedFormat(self, ({
"subtable": "single positioning lookup"
},))
raise UnsupportedFormat(self, subtable="single positioning lookup")
return None
def _Lookup_PairPos_get_effective_value_pair(subtables, firstGlyph, secondGlyph):
@ -254,19 +242,14 @@ def _Lookup_PairPos_get_effective_value_pair(subtables, firstGlyph, secondGlyph)
klass2 = self.ClassDef2.classDefs.get(secondGlyph, 0)
return self.Class1Record[klass1].Class2Record[klass2]
else:
raise UnsupportedFormat(self, ({
"subtable": "pair positioning lookup"
},))
raise UnsupportedFormat(self, subtable="pair positioning lookup")
return None
@AligningMerger.merger(ot.SinglePos)
def merge(merger, self, lst):
self.ValueFormat = valueFormat = reduce(int.__or__, [l.ValueFormat for l in lst], 0)
if not (len(lst) == 1 or (valueFormat & ~0xF == 0)):
raise UnsupportedFormat(self, ({
"subtable": "single positioning lookup"
},))
raise UnsupportedFormat(self, subtable="single positioning lookup")
# If all have same coverage table and all are format 1,
coverageGlyphs = self.Coverage.glyphs
@ -552,9 +535,7 @@ def merge(merger, self, lst):
elif self.Format == 2:
_PairPosFormat2_merge(self, lst, merger)
else:
raise UnsupportedFormat(self, ({
"subtable": "pair positioning lookup"
},))
raise UnsupportedFormat(self, subtable="pair positioning lookup")
del merger.valueFormat1, merger.valueFormat2
@ -669,31 +650,28 @@ def _MarkBasePosFormat1_merge(self, lst, merger, Mark='Mark', Base='Base'):
@AligningMerger.merger(ot.MarkBasePos)
def merge(merger, self, lst):
if not allEqualTo(self.Format, (l.Format for l in lst)):
raise InconsistentFormats(self, ({
"subtable": "mark-to-base positioning lookup",
"expected": self.Format,
"got": [l.Format for l in lst]},))
raise InconsistentFormats(self,
subtable="mark-to-base positioning lookup",
expected=self.Format,
got=[l.Format for l in lst]
)
if self.Format == 1:
_MarkBasePosFormat1_merge(self, lst, merger)
else:
raise UnsupportedFormat(self, ({
"subtable": "mark-to-base positioning lookup",
}))
raise UnsupportedFormat(self, subtable="mark-to-base positioning lookup")
@AligningMerger.merger(ot.MarkMarkPos)
def merge(merger, self, lst):
if not allEqualTo(self.Format, (l.Format for l in lst)):
raise InconsistentFormats(self, ({
"subtable": "mark-to-mark positioning lookup",
"expected": self.Format,
"got": [l.Format for l in lst]},))
raise InconsistentFormats(self,
subtable="mark-to-mark positioning lookup",
expected=self.Format,
got=[l.Format for l in lst]
)
if self.Format == 1:
_MarkBasePosFormat1_merge(self, lst, merger, 'Mark1', 'Mark2')
else:
raise UnsupportedFormat(self, ({
"subtable": "mark-to-mark positioning lookup",
}))
raise UnsupportedFormat(self, subtable="mark-to-mark positioning lookup")
def _PairSet_flatten(lst, font):
self = ot.PairSet()
@ -822,13 +800,12 @@ def merge(merger, self, lst):
continue
if sts[0].__class__.__name__.startswith('Extension'):
if not allEqual([st.__class__ for st in sts]):
raise InconsistentExtensions(self, ({
"expected": "Extension",
"got": [st.__class__.__name__ for st in sts]
},))
raise InconsistentExtensions(self,
expected="Extension",
got=[st.__class__.__name__ for st in sts]
)
if not allEqual([st.ExtensionLookupType for st in sts]):
raise InconsistentExtensions(self, ({
},))
raise InconsistentExtensions(self)
l.LookupType = sts[0].ExtensionLookupType
new_sts = [st.ExtSubTable for st in sts]
del sts[:]
@ -1057,9 +1034,7 @@ class VariationMerger(AligningMerger):
if None in lst:
if allNone(lst):
if out is not None:
raise FoundANone(self, ({
"got": lst
},))
raise FoundANone(self, got=lst)
return
masterModel = self.model
model, lst = masterModel.getSubModel(lst)
@ -1080,9 +1055,7 @@ def buildVarDevTable(store_builder, master_values):
@VariationMerger.merger(ot.BaseCoord)
def merge(merger, self, lst):
if self.Format != 1:
raise UnsupportedFormat(self, ({
"subtable": "a baseline coordinate"
},))
raise UnsupportedFormat(self, subtable="a baseline coordinate")
self.Coordinate, DeviceTable = buildVarDevTable(merger.store_builder, [a.Coordinate for a in lst])
if DeviceTable:
self.Format = 3
@ -1091,9 +1064,7 @@ def merge(merger, self, lst):
@VariationMerger.merger(ot.CaretValue)
def merge(merger, self, lst):
if self.Format != 1:
raise UnsupportedFormat(self, ({
"subtable": "a caret"
},))
raise UnsupportedFormat(self, subtable="a caret")
self.Coordinate, DeviceTable = buildVarDevTable(merger.store_builder, [a.Coordinate for a in lst])
if DeviceTable:
self.Format = 3
@ -1102,9 +1073,7 @@ def merge(merger, self, lst):
@VariationMerger.merger(ot.Anchor)
def merge(merger, self, lst):
if self.Format != 1:
raise UnsupportedFormat(self, ({
"subtable": "an anchor"
},))
raise UnsupportedFormat(self, subtable="an anchor")
self.XCoordinate, XDeviceTable = buildVarDevTable(merger.store_builder, [a.XCoordinate for a in lst])
self.YCoordinate, YDeviceTable = buildVarDevTable(merger.store_builder, [a.YCoordinate for a in lst])
if XDeviceTable or YDeviceTable: