examples/narwhals_example.py fails on main. The narwhals expression layer still passes the legacy extension filename where the registry now expects an extension URN, so any narwhals expression that resolves a function raises Unknown function.
Reproduction
uv run examples/narwhals_example.py
Exception: Unknown function abs for [i64 {
nullability: NULLABILITY_REQUIRED
}
]
Triggered by examples/narwhals_example.py:33 — nw.col("id").abs().
Root cause
src/substrait/narwhals/expression.py:20 passes a YAML filename as the URN:
self.expr = scalar_function(
"functions_arithmetic.yaml", "abs", expressions=[self.expr]
)
but the registry keys on URNs:
>>> r.has_urn("functions_arithmetic.yaml")
False
>>> r.has_urn("extension:io.substrait:functions_arithmetic")
True
The overload itself is fine — lookup_function("extension:io.substrait:functions_arithmetic", "abs", [i64]) resolves abs:i64 — so this is purely the URN argument. It is the only remaining *.yaml literal in src/substrait/narwhals/, so the narwhals layer appears to have been missed when the registry moved to URNs.
Why CI does not catch it
.github/workflows/example.yml runs only builder_example.py, duckdb_example.py, adbc_example.py and pyarrow_example.py. narwhals_example.py and dataframe_example.py are outside that matrix — which CONTRIBUTING.md notes means they have to be run by hand. Of the two, dataframe_example.py currently passes and narwhals_example.py does not. Adding both to the matrix would stop this regressing silently.
Affected versions
Measured on main at 4c0aebb (substrait.version.substrait_version → 0.99.0). Pre-existing, not a recent regression.
examples/narwhals_example.pyfails onmain. The narwhals expression layer still passes the legacy extension filename where the registry now expects an extension URN, so any narwhals expression that resolves a function raisesUnknown function.Reproduction
Triggered by
examples/narwhals_example.py:33—nw.col("id").abs().Root cause
src/substrait/narwhals/expression.py:20passes a YAML filename as the URN:but the registry keys on URNs:
The overload itself is fine —
lookup_function("extension:io.substrait:functions_arithmetic", "abs", [i64])resolvesabs:i64— so this is purely the URN argument. It is the only remaining*.yamlliteral insrc/substrait/narwhals/, so the narwhals layer appears to have been missed when the registry moved to URNs.Why CI does not catch it
.github/workflows/example.ymlruns onlybuilder_example.py,duckdb_example.py,adbc_example.pyandpyarrow_example.py.narwhals_example.pyanddataframe_example.pyare outside that matrix — whichCONTRIBUTING.mdnotes means they have to be run by hand. Of the two,dataframe_example.pycurrently passes andnarwhals_example.pydoes not. Adding both to the matrix would stop this regressing silently.Affected versions
Measured on
mainat4c0aebb(substrait.version.substrait_version→ 0.99.0). Pre-existing, not a recent regression.