Summary
Lambda functions in filter_dict (e.g., n({"score": lambda x: (x > 50) & (x % 2 == 0)})) were removed when AST validation was tightened to require JSON-serializable values for the wire protocol and remote execution.
This is a regression for local-only workflows where serialization isn't needed. Lambdas were a convenient way to express compound conditions that don't map cleanly to a single predicate.
RCA
The check at graphistry/compute/ast.py:167 rejects any filter_dict value that isn't an ASTPredicate or JSON-serializable. Lambdas/callables fail this check.
The reason is wire protocol: filter_dict values need to round-trip through JSON for to_json() / from_json() and remote execution via gfql_remote().
Proposed
For local-only execution (g.gfql([...]), not g.gfql_remote([...])), allow callables in filter_dict:
- Accept
callable values at AST construction time (skip the JSON-serializable check)
- In
filter_by_dict(), apply callables directly: df[df[col].apply(val)]
- Raise at serialization time (
to_json()) if a callable is present, not at construction time
This preserves the wire protocol constraint while restoring local usability.
Current workaround
# Instead of: n({"score": lambda x: (x > 50) & (x % 2 == 0)})
# Use query string:
n(query="score > 50 and score % 2 == 0")
Summary
Lambda functions in
filter_dict(e.g.,n({"score": lambda x: (x > 50) & (x % 2 == 0)})) were removed when AST validation was tightened to require JSON-serializable values for the wire protocol and remote execution.This is a regression for local-only workflows where serialization isn't needed. Lambdas were a convenient way to express compound conditions that don't map cleanly to a single predicate.
RCA
The check at
graphistry/compute/ast.py:167rejects anyfilter_dictvalue that isn't anASTPredicateor JSON-serializable. Lambdas/callables fail this check.The reason is wire protocol:
filter_dictvalues need to round-trip through JSON forto_json()/from_json()and remote execution viagfql_remote().Proposed
For local-only execution (
g.gfql([...]), notg.gfql_remote([...])), allow callables infilter_dict:callablevalues at AST construction time (skip the JSON-serializable check)filter_by_dict(), apply callables directly:df[df[col].apply(val)]to_json()) if a callable is present, not at construction timeThis preserves the wire protocol constraint while restoring local usability.
Current workaround