Skip to content

Commit 6e6b956

Browse files
nielspardonclaude
andauthored
fix(extensions): expose top-level metadata in YAML extension files (#170)
## Summary build_simple_extensions populated metadata for functions and types but silently dropped the file-level metadata field, so it was not available at runtime. This completes the metadata exposure work started in #168. - Pass metadata through to SimpleExtensions. - Add a test module covering metadata exposure at the file, function, and type levels, plus the default-None case. Implementation-level (Impl/Impl1/Impl2) and TypeVariation schema classes have no metadata field, so there is nothing to expose there. ## Testing - New tests/test_simple_extension_utils.py — 2 passed. - Existing tests/extension_registry/ suite — 88 passed, no regressions. Fixes #149 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 077859b commit 6e6b956

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

src/substrait/simple_extension_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ def build_type_variation(d: dict) -> se.TypeVariation:
172172
def build_simple_extensions(d: dict) -> se.SimpleExtensions:
173173
return se.SimpleExtensions(
174174
urn=d["urn"],
175+
metadata=d.get("metadata"),
175176
dependencies=d.get("dependencies"),
176177
types=[build_type_model(t) for t in d["types"]] if "types" in d else None,
177178
type_variations=[build_type_variation(t) for t in d["type_variations"]]
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""Tests for parsing simple extension YAML dicts into schema objects."""
2+
3+
from substrait.simple_extension_utils import build_simple_extensions
4+
5+
6+
def test_metadata_is_exposed_at_all_levels():
7+
"""Metadata should be carried through from the YAML dict at every level
8+
where the simple-extension schema supports it (file, function, type)."""
9+
definitions = {
10+
"urn": "extension:test:metadata",
11+
"metadata": {"author": "me", "version": 1},
12+
"types": [
13+
{"name": "point", "metadata": {"kind": "geometry"}},
14+
],
15+
"scalar_functions": [
16+
{
17+
"name": "f",
18+
"impls": [{"return": "i64"}],
19+
"metadata": {"category": "math"},
20+
},
21+
],
22+
"aggregate_functions": [
23+
{
24+
"name": "g",
25+
"impls": [{"return": "i64"}],
26+
"metadata": {"category": "stats"},
27+
},
28+
],
29+
"window_functions": [
30+
{
31+
"name": "h",
32+
"impls": [{"return": "i64"}],
33+
"metadata": {"category": "window"},
34+
},
35+
],
36+
}
37+
38+
extensions = build_simple_extensions(definitions)
39+
40+
assert extensions.metadata == {"author": "me", "version": 1}
41+
assert extensions.types[0].metadata == {"kind": "geometry"}
42+
assert extensions.scalar_functions[0].metadata == {"category": "math"}
43+
assert extensions.aggregate_functions[0].metadata == {"category": "stats"}
44+
assert extensions.window_functions[0].metadata == {"category": "window"}
45+
46+
47+
def test_metadata_defaults_to_none_when_absent():
48+
"""Metadata is optional and should default to None when not present."""
49+
extensions = build_simple_extensions({"urn": "extension:test:no-metadata"})
50+
51+
assert extensions.metadata is None

0 commit comments

Comments
 (0)