Skip to content

Derive widget canvas metadata from NODE_SPEC - #50

Merged
d-chambers merged 1 commit into
mainfrom
refactor/spec-derived-metadata
Aug 13, 2026
Merged

Derive widget canvas metadata from NODE_SPEC#50
d-chambers merged 1 commit into
mainfrom
refactor/spec-derived-metadata

Conversation

@d-chambers

Copy link
Copy Markdown
Contributor

Description

The last structural decoupling item from the architecture review: every bundled widget re-declared the six canvas-metadata attributes (name, description, icon, category, keywords, priority) that its NODE_SPEC already carries. This PR makes the spec the single source:

  • ZugWidget.__init_subclass__'s existing spec derivation (_SPEC_DERIVED_ATTRS) now also covers the six metadata fields, filling them in only when the widget class doesn't declare its own — deliberate overrides still work.
  • The duplicate declarations are deleted from all 26 widgets (−171 lines). A pre-change sweep imported every derzug.widgets entry point and compared all six fields against the spec: zero mismatches, so nothing canvas-visible changes.
  • The shared test_node_spec_consistency now pins all six fields (previously only name), so any future widget/spec drift fails the widget's default test suite.

Also removes the unreachable "unmigrated widget" scaffolding from PatchMethodWidget: with every bundled widget declaring a node_spec + task factory, the generated-params-model fallback and the options_task_factory task built from widget-level method_name/call_style attributes could never run — and the four leftover method_name/call_style attrs on taper/detrend/analytic/ufunc_unary were dead. _OPTIONS subclasses must now declare their own node_spec (enforced with a clear TypeError), and get_task always goes through node_spec.build_task. The Qt-free build_params_model/options_task_factory remain where they belong — used by the node modules themselves.

CHANGELOG updated under Changed (breaking) for the external-subclass contract tightening.

Counterpart review: Codex CLI still rate-limited (resets Aug 8); adversarial self-review record in the untracked .scratch/review_spec_metadata.md (pre-change drift sweep, derivation-order check vs Orange discovery, AST-based deletion validation, and confirmation that the node modules still own the options machinery).

Checklist

I have (if applicable):

  • referenced the GitHub issue this PR closes.
  • documented new behavior with docstrings and a CHANGELOG entry.
  • included tests (test_node_spec_consistency now asserts all six metadata fields across every widget's default suite).
  • run prek run --all-files and pytest tests (2114 passed, 44 skipped; all 10 hooks pass — staged before linting this time).
  • for hot-path changes, run python scripts/bench_compare.py --baseline main. (n/a — class-creation-time attribute copies; no executed path changes)

Every bundled widget re-declared the six canvas-metadata attributes
(name, description, icon, category, keywords, priority) its NODE_SPEC
already carries. Extend ZugWidget.__init_subclass__'s spec derivation to
cover them and delete the duplicates from all 26 widgets (-171 lines).
A pre-change sweep confirmed zero widget/spec mismatches, so no
canvas-visible value changes; the shared test_node_spec_consistency now
pins all six fields (previously only name) so drift is caught if a
widget overrides one.

Also remove the unreachable unmigrated-widget scaffolding from
PatchMethodWidget: every bundled widget declares a node_spec with a task
factory, so the generated-params-model fallback and the task built from
widget-level method_name/call_style attributes could never run. Those
four leftover widget attrs (taper, detrend, analytic, ufunc_unary) were
dead. _OPTIONS subclasses must now declare their own node_spec;
get_task always goes through node_spec.build_task.
@d-chambers
d-chambers merged commit 3380aab into main Aug 13, 2026
9 checks passed
@d-chambers
d-chambers deleted the refactor/spec-derived-metadata branch August 13, 2026 15:11
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