While assisting @RosaWagner with investigating https://github.com/zalando/sans/actions/runs/21861926252/job/63093057085?pr=42, I found an error in gftools' treatment of nested list variables.
Description
When running gftools builder on a config.yaml file that includes operations generating complex metadata fixes—such as splitItalic: true or - operation: fix—the build process crashes while attempting to generate the Ninja build file.
The builder is internally passing a Python list of lists (representing the table fixes) directly to the Ninja writer. Because ninja-syntax expects a flat list of strings to join, it throws a TypeError when it encounters the nested lists.
Proposed Resolution
The gftools builder needs to intercept these complex internal data structures and safely serialize them into JSON strings before passing them to the Ninja writer payload.
--
I was able to resolve this locally via modifying the ninja_syntax.py file to serialize the data, but the fix should happen in gftools directly.
if isinstance(value, list):
try:
value = ' '.join(filter(None, value))
except TypeError:
# Bypass gftools bug: safely serialize nested lists into a quoted JSON string
import json
import shlex
value = shlex.quote(json.dumps(value))
Gemini suggests modifying: https://github.com/googlefonts/gftools/blob/main/Lib/gftools/builder/operations/__init__.py
@property
def variables(self):
return {k: v for k, v in self.original.items() if k != "needs"}
to
@property
def variables(self):
import json
import shlex
vars_dict = {}
for k, v in self.original.items():
if k == "needs":
continue
# If the value is a complex structure (like a list of lists),
# safely serialize it so ninja-syntax doesn't crash on .join()
if isinstance(v, (list, dict)) and any(isinstance(i, (list, dict)) for i in (v if isinstance(v, list) else v.values())):
vars_dict[k] = shlex.quote(json.dumps(v))
else:
vars_dict[k] = v
return vars_dict
While assisting @RosaWagner with investigating https://github.com/zalando/sans/actions/runs/21861926252/job/63093057085?pr=42, I found an error in gftools' treatment of nested list variables.
Description
When running gftools builder on a config.yaml file that includes operations generating complex metadata fixes—such as splitItalic: true or - operation: fix—the build process crashes while attempting to generate the Ninja build file.
The builder is internally passing a Python list of lists (representing the table fixes) directly to the Ninja writer. Because ninja-syntax expects a flat list of strings to join, it throws a TypeError when it encounters the nested lists.
Proposed Resolution
The gftools builder needs to intercept these complex internal data structures and safely serialize them into JSON strings before passing them to the Ninja writer payload.
--
I was able to resolve this locally via modifying the
ninja_syntax.pyfile to serialize the data, but the fix should happen in gftools directly.Gemini suggests modifying:
https://github.com/googlefonts/gftools/blob/main/Lib/gftools/builder/operations/__init__.pyto