Skip to content

🐛 Keep an explicitly assigned empty namespace at collection - #170

Open
elinscott wants to merge 1 commit into
scinode:mainfrom
elinscott:fix/keep-empty-namespace-assignment
Open

elinscott wants to merge 1 commit into
scinode:mainfrom
elinscott:fix/keep-empty-namespace-assignment

Conversation

@elinscott

Copy link
Copy Markdown
Collaborator

Problem

from typing import Annotated

from node_graph import namespace, task


@task.graph()
def my_graph(data: Annotated[dict, namespace(x=int)]) -> dict:
    return {}


my_graph.build(data={})
# TypeError: my_graph() missing 1 required positional argument: 'data'

The error is wrong: the caller passed data explicitly; the error says they didn't.

The mechanism: TaskSocketNamespace._collect_values kept a child namespace only if its collected dict was truthy, so an assigned-but-empty namespace was indistinguishable from a never-assigned one by the time the graph body was called.

Changes

  • A namespace remembers that a dict was assigned to it (_explicitly_assigned, set by _set_socket_value), and _collect_values keeps it even when it collects to nothing — the body now receives {}.

Testing

  • The example above builds; a populated namespace still collects its members (control in the same test).
  • Reverting the _collect_values change fails exactly the new test; the full suite passes (310) with it in place.

An empty dict assigned to a namespace input vanished during value
collection, so the graph body was called without the argument and the
caller saw a missing-argument TypeError instead of the input check's
missing-member report.

- A namespace remembers that a dict was assigned to it, and
  _collect_values keeps it even when it collects to nothing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.70%. Comparing base (8d85e61) to head (adc405f).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #170      +/-   ##
==========================================
+ Coverage   89.68%   89.70%   +0.02%     
==========================================
  Files          81       81              
  Lines        8984     8996      +12     
==========================================
+ Hits         8057     8070      +13     
+ Misses        927      926       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

elinscott added a commit to elinscott/node-graph that referenced this pull request Aug 12, 2026
The stored-ref review's fuller report (arrived after the earlier merge
and test commits) flagged a second shape of the same bug: a required
namespace nested INSIDE an explicitly-assigned-empty parent used to
survive collection too, via the same required-based keep_empty rule
this branch dropped in favor of scinode#170's assigned-based one — visible
as `"codes" in config` silently flipping False to True with no
assignment to `codes` anywhere.

Already fixed by dropping keep_empty; this commit only locks it in
with a regression test, following the file's own established pattern
of a module-level reporting graph body (a locally-nested one does not
reliably share SEEN across the cloudpickle re-import).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant