You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
python_remote: a callable named 'task' (the documented contract) raises a bare AssertionError; the verbatim docstring example raises IndentationError #1959
Category: bare-crash on valid/documented input + doc-vs-code divergence. Repro-backed on master (84be35fb3); no server needed (both failures happen before any HTTP call).
1. Passing a callable literally named task — the documented contract — raises a bare AssertionError
Every python_remote_* docstring says the code must define "a top-level function task(g: Plottable)", and the signature is code: Union[str, Callable[..., object]]. The branch that converts a callable to source only runs when the name is nottask (python_remote.py:100-106):
ifcallable(code):
ifcode.__name__!="task": # <-- inverted: the correct name is the one skippedcode_str=inspect.getsource(code)
code=code_str.replace(f"def {old_name}", "def task", 1)
assertcodeisnotNoneandisinstance(code, str), f"Expected code to be a string, received type: {type(code)}"
Repro:
deftask(g):
return {'n': len(g._edges)}
g.python_remote_json(task) # AssertionError: Expected code to be a string, received type: <class 'function'>defmytask(g):
return {'n': len(g._edges)}
g.python_remote_json(mytask) # works; sends " def task(g):\n return {'n': 1}\n"
So the only callable name that cannot be used is the one the documentation mandates, and the failure is an untyped AssertionError (which also disappears entirely under python -O, leaving a function object to be JSON-serialized).
Expected: accept a callable named task (skip the rename, keep the getsource conversion), or raise a typed error naming the limitation.
2. The verbatim docstring example raises IndentationError
The example that appears in all four python_remote_* docstrings (e.g. python_remote.py:85-97) passes an indented triple-quoted block:
code=''' from typing import Any, Dict from graphistry import Plottable def task(g: Plottable) -> Dict[str, Any]: return {'num_edges': len(g._edges)} '''validate_python_str(code)
# IndentationError: unexpected indent (<unknown>, line 2)
validate_python_str calls ast.parse(code) with no textwrap.dedent (python_remote.py:25). Anyone who copies the documented snippet, or who simply writes the triple-quoted literal inside a function body (universal Python style), gets a raw IndentationError from a validator whose job is to produce a good message.
Expected: textwrap.dedent(code) before parsing (and before sending), or a typed error explaining the indentation requirement.
3. INDICATIVE: the blanket 4-space re-indent mutates multi-line string literals in user code
python_remote.py:136-138 prepends 4 spaces to every line, including continuation lines inside triple-quoted literals:
in : 'def task(g):\n s = """line1\nline2"""\n return {"s": s}\n'
out: ' def task(g):\n s = """line1\n line2"""\n return {"s": s}\n '
The literal's value silently gains 4 leading spaces on line 2. Whether this survives depends on how the server un-indents (the comment calls it a "workaround parsing bug ... TODO remove when server updated"); a uniform 4-space dedent restores it, anything else does not. Not verifiable from the client — flagged INDICATIVE. If the server-side workaround is still needed, wrapping (if True:\n + indent) or an explicit AST-preserving transform avoids touching literals.
Found by the 2026-08 remote/over-the-wire amplification probe (first pass over this surface).
Activity
fix(remote): accept the task function name python_remote's own contra…