Found by the #1737 seam re-review's input-type probes; pre-existing (the crash site is untouched by #1737's diff and predates it).
Repro
import polars as pl, graphistry
nodes = pl.DataFrame({"id": [1, 2], "label__Person": [True, True]}).lazy() # LazyFrame nodes
edges = pl.DataFrame({"src": [1], "dst": [2], "type": ["KNOWS"]})
g = graphistry.nodes(nodes, "id").edges(edges, "src", "dst")
g.gfql("MATCH (a:Person)-[:KNOWS]-(b) RETURN b.id AS x", engine="polars")
# TypeError: expected `other` to be a 'LazyFrame', not 'DataFrame'
Matrix (undirected single-hop shape): lazy nodes + eager edges → crash; eager nodes + lazy edges → OK; lazy both → crash. Directed hops with LazyFrame inputs work fine.
Cause
_chain_traversal_polars's undirected single-hop node override (graphistry/compute/gfql/lazy/engine/polars/chain.py:~720):
_both = endpoint_ids(rev._edges, src, dst, node_col).unique(subset=[node_col])
rev = rev.nodes(g._nodes.join(_both, on=node_col, how="semi"), node_col)
g._nodes is the user's LazyFrame while _both is eager (or vice versa) — polars refuses mixed-laziness joins. Uncaught TypeError violates the parity-or-honest-NIE contract (should be a correct result or an NIE, never a crash).
Fix sketch
Normalize laziness at the join (_both.lazy() when g._nodes is a LazyFrame, or .lazy() both sides and keep the plan deferred). Add a lazy/eager input matrix test for the undirected shape.
Found by the #1737 seam re-review's input-type probes; pre-existing (the crash site is untouched by #1737's diff and predates it).
Repro
Matrix (undirected single-hop shape): lazy nodes + eager edges → crash; eager nodes + lazy edges → OK; lazy both → crash. Directed hops with LazyFrame inputs work fine.
Cause
_chain_traversal_polars's undirected single-hop node override (graphistry/compute/gfql/lazy/engine/polars/chain.py:~720):g._nodesis the user's LazyFrame while_bothis eager (or vice versa) — polars refuses mixed-laziness joins. UncaughtTypeErrorviolates the parity-or-honest-NIE contract (should be a correct result or an NIE, never a crash).Fix sketch
Normalize laziness at the join (
_both.lazy()wheng._nodesis a LazyFrame, or.lazy()both sides and keep the plan deferred). Add a lazy/eager input matrix test for the undirected shape.