"""Generate exact repository source anchors without importing application code.""" from __future__ import annotations import ast import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] EXAMPLES_DIR = ROOT / "src" / "gallery" / "examples" OUTPUT = ROOT / "src" / "gallery" / "source_manifest.json" def collect() -> dict[str, dict[str, str | int]]: manifest: dict[str, dict[str, str | int]] = {} for path in sorted(EXAMPLES_DIR.glob("*.py")): if path.name == "__init__.py": continue tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path)) functions = { node.name: node.lineno for node in tree.body if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) } for node in ast.walk(tree): if not isinstance(node, ast.Call) or not isinstance(node.func, ast.Name): continue if node.func.id != "Example" or len(node.args) < 5: continue example_id, builder = node.args[0], node.args[4] if not isinstance(example_id, ast.Constant) or not isinstance(example_id.value, str): raise TypeError(f"Example id must be a string in {path}") if not isinstance(builder, ast.Name) or builder.id not in functions: raise ValueError(f"Example {example_id.value} must reference a local function") if example_id.value in manifest: raise ValueError(f"Duplicate example id: {example_id.value}") manifest[example_id.value] = { "path": path.relative_to(ROOT).as_posix(), "line": functions[builder.id], "function": builder.id, } return manifest def main() -> None: content = json.dumps(collect(), ensure_ascii=False, indent=2, sort_keys=True) + "\n" OUTPUT.write_text(content, encoding="utf-8") print(f"Generated {OUTPUT.relative_to(ROOT)}") if __name__ == "__main__": main()