Commit 32abb94
Review asked whether `clear_row_exec_context` should RESTORE the value the graph
carried on entry rather than NULLing it — a fair question, because
`attach_row_exec_context` INHERITS on the way in (a `None` argument keeps what
`g` already carries), so an outer scope's value can reach an inner execution and
be dropped by it.
Determination: NULL is correct and restore would reintroduce #1786. Three
reasons, each now carried by a test rather than by argument:
1. `clear` is PURE. It returns `g.bind()` and never writes through to the
object it was handed, so an outer scope that set the field still has it
afterwards. There is no caller state to save. That is exactly what
separates this from #1786, which WAS an in-place write onto the caller's
own graph — restore is the fix for a mutation, and there is no mutation.
2. The only channel restore would change is the RETURN VALUE, and putting the
seed back there IS the second half of #1786 ("the result of a WITH query
carries the seed, and a follow-up query on that result is answered against
it"). Measured: hand-restoring the seed onto a result changes the answer of
the next query on it (7 -> 2 -> 1 rows).
3. No execution frame inherits a context it did not set. Instrumenting
`attach` over `graphistry/tests/compute` recorded 3907 calls and ZERO
inheriting ones. 53 DID enter on a graph already carrying a seed (nested
boundary frames) but each was handed the IDENTICAL `start_nodes` parameter,
so the frame still owns what it sets. The cross-segment WITH seed travels
as the explicit `start_nodes` PARAMETER (`chain_impl(..., start_nodes=)`,
`_compiled_query_reentry_state`), never through the graph field, so the
field's lifetime is exactly one boundary-call run.
`test_exec_context_scoping.py` re-runs that ownership measurement as an
assertion over a corpus of the shapes that reach every attach site, so a future
path that starts relying on inheritance reopens this decision loudly instead of
silently losing an outer value.
MUTATION-CHECKED IN THE DECIDING DIRECTION: implementing save/restore at all
three attach sites (chain, native polars chain, gfql_unified) fails 4 of the new
tests on every runnable engine — while the existing #1793 suite
(`test_reentry_caller_graph_immutability.py`) passes UNCHANGED. Those tests
could not distinguish the two designs; this file can, which is why it exists.
Engine-parametrized over pandas/polars/cuDF/polars-gpu with a fixed engine list
plus a runtime probe (not `available_nonpandas_engines()`, which silently
shrinks): a non-runnable engine reports SKIPPED, it does not vanish from the
report. Also added to `bin/test-polars.sh` — the file has no module-level
`importorskip`, so nothing would otherwise have flagged that its polars params
run in no lane (#1795 class).
RUNTIME DELTA: zero. No production line changed; the only non-test edits are the
`clear_row_exec_context` docstring and a CHANGELOG entry, so no pyg-bench lane
run is required (CB5).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015YsqAZQLbqjSDrYSFz2GoB
1 parent 49db91c commit 32abb94
4 files changed
Lines changed: 336 additions & 0 deletions
File tree
- bin
- graphistry
- compute/gfql
- tests/compute/gfql
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
28 | 31 | | |
29 | 32 | | |
30 | 33 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
51 | 74 | | |
52 | 75 | | |
53 | 76 | | |
| |||
0 commit comments