Skip to content

feat(bridge): resolve form_to_widget_html from the bridge namespace - #60

Open
silversurfer562 wants to merge 1 commit into
mainfrom
claude/bridge-widget-reexport
Open

feat(bridge): resolve form_to_widget_html from the bridge namespace#60
silversurfer562 wants to merge 1 commit into
mainfrom
claude/bridge-widget-reexport

Conversation

@silversurfer562

Copy link
Copy Markdown
Member

Summary

The two surface renderers were split across submodules — bridge.form_to_askuserquestion and widget.form_to_widget_html — so a caller reaching for one and then the other by submodule path got an ImportError that reads as "this renderer does not exist."

Hit live: following attune-ai's CLAUDE.md D21 rule (which names form_to_widget_html without naming its module), I imported from bridge because its sibling renderer lives there, concluded the function was missing from the package entirely, and fell back to the AskUserQuestion surface — then upgraded 0.7.0 → 0.8.0 chasing a version problem that did not exist.

Why __getattr__ and not a plain import

attune_forms.widget imports is_fully_inferred from bridge. A top-level re-export would therefore be a circular import, and it would invert the layering — the renderer builds on the bridge, not the reverse. The lazy accessor keeps that layering intact while making the renderer family reachable from one namespace.

A drift guard (test_bridge_has_no_module_level_widget_import) asserts the bridge module body contains no attune_forms.widget import, because collapsing the accessor into a normal import is the obvious future "simplification" and reintroduces the cycle.

Both renderers remain exported from the package root, which stays the preferred import path — the added test pins that too.

Receipts

  • Full suite: 814 passed
  • Four new tests: identity with widget.form_to_widget_html, both renderers at the package root, unknown attributes still raise AttributeError, and the laziness drift guard

🤖 Generated with Claude Code

The two surface renderers were split across submodules —
bridge.form_to_askuserquestion and widget.form_to_widget_html — so a
caller reaching for one and then the other by submodule path got an
ImportError that reads as "this renderer does not exist". Hit live
while following attune-ai CLAUDE.md D21, which names
form_to_widget_html without naming its module.

Served via a module __getattr__, not a top-level import:
attune_forms.widget imports is_fully_inferred from bridge, so hoisting
it would be a circular import AND would invert the layering (the
renderer builds on the bridge, not the reverse). A drift guard asserts
the bridge module body has no attune_forms.widget import, since
"simplifying" the accessor away is the obvious future regression.

Both renderers stay exported from the package root, which remains the
preferred import path.

814 tests pass.

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