Repository navigation
gfql polars: the plain single-hop chain branch ignores prune_to_endpoints (pandas keeps only the arrival side) #2053
Description
Activity
Scope update from the route harness (#2061): the divergence is not only the plain single-hop branch. With every hot path declined (
GFQL_ROUTES_OFF=all, pygraphistry's test-side route switch), the polars general traversal returns the same rows as the plain branch, so the polars engine as a whole ignoresprune_to_endpointswhile pandas keeps only the arrival side.Probe on the issue's frames (
[n({"key": 1}), e_forward(prune_to_endpoints=True), n()]):path nodes edges pandas lane [2, 3] [] pandas general [2, 3] [] polars lane [1, 2, 3] [(1,2), (1,3)] polars general [1, 2, 3] [(1,2), (1,3)] Unseeded
[n(), e_forward(prune_to_endpoints=True), n()]: pandas general [1, 2, 3, 5], polars general [1, 2, 3, 4, 5] (plus the (4,5) edge).So declining the shape in
polars_plain_single_hop_admitswould only move the wrong answer from the lane to the full path. The fix is the arrival-side contract in the polars chain itself (or a typed decline until it exists). The harness pins this as a strict expected failure onpolars-plainkeyed by tag#2053(routes corpus + the pandas_BYPASS_SHAPESprune rows), so it flips when fixed.- added 10 commits that reference this issue
on Sep 6, 2026 2 remaining items
- added 13 commits that reference this issue
on Sep 6, 2026 Closing: fixed by #2065. Its "Closes #2053" did not fire because the PR merged into a stacked base (
fix/gfql-2058-general-path-int-dtypes) and the stack was re-landed under new SHAs, so GitHub never saw it reach master; the content is on master —test_prune_to_endpoints_is_a_typed_decline_on_polars_and_served_on_pandasand theprune_to_endpointsadmission guard inchain_specializations/admission.py. Polars declines single-hopprune_to_endpointswith a typed error instead of ignoring it.
Summary
Route-level sibling found while hoisting the chain admission predicates: the pandas/cuDF chain fast path declines
prune_to_endpoints=True("prune keeps only the arrival side → full path"), but the polars chain's plain single-hop branch admits the shape and returns both endpoints plus the edges, so polars and pandas disagree.Repro
Unseeded
[n(), e_forward(prune_to_endpoints=True), n()]: pandas[1, 2, 3, 5], polars[1, 2, 3, 4, 5].Expected
Either the polars plain branch declines
prune_to_endpointslike the pandas gate (polars_plain_single_hop_admitsis the single place to do it once the predicate refactor lands) or it implements the arrival-side contract; both engines must agree.Pins
A strict-xfail parity pin lives in
graphistry/tests/compute/gfql/lazy/engine/polars/test_chain_admission.pyover the shared route corpus and flips when this is fixed.