We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[varLib.merger] <exception str() failed>
I'm in the process of figuring out what is happening here, but in the meantime I thought I'd post this as it apears there is a bug in the exception handling: see the `<exception str() failed>` messages below.

```
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py", line 1065, in run_from_designspace
    self._run_from_designspace_interpolatable(
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py", line 1157, in _run_from_designspace_interpolatable
    self.build_variable_fonts(
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py", line 384, in build_variable_fonts
    fonts = ufo2ft.compileVariableTTFs(
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/ufo2ft/__init__.py", line 605, in compileVariableTTFs
    vfNameToTTFont = varLib.build_many(
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/__init__.py", line 911, in build_many
    vf = build(
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/__init__.py", line 986, in build
    _merge_OTL(vf, model, master_fonts, axisTags)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/__init__.py", line 624, in _merge_OTL
    merger.mergeTables(font, master_fonts, ['GSUB', 'GDEF', 'GPOS'])
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 150, in mergeTables
    self.mergeThings(font[tag], [m.get(tag) for m in master_ttfs])
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 1067, in mergeThings
    super(VariationMerger, self).mergeThings(out, lst)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 138, in mergeThings
    self.mergeObjects(out, lst)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 108, in mergeObjects
    mergerFunc(self, value, values)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 1067, in mergeThings
    super(VariationMerger, self).mergeThings(out, lst)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 138, in mergeThings
    self.mergeObjects(out, lst)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 108, in mergeObjects
    mergerFunc(self, value, values)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 1067, in mergeThings
    super(VariationMerger, self).mergeThings(out, lst)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 138, in mergeThings
    self.mergeObjects(out, lst)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 108, in mergeObjects
    mergerFunc(self, value, values)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 1067, in mergeThings
    super(VariationMerger, self).mergeThings(out, lst)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py", line 143, in mergeThings
    raise ShouldBeConstant(self, expected=out, got=lst)
fontTools.varLib.errors.ShouldBeConstant: <exception str() failed>
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/__main__.py", line 639, in main
    project.run_from_designspace(inputs.designspace_path, **args)
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py", line 1080, in run_from_designspace
    raise FontmakeError(
fontmake.errors.FontmakeError: <exception str() failed>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.8.13/x64/bin/fontmake", line 8, in <module>
    sys.exit(main())
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/__main__.py", line 664, in main
    sys.exit(f"fontmake: Error: {str(e)}")
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/errors.py", line 33, in __str__
    cause = str(self.__cause__) if self.__cause__ is not None else None
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/errors.py", line 70, in __str__
    return "\n\n" + basic + location + self.details
  File "/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/errors.py", line 86, in details
    good_ttf = next(
StopIteration
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Lib/fontTools/varLib/errors.py`
Content:
```
1 import textwrap
2 
3 
4 class VarLibError(Exception):
5     """Base exception for the varLib module."""
6 
7 
8 class VarLibValidationError(VarLibError):
9     """Raised when input data is invalid from varLib's point of view."""
10 
11 
12 class VarLibMergeError(VarLibError):
13     """Raised when input data cannot be merged into a variable font."""
14 
15     def __init__(self, merger=None, **kwargs):
16         self.merger = merger
17         if not kwargs:
18             kwargs = {}
19         if "stack" in kwargs:
20             self.stack = kwargs["stack"]
21             del kwargs["stack"]
22         else:
23             self.stack = []
24         self.cause = kwargs
25 
26     @property
27     def reason(self):
28         return self.__doc__
29 
30     def _master_name(self, ix):
31         if self.merger is not None:
32             ttf = self.merger.ttfs[ix]
33             if "name" in ttf and ttf["name"].getBestFullName():
34                 return ttf["name"].getBestFullName()
35             elif hasattr(ttf.reader, "file") and hasattr(ttf.reader.file, "name"):
36                 return ttf.reader.file.name
37         return f"master number {ix}"
38 
39     @property
40     def offender(self):
41         if "expected" in self.cause and "got" in self.cause:
42             index = [x == self.cause["expected"] for x in self.cause["got"]].index(
43                 False
44             )
45             master_name = self._master_name(index)
46             if "location" in self.cause:
47                 master_name = f"{master_name} ({self.cause['location']})"
48             return index, master_name
49         return None, None
50 
51     @property
52     def details(self):
53         if "expected" in self.cause and "got" in self.cause:
54             offender_index, offender = self.offender
55             got = self.cause["got"][offender_index]
56             return f"Expected to see {self.stack[0]}=={self.cause['expected']!r}, instead saw {got!r}\n"
57         return ""
58 
59     def __str__(self):
60         offender_index, offender = self.offender
61         location = ""
62         if offender:
63             location = f"\n\nThe problem is likely to be in {offender}:\n"
64         context = "".join(reversed(self.stack))
65         basic = textwrap.fill(
66             f"Couldn't merge the fonts, because {self.reason}. "
67             f"This happened while performing the following operation: {context}",
68             width=78,
69         )
70         return "\n\n" + basic + location + self.details
71 
72 
73 class ShouldBeConstant(VarLibMergeError):
74     """some values were different, but should have been the same"""
75 
76     @property
77     def details(self):
78         basic_message = super().details
79 
80         if self.stack[0] != ".FeatureCount" or self.merger is None:
81             return basic_message
82 
83         assert self.stack[0] == ".FeatureCount"
84         offender_index, _ = self.offender
85         bad_ttf = self.merger.ttfs[offender_index]
86         good_ttf = next(
87             ttf
88             for ttf in self.merger.ttfs
89             if ttf["GPOS"].table.FeatureList.FeatureCount == self.cause["expected"]
90         )
91 
92         good_features = [
93             x.FeatureTag
94             for x in good_ttf[self.stack[-1]].table.FeatureList.FeatureRecord
95         ]
96         bad_features = [
97             x.FeatureTag
98             for x in bad_ttf[self.stack[-1]].table.FeatureList.FeatureRecord
99         ]
100         return basic_message + (
101             "\nIncompatible features between masters.\n"
102             f"Expected: {', '.join(good_features)}.\n"
103             f"Got: {', '.join(bad_features)}.\n"
104         )
105 
106 
107 class FoundANone(VarLibMergeError):
108     """one of the values in a list was empty when it shouldn't have been"""
109 
110     @property
111     def offender(self):
112         index = [x is None for x in self.cause["got"]].index(True)
113         return index, self._master_name(index)
114 
115     @property
116     def details(self):
117         cause, stack = self.cause, self.stack
118         return f"{stack[0]}=={cause['got']}\n"
119 
120 
121 class MismatchedTypes(VarLibMergeError):
122     """data had inconsistent types"""
123 
124 
125 class LengthsDiffer(VarLibMergeError):
126     """a list of objects had inconsistent lengths"""
127 
128 
129 class KeysDiffer(VarLibMergeError):
130     """a list of objects had different keys"""
131 
132 
133 class InconsistentGlyphOrder(VarLibMergeError):
134     """the glyph order was inconsistent between masters"""
135 
136 
137 class InconsistentExtensions(VarLibMergeError):
138     """the masters use extension lookups in inconsistent ways"""
139 
140 
141 class UnsupportedFormat(VarLibMergeError):
142     """an OpenType subtable (%s) had a format I didn't expect"""
143 
144     def __init__(self, merger=None, **kwargs):
145         super().__init__(merger, **kwargs)
146         if not self.stack:
147             self.stack = [".Format"]
148 
149     @property
150     def reason(self):
151         s = self.__doc__ % self.cause["subtable"]
152         if "value" in self.cause:
153             s += f" ({self.cause['value']!r})"
154         return s
155 
156 
157 class InconsistentFormats(UnsupportedFormat):
158     """an OpenType subtable (%s) had inconsistent formats between masters"""
159 
160 
161 class VarLibCFFMergeError(VarLibError):
162     pass
163 
164 
165 class VarLibCFFDictMergeError(VarLibCFFMergeError):
166     """Raised when a CFF PrivateDict cannot be merged."""
167 
168     def __init__(self, key, value, values):
169         error_msg = (
170             f"For the Private Dict key '{key}', the default font value list:"
171             f"\n\t{value}\nhad a different number of values than a region font:"
172         )
173         for region_value in values:
174             error_msg += f"\n\t{region_value}"
175         self.args = (error_msg,)
176 
177 
178 class VarLibCFFPointTypeMergeError(VarLibCFFMergeError):
179     """Raised when a CFF glyph cannot be merged because of point type differences."""
180 
181     def __init__(self, point_type, pt_index, m_index, default_type, glyph_name):
182         error_msg = (
183             f"Glyph '{glyph_name}': '{point_type}' at point index {pt_index} in "
184             f"master index {m_index} differs from the default font point type "
185             f"'{default_type}'"
186         )
187         self.args = (error_msg,)
188 
189 
190 class VarLibCFFHintTypeMergeError(VarLibCFFMergeError):
191     """Raised when a CFF glyph cannot be merged because of hint type differences."""
192 
193     def __init__(self, hint_type, cmd_index, m_index, default_type, glyph_name):
194         error_msg = (
195             f"Glyph '{glyph_name}': '{hint_type}' at index {cmd_index} in "
196             f"master index {m_index} differs from the default font hint type "
197             f"'{default_type}'"
198         )
199         self.args = (error_msg,)
200 
201 
202 class VariationModelError(VarLibError):
203     """Raised when a variation model is faulty."""
204
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Lib/fontTools/varLib/errors.py b/Lib/fontTools/varLib/errors.py
--- a/Lib/fontTools/varLib/errors.py
+++ b/Lib/fontTools/varLib/errors.py
@@ -86,7 +86,9 @@
         good_ttf = next(
             ttf
             for ttf in self.merger.ttfs
-            if ttf["GPOS"].table.FeatureList.FeatureCount == self.cause["expected"]
+            if self.stack[-1] in ttf
+            and ttf[self.stack[-1]].table.FeatureList.FeatureCount
+            == self.cause["expected"]
         )
 
         good_features = [

{"golden_diff": "diff --git a/Lib/fontTools/varLib/errors.py b/Lib/fontTools/varLib/errors.py\n--- a/Lib/fontTools/varLib/errors.py\n+++ b/Lib/fontTools/varLib/errors.py\n@@ -86,7 +86,9 @@\n         good_ttf = next(\n             ttf\n             for ttf in self.merger.ttfs\n-            if ttf[\"GPOS\"].table.FeatureList.FeatureCount == self.cause[\"expected\"]\n+            if self.stack[-1] in ttf\n+            and ttf[self.stack[-1]].table.FeatureList.FeatureCount\n+            == self.cause[\"expected\"]\n         )\n \n         good_features = [\n", "issue": "[varLib.merger] <exception str() failed>\nI'm in the process of figuring out what is happening here, but in the meantime I thought I'd post this as it apears there is a bug in the exception handling: see the `<exception str() failed>` messages below.\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py\", line 1065, in run_from_designspace\r\n    self._run_from_designspace_interpolatable(\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py\", line 1157, in _run_from_designspace_interpolatable\r\n    self.build_variable_fonts(\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py\", line 384, in build_variable_fonts\r\n    fonts = ufo2ft.compileVariableTTFs(\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/ufo2ft/__init__.py\", line 605, in compileVariableTTFs\r\n    vfNameToTTFont = varLib.build_many(\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/__init__.py\", line 911, in build_many\r\n    vf = build(\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/__init__.py\", line 986, in build\r\n    _merge_OTL(vf, model, master_fonts, axisTags)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/__init__.py\", line 624, in _merge_OTL\r\n    merger.mergeTables(font, master_fonts, ['GSUB', 'GDEF', 'GPOS'])\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 150, in mergeTables\r\n    self.mergeThings(font[tag], [m.get(tag) for m in master_ttfs])\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 1067, in mergeThings\r\n    super(VariationMerger, self).mergeThings(out, lst)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 138, in mergeThings\r\n    self.mergeObjects(out, lst)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 108, in mergeObjects\r\n    mergerFunc(self, value, values)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 1067, in mergeThings\r\n    super(VariationMerger, self).mergeThings(out, lst)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 138, in mergeThings\r\n    self.mergeObjects(out, lst)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 108, in mergeObjects\r\n    mergerFunc(self, value, values)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 1067, in mergeThings\r\n    super(VariationMerger, self).mergeThings(out, lst)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 138, in mergeThings\r\n    self.mergeObjects(out, lst)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 108, in mergeObjects\r\n    mergerFunc(self, value, values)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 1067, in mergeThings\r\n    super(VariationMerger, self).mergeThings(out, lst)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/merger.py\", line 143, in mergeThings\r\n    raise ShouldBeConstant(self, expected=out, got=lst)\r\nfontTools.varLib.errors.ShouldBeConstant: <exception str() failed>\r\nThe above exception was the direct cause of the following exception:\r\nTraceback (most recent call last):\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/__main__.py\", line 639, in main\r\n    project.run_from_designspace(inputs.designspace_path, **args)\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/font_project.py\", line 1080, in run_from_designspace\r\n    raise FontmakeError(\r\nfontmake.errors.FontmakeError: <exception str() failed>\r\nDuring handling of the above exception, another exception occurred:\r\nTraceback (most recent call last):\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/bin/fontmake\", line 8, in <module>\r\n    sys.exit(main())\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/__main__.py\", line 664, in main\r\n    sys.exit(f\"fontmake: Error: {str(e)}\")\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontmake/errors.py\", line 33, in __str__\r\n    cause = str(self.__cause__) if self.__cause__ is not None else None\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/errors.py\", line 70, in __str__\r\n    return \"\\n\\n\" + basic + location + self.details\r\n  File \"/opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/fontTools/varLib/errors.py\", line 86, in details\r\n    good_ttf = next(\r\nStopIteration\r\n```\n", "before_files": [{"content": "import textwrap\n\n\nclass VarLibError(Exception):\n    \"\"\"Base exception for the varLib module.\"\"\"\n\n\nclass VarLibValidationError(VarLibError):\n    \"\"\"Raised when input data is invalid from varLib's point of view.\"\"\"\n\n\nclass VarLibMergeError(VarLibError):\n    \"\"\"Raised when input data cannot be merged into a variable font.\"\"\"\n\n    def __init__(self, merger=None, **kwargs):\n        self.merger = merger\n        if not kwargs:\n            kwargs = {}\n        if \"stack\" in kwargs:\n            self.stack = kwargs[\"stack\"]\n            del kwargs[\"stack\"]\n        else:\n            self.stack = []\n        self.cause = kwargs\n\n    @property\n    def reason(self):\n        return self.__doc__\n\n    def _master_name(self, ix):\n        if self.merger is not None:\n            ttf = self.merger.ttfs[ix]\n            if \"name\" in ttf and ttf[\"name\"].getBestFullName():\n                return ttf[\"name\"].getBestFullName()\n            elif hasattr(ttf.reader, \"file\") and hasattr(ttf.reader.file, \"name\"):\n                return ttf.reader.file.name\n        return f\"master number {ix}\"\n\n    @property\n    def offender(self):\n        if \"expected\" in self.cause and \"got\" in self.cause:\n            index = [x == self.cause[\"expected\"] for x in self.cause[\"got\"]].index(\n                False\n            )\n            master_name = self._master_name(index)\n            if \"location\" in self.cause:\n                master_name = f\"{master_name} ({self.cause['location']})\"\n            return index, master_name\n        return None, None\n\n    @property\n    def details(self):\n        if \"expected\" in self.cause and \"got\" in self.cause:\n            offender_index, offender = self.offender\n            got = self.cause[\"got\"][offender_index]\n            return f\"Expected to see {self.stack[0]}=={self.cause['expected']!r}, instead saw {got!r}\\n\"\n        return \"\"\n\n    def __str__(self):\n        offender_index, offender = self.offender\n        location = \"\"\n        if offender:\n            location = f\"\\n\\nThe problem is likely to be in {offender}:\\n\"\n        context = \"\".join(reversed(self.stack))\n        basic = textwrap.fill(\n            f\"Couldn't merge the fonts, because {self.reason}. \"\n            f\"This happened while performing the following operation: {context}\",\n            width=78,\n        )\n        return \"\\n\\n\" + basic + location + self.details\n\n\nclass ShouldBeConstant(VarLibMergeError):\n    \"\"\"some values were different, but should have been the same\"\"\"\n\n    @property\n    def details(self):\n        basic_message = super().details\n\n        if self.stack[0] != \".FeatureCount\" or self.merger is None:\n            return basic_message\n\n        assert self.stack[0] == \".FeatureCount\"\n        offender_index, _ = self.offender\n        bad_ttf = self.merger.ttfs[offender_index]\n        good_ttf = next(\n            ttf\n            for ttf in self.merger.ttfs\n            if ttf[\"GPOS\"].table.FeatureList.FeatureCount == self.cause[\"expected\"]\n        )\n\n        good_features = [\n            x.FeatureTag\n            for x in good_ttf[self.stack[-1]].table.FeatureList.FeatureRecord\n        ]\n        bad_features = [\n            x.FeatureTag\n            for x in bad_ttf[self.stack[-1]].table.FeatureList.FeatureRecord\n        ]\n        return basic_message + (\n            \"\\nIncompatible features between masters.\\n\"\n            f\"Expected: {', '.join(good_features)}.\\n\"\n            f\"Got: {', '.join(bad_features)}.\\n\"\n        )\n\n\nclass FoundANone(VarLibMergeError):\n    \"\"\"one of the values in a list was empty when it shouldn't have been\"\"\"\n\n    @property\n    def offender(self):\n        index = [x is None for x in self.cause[\"got\"]].index(True)\n        return index, self._master_name(index)\n\n    @property\n    def details(self):\n        cause, stack = self.cause, self.stack\n        return f\"{stack[0]}=={cause['got']}\\n\"\n\n\nclass MismatchedTypes(VarLibMergeError):\n    \"\"\"data had inconsistent types\"\"\"\n\n\nclass LengthsDiffer(VarLibMergeError):\n    \"\"\"a list of objects had inconsistent lengths\"\"\"\n\n\nclass KeysDiffer(VarLibMergeError):\n    \"\"\"a list of objects had different keys\"\"\"\n\n\nclass InconsistentGlyphOrder(VarLibMergeError):\n    \"\"\"the glyph order was inconsistent between masters\"\"\"\n\n\nclass InconsistentExtensions(VarLibMergeError):\n    \"\"\"the masters use extension lookups in inconsistent ways\"\"\"\n\n\nclass UnsupportedFormat(VarLibMergeError):\n    \"\"\"an OpenType subtable (%s) had a format I didn't expect\"\"\"\n\n    def __init__(self, merger=None, **kwargs):\n        super().__init__(merger, **kwargs)\n        if not self.stack:\n            self.stack = [\".Format\"]\n\n    @property\n    def reason(self):\n        s = self.__doc__ % self.cause[\"subtable\"]\n        if \"value\" in self.cause:\n            s += f\" ({self.cause['value']!r})\"\n        return s\n\n\nclass InconsistentFormats(UnsupportedFormat):\n    \"\"\"an OpenType subtable (%s) had inconsistent formats between masters\"\"\"\n\n\nclass VarLibCFFMergeError(VarLibError):\n    pass\n\n\nclass VarLibCFFDictMergeError(VarLibCFFMergeError):\n    \"\"\"Raised when a CFF PrivateDict cannot be merged.\"\"\"\n\n    def __init__(self, key, value, values):\n        error_msg = (\n            f\"For the Private Dict key '{key}', the default font value list:\"\n            f\"\\n\\t{value}\\nhad a different number of values than a region font:\"\n        )\n        for region_value in values:\n            error_msg += f\"\\n\\t{region_value}\"\n        self.args = (error_msg,)\n\n\nclass VarLibCFFPointTypeMergeError(VarLibCFFMergeError):\n    \"\"\"Raised when a CFF glyph cannot be merged because of point type differences.\"\"\"\n\n    def __init__(self, point_type, pt_index, m_index, default_type, glyph_name):\n        error_msg = (\n            f\"Glyph '{glyph_name}': '{point_type}' at point index {pt_index} in \"\n            f\"master index {m_index} differs from the default font point type \"\n            f\"'{default_type}'\"\n        )\n        self.args = (error_msg,)\n\n\nclass VarLibCFFHintTypeMergeError(VarLibCFFMergeError):\n    \"\"\"Raised when a CFF glyph cannot be merged because of hint type differences.\"\"\"\n\n    def __init__(self, hint_type, cmd_index, m_index, default_type, glyph_name):\n        error_msg = (\n            f\"Glyph '{glyph_name}': '{hint_type}' at index {cmd_index} in \"\n            f\"master index {m_index} differs from the default font hint type \"\n            f\"'{default_type}'\"\n        )\n        self.args = (error_msg,)\n\n\nclass VariationModelError(VarLibError):\n    \"\"\"Raised when a variation model is faulty.\"\"\"\n", "path": "Lib/fontTools/varLib/errors.py"}], "after_files": [{"content": "import textwrap\n\n\nclass VarLibError(Exception):\n    \"\"\"Base exception for the varLib module.\"\"\"\n\n\nclass VarLibValidationError(VarLibError):\n    \"\"\"Raised when input data is invalid from varLib's point of view.\"\"\"\n\n\nclass VarLibMergeError(VarLibError):\n    \"\"\"Raised when input data cannot be merged into a variable font.\"\"\"\n\n    def __init__(self, merger=None, **kwargs):\n        self.merger = merger\n        if not kwargs:\n            kwargs = {}\n        if \"stack\" in kwargs:\n            self.stack = kwargs[\"stack\"]\n            del kwargs[\"stack\"]\n        else:\n            self.stack = []\n        self.cause = kwargs\n\n    @property\n    def reason(self):\n        return self.__doc__\n\n    def _master_name(self, ix):\n        if self.merger is not None:\n            ttf = self.merger.ttfs[ix]\n            if \"name\" in ttf and ttf[\"name\"].getBestFullName():\n                return ttf[\"name\"].getBestFullName()\n            elif hasattr(ttf.reader, \"file\") and hasattr(ttf.reader.file, \"name\"):\n                return ttf.reader.file.name\n        return f\"master number {ix}\"\n\n    @property\n    def offender(self):\n        if \"expected\" in self.cause and \"got\" in self.cause:\n            index = [x == self.cause[\"expected\"] for x in self.cause[\"got\"]].index(\n                False\n            )\n            master_name = self._master_name(index)\n            if \"location\" in self.cause:\n                master_name = f\"{master_name} ({self.cause['location']})\"\n            return index, master_name\n        return None, None\n\n    @property\n    def details(self):\n        if \"expected\" in self.cause and \"got\" in self.cause:\n            offender_index, offender = self.offender\n            got = self.cause[\"got\"][offender_index]\n            return f\"Expected to see {self.stack[0]}=={self.cause['expected']!r}, instead saw {got!r}\\n\"\n        return \"\"\n\n    def __str__(self):\n        offender_index, offender = self.offender\n        location = \"\"\n        if offender:\n            location = f\"\\n\\nThe problem is likely to be in {offender}:\\n\"\n        context = \"\".join(reversed(self.stack))\n        basic = textwrap.fill(\n            f\"Couldn't merge the fonts, because {self.reason}. \"\n            f\"This happened while performing the following operation: {context}\",\n            width=78,\n        )\n        return \"\\n\\n\" + basic + location + self.details\n\n\nclass ShouldBeConstant(VarLibMergeError):\n    \"\"\"some values were different, but should have been the same\"\"\"\n\n    @property\n    def details(self):\n        basic_message = super().details\n\n        if self.stack[0] != \".FeatureCount\" or self.merger is None:\n            return basic_message\n\n        assert self.stack[0] == \".FeatureCount\"\n        offender_index, _ = self.offender\n        bad_ttf = self.merger.ttfs[offender_index]\n        good_ttf = next(\n            ttf\n            for ttf in self.merger.ttfs\n            if self.stack[-1] in ttf\n            and ttf[self.stack[-1]].table.FeatureList.FeatureCount\n            == self.cause[\"expected\"]\n        )\n\n        good_features = [\n            x.FeatureTag\n            for x in good_ttf[self.stack[-1]].table.FeatureList.FeatureRecord\n        ]\n        bad_features = [\n            x.FeatureTag\n            for x in bad_ttf[self.stack[-1]].table.FeatureList.FeatureRecord\n        ]\n        return basic_message + (\n            \"\\nIncompatible features between masters.\\n\"\n            f\"Expected: {', '.join(good_features)}.\\n\"\n            f\"Got: {', '.join(bad_features)}.\\n\"\n        )\n\n\nclass FoundANone(VarLibMergeError):\n    \"\"\"one of the values in a list was empty when it shouldn't have been\"\"\"\n\n    @property\n    def offender(self):\n        index = [x is None for x in self.cause[\"got\"]].index(True)\n        return index, self._master_name(index)\n\n    @property\n    def details(self):\n        cause, stack = self.cause, self.stack\n        return f\"{stack[0]}=={cause['got']}\\n\"\n\n\nclass MismatchedTypes(VarLibMergeError):\n    \"\"\"data had inconsistent types\"\"\"\n\n\nclass LengthsDiffer(VarLibMergeError):\n    \"\"\"a list of objects had inconsistent lengths\"\"\"\n\n\nclass KeysDiffer(VarLibMergeError):\n    \"\"\"a list of objects had different keys\"\"\"\n\n\nclass InconsistentGlyphOrder(VarLibMergeError):\n    \"\"\"the glyph order was inconsistent between masters\"\"\"\n\n\nclass InconsistentExtensions(VarLibMergeError):\n    \"\"\"the masters use extension lookups in inconsistent ways\"\"\"\n\n\nclass UnsupportedFormat(VarLibMergeError):\n    \"\"\"an OpenType subtable (%s) had a format I didn't expect\"\"\"\n\n    def __init__(self, merger=None, **kwargs):\n        super().__init__(merger, **kwargs)\n        if not self.stack:\n            self.stack = [\".Format\"]\n\n    @property\n    def reason(self):\n        s = self.__doc__ % self.cause[\"subtable\"]\n        if \"value\" in self.cause:\n            s += f\" ({self.cause['value']!r})\"\n        return s\n\n\nclass InconsistentFormats(UnsupportedFormat):\n    \"\"\"an OpenType subtable (%s) had inconsistent formats between masters\"\"\"\n\n\nclass VarLibCFFMergeError(VarLibError):\n    pass\n\n\nclass VarLibCFFDictMergeError(VarLibCFFMergeError):\n    \"\"\"Raised when a CFF PrivateDict cannot be merged.\"\"\"\n\n    def __init__(self, key, value, values):\n        error_msg = (\n            f\"For the Private Dict key '{key}', the default font value list:\"\n            f\"\\n\\t{value}\\nhad a different number of values than a region font:\"\n        )\n        for region_value in values:\n            error_msg += f\"\\n\\t{region_value}\"\n        self.args = (error_msg,)\n\n\nclass VarLibCFFPointTypeMergeError(VarLibCFFMergeError):\n    \"\"\"Raised when a CFF glyph cannot be merged because of point type differences.\"\"\"\n\n    def __init__(self, point_type, pt_index, m_index, default_type, glyph_name):\n        error_msg = (\n            f\"Glyph '{glyph_name}': '{point_type}' at point index {pt_index} in \"\n            f\"master index {m_index} differs from the default font point type \"\n            f\"'{default_type}'\"\n        )\n        self.args = (error_msg,)\n\n\nclass VarLibCFFHintTypeMergeError(VarLibCFFMergeError):\n    \"\"\"Raised when a CFF glyph cannot be merged because of hint type differences.\"\"\"\n\n    def __init__(self, hint_type, cmd_index, m_index, default_type, glyph_name):\n        error_msg = (\n            f\"Glyph '{glyph_name}': '{hint_type}' at index {cmd_index} in \"\n            f\"master index {m_index} differs from the default font hint type \"\n            f\"'{default_type}'\"\n        )\n        self.args = (error_msg,)\n\n\nclass VariationModelError(VarLibError):\n    \"\"\"Raised when a variation model is faulty.\"\"\"\n", "path": "Lib/fontTools/varLib/errors.py"}]}