Skip to content

Commit c257996

Browse files
lmeyerovclaude
andcommitted
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
1 parent 1ff5d44 commit c257996

2 files changed

Lines changed: 24 additions & 20 deletions

File tree

graphistry/compute/gfql/cypher/reentry/execution.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# ruff: noqa: E501
33
from __future__ import annotations
44

5-
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union, cast
5+
from typing import Any, Dict, List, Mapping, Optional, Sequence, Tuple, Union, cast
66

77
from graphistry.Engine import EngineAbstract, df_concat, df_cons, resolve_engine, safe_merge
88
from graphistry.Plottable import Plottable
@@ -23,36 +23,40 @@
2323
from graphistry.Engine import is_polars_df as _is_polars_df
2424

2525

26-
def _series_is_series_like(s: Any) -> bool:
26+
def _series_is_series_like(s: object) -> bool:
2727
"""True for a pandas/cuDF Series (``.dropna``) or a polars Series (module check).
2828
2929
The reentry executor recovers carried node identities from a projection-meta ``ids`` Series
3030
that is pandas under ``engine='pandas'`` and polars under ``engine='polars'``; both are valid."""
3131
return hasattr(s, "dropna") or _is_polars_df(s)
3232

3333

34-
def _series_not_null_mask(s: Any) -> Any:
34+
# The four helpers below are engine-agnostic (pandas/cuDF/polars); `SeriesT`/`DataFrameT` are the
35+
# repo's frame aliases (pandas types for mypy). The polars branches genuinely return polars objects
36+
# mypy can't narrow to the alias, so the suppression lives here at the dispatch point — callers get
37+
# a clean `SeriesT`/`DataFrameT` contract with no cast().
38+
def _series_not_null_mask(s: SeriesT) -> SeriesT:
3539
"""Non-null boolean mask, engine-aware (polars ``is_not_null`` vs pandas ``notna``)."""
3640
if _is_polars_df(s):
37-
return s.is_not_null()
41+
return s.is_not_null() # type: ignore[attr-defined,no-any-return]
3842
return s.notna()
3943

4044

41-
def _series_filter(s: Any, mask: Any) -> Any:
45+
def _series_filter(s: SeriesT, mask: SeriesT) -> SeriesT:
4246
"""Filter a Series by a boolean mask, engine-aware, dropping the old index (pandas)."""
4347
if _is_polars_df(s):
44-
return s.filter(mask)
48+
return s.filter(mask) # type: ignore[attr-defined,no-any-return]
4549
return s[mask].reset_index(drop=True)
4650

4751

48-
def _frame_filter(df: Any, mask: Any) -> Any:
52+
def _frame_filter(df: DataFrameT, mask: SeriesT) -> DataFrameT:
4953
"""Filter a DataFrame's rows by a boolean mask, engine-aware, dropping the old index."""
5054
if _is_polars_df(df):
51-
return df.filter(mask)
55+
return df.filter(mask) # type: ignore[attr-defined,no-any-return]
5256
return df.loc[mask].reset_index(drop=True)
5357

5458

55-
def _ordered_left_join(left: Any, right: Any, *, on: str) -> Any:
59+
def _ordered_left_join(left: DataFrameT, right: DataFrameT, *, on: str) -> DataFrameT:
5660
"""Left join preserving ``left`` row order, engine-aware. Polars ``.merge`` does not exist;
5761
``safe_merge`` (pandas/cuDF ``.merge``) cannot run on polars frames, so branch to
5862
``.join(..., maintain_order='left')`` which pins the WITH-row ordering the reentry seed needs.
@@ -64,25 +68,25 @@ def _ordered_left_join(left: Any, right: Any, *, on: str) -> Any:
6468
from graphistry.Engine import Engine, df_to_engine
6569
if not _is_polars_df(right):
6670
right = df_to_engine(right, Engine.POLARS)
67-
return left.join(right, on=on, how="left", maintain_order="left")
71+
return left.join(right, on=on, how="left", maintain_order="left") # type: ignore[call-arg,no-any-return]
6872
return safe_merge(left, right, on=on, how="left")
6973

7074

71-
def _reentry_row(prefix_rows: Any, row_index: int) -> Any:
75+
def _reentry_row(prefix_rows: DataFrameT, row_index: int) -> Mapping[str, Any]:
7276
"""One prefix row as a col->scalar mapping, engine-aware (``row[col]`` works for
7377
both the pandas Series and the polars named-row dict)."""
7478
if _is_polars_df(prefix_rows):
75-
return prefix_rows.row(row_index, named=True)
79+
return prefix_rows.row(row_index, named=True) # type: ignore[attr-defined,no-any-return]
7680
return prefix_rows.iloc[row_index]
7781

7882

79-
def _assign_constant_columns(df: Any, values: Dict[str, Any]) -> Any:
83+
def _assign_constant_columns(df: DataFrameT, values: Dict[str, Any]) -> DataFrameT:
8084
"""Broadcast scalar ``values`` as constant columns, engine-aware."""
8185
if not values:
8286
return df
8387
if _is_polars_df(df):
8488
import polars as pl
85-
return df.with_columns([pl.lit(v).alias(k) for k, v in values.items()])
89+
return df.with_columns([pl.lit(v).alias(k) for k, v in values.items()]) # type: ignore[attr-defined,no-any-return]
8690
return df.assign(**values)
8791

8892

@@ -552,10 +556,10 @@ def aligned_reentry_rows(
552556
)
553557

554558
non_null_mask = _series_not_null_mask(ids)
555-
carried_ids = cast(SeriesT, _series_filter(ids, non_null_mask))
559+
carried_ids = _series_filter(ids, non_null_mask)
556560
if prefix_rows is None:
557561
return carried_ids, None
558-
return carried_ids, cast(DataFrameT, _frame_filter(prefix_rows, non_null_mask))
562+
return carried_ids, _frame_filter(prefix_rows, non_null_mask)
559563

560564

561565
def reentry_carry_payload(
@@ -589,4 +593,4 @@ def ordered_reentry_start_nodes(
589593
id_column: str,
590594
) -> DataFrameT:
591595
# MATCH re-entry must preserve the WITH row order, not the base node-table order.
592-
return cast(DataFrameT, _ordered_left_join(carried_node_ids, node_rows, on=id_column))
596+
return _ordered_left_join(carried_node_ids, node_rows, on=id_column)

graphistry/compute/gfql/lazy/engine/polars/projection.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"""
1111
from __future__ import annotations
1212

13-
from typing import TYPE_CHECKING, Any, List, Optional
13+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
1414

1515
from graphistry.Plottable import Plottable
1616

@@ -133,7 +133,7 @@ def _flat_entity_exprs_polars(rows_df: pl.DataFrame, projection: ResultProjectio
133133

134134

135135
def _record_entity_meta(
136-
entity_meta: dict,
136+
entity_meta: Dict[str, Dict[str, Any]],
137137
rows_df: pl.DataFrame,
138138
projection: ResultProjectionPlan,
139139
source_alias: str,
@@ -167,7 +167,7 @@ def _try_native_projection(result: Plottable, rows_df: pl.DataFrame, projection:
167167
# pandas projector (result_postprocess._apply_result_projection_pandas), which records the
168168
# carried alias's id column so the bounded-reentry executor can recover carried node
169169
# identities. Without it a WITH-projected node alias feeding a trailing MATCH declines.
170-
entity_meta: dict = {}
170+
entity_meta: Dict[str, Dict[str, Any]] = {}
171171
id_column = result._node
172172
for column in projection.columns:
173173
if column.kind == "whole_row":

0 commit comments

Comments
 (0)