Commit faf3184
* feat(gfql): native polars WITH...MATCH re-traversal reentry (IC6/IC11 core)
A MATCH re-traversing from a preceding WITH's projected/aggregated bindings previously
declined on polars ("could not recover carried node identities"). Fixes two pandas-only
gaps: the native projector now emits the _cypher_entity_projection_meta side-channel the
bounded-reentry executor reads to re-seed; the executor id-handling + seeded binding
pipeline are engine-aware (polars is_not_null/filter/order-preserving join; semi-join to
carried ids). RETURN entity/property/count/count(*)/DISTINCT over WITH->MATCH now native,
pandas-parity. Differential fuzz ~3500 graphs: 0 disagreements, 0 crashes. Scalar-column
carry + duplicate-id / cartesian-under-seed stay honest NIEs (were crashes/silent-wrong).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
* test(gfql): lower pandas-lane execution.py coverage floor 84.75->83.5
WITH...MATCH reentry added polars-specific branches to the shared reentry/execution.py.
Those are covered by the polars test lane (changed-line 100%) but unreachable by the
pandas core lane, which legitimately drops its per-file coverage to 83.81%. Lower the
pandas-lane floor to match; the polars branches keep real coverage via test-polars.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
* refactor(gfql): type reentry/projection helpers with SeriesT/DataFrameT, drop call-site casts (review)
Review feedback on #1751: the engine-agnostic reentry helpers were (s: Any) -> Any with
unchecked cast(SeriesT/DataFrameT, ...) at call sites. Now typed with the repo frame
aliases (SeriesT/DataFrameT; object for the type-guard); the genuinely-dynamic polars
branches carry a localized # type: ignore at the dispatch point instead of an opaque Any
return + caller cast -> the three call-site casts are removed. projection.py entity_meta
dict -> Dict[str, Dict[str, Any]]. mypy: 0 new errors; ruff clean; 19 reentry tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
* refactor(gfql): move engine-agnostic frame/series helpers to Engine.py
The reentry executor accumulated a cluster of generic pandas/cuDF/polars
dispatch helpers (null mask, series/frame filter, order-preserving left join,
constant-column assign, drop-columns, row-as-mapping, series-to-pylist) that
have no reentry semantics and belong with safe_merge / df_concat / df_unique in
the engine layer. gfql_unified.py had already re-implemented series_to_pylist,
proving the leak. Move the eight primitives to graphistry.Engine (public names,
no underscore), drop the reentry-local defs, and consolidate the duplicate onto
the more-defensive version. SeriesT/DataFrameT typing preserved via a
TYPE_CHECKING import + string annotations so Engine.py (imported very early)
never triggers graphistry.compute package init at runtime (would be circular).
No behavior change: byte-identical dispatch; reentry suite 19/19, cypher/entity
subset green, ruff clean, mypy-neutral.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
* test(engine): cover moved frame/series primitives; widen polars lane cov to graphistry
The frame-helper move added dispatch code to graphistry/Engine.py, whose polars
branches were exercised only via the reentry tests but NOT measured — the polars
lane covered only `--cov=graphistry/compute`, so Engine.py (outside compute/)
showed 0% on its polars branches and dragged changed-line coverage to 75%.
Fix both halves: (1) add a dedicated unit test for all nine primitives across
pandas and polars (polars cases guarded by _HAS_POLARS + registered in
POLARS_TEST_FILES) plus series_to_pylist's arrow/pandas/tolist fallbacks and
raise-paths; (2) widen the polars lane to `--cov=graphistry` (the #1727 pattern)
so Engine.py's polars branches are measured. Audit-safe: coverage_audit's polars
profile only enforces graphistry/compute/gfql/lazy/**, so Engine.py is not floored.
Reproduced the exact changed-line gate locally (combined core+gfql+polars
artifacts): 75.00% -> 98.96%, Engine.py changed lines 100%.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
* test(gfql): end-to-end parity for the seeded binding-rows WITH->MATCH path
The row_pipeline.py change (WITH re-entry seed for binding_rows_polars) was
covered only by direct-call unit tests asserting the seed is applied + the
decline branches; nothing drove a real cypher WITH->MATCH whose trailing MATCH
routes through the MULTI-ALIAS binding-table path (vs the single-alias hop path
the differential fuzz exercises). Add an e2e differential-parity test for a
two-fresh-alias trailing MATCH with a multi-alias RETURN, with a monkeypatch
guard asserting the seeded binding_rows path is actually hit so coverage can't
silently regress.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 4dd0daa commit faf3184
11 files changed
Lines changed: 743 additions & 79 deletions
File tree
- bin
- graphistry
- compute
- gfql
- cypher/reentry
- lazy/engine/polars
- tests
- compute/gfql
- coverage_baselines
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| |||
29 | 30 | | |
30 | 31 | | |
31 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
32 | 36 | | |
33 | 37 | | |
34 | 38 | | |
35 | 39 | | |
36 | | - | |
| 40 | + | |
37 | 41 | | |
38 | 42 | | |
39 | 43 | | |
| |||
42 | 46 | | |
43 | 47 | | |
44 | 48 | | |
45 | | - | |
| 49 | + | |
46 | 50 | | |
47 | 51 | | |
48 | 52 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
12 | 18 | | |
13 | 19 | | |
14 | 20 | | |
| |||
850 | 856 | | |
851 | 857 | | |
852 | 858 | | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
0 commit comments