From bfe4bad37b93904619d66866b696a07986cec927 Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Fri, 19 Mar 2021 10:38:15 +0000 Subject: [PATCH] Use kwargs and explicit stack --- Lib/fontTools/varLib/errors.py | 19 +++--- Lib/fontTools/varLib/merger.py | 111 ++++++++++++--------------------- 2 files changed, 49 insertions(+), 81 deletions(-) diff --git a/Lib/fontTools/varLib/errors.py b/Lib/fontTools/varLib/errors.py index 9d150a0e0..e14138290 100644 --- a/Lib/fontTools/varLib/errors.py +++ b/Lib/fontTools/varLib/errors.py @@ -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): diff --git a/Lib/fontTools/varLib/merger.py b/Lib/fontTools/varLib/merger.py index 72868c6c2..b8b7b27d6 100644 --- a/Lib/fontTools/varLib/merger.py +++ b/Lib/fontTools/varLib/merger.py @@ -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: