feat(bridge): resolve form_to_widget_html from the bridge namespace - #60
Open
silversurfer562 wants to merge 1 commit into
Open
feat(bridge): resolve form_to_widget_html from the bridge namespace#60silversurfer562 wants to merge 1 commit into
silversurfer562 wants to merge 1 commit into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The two surface renderers were split across submodules —
bridge.form_to_askuserquestionandwidget.form_to_widget_html— so a caller reaching for one and then the other by submodule path got anImportErrorthat reads as "this renderer does not exist."Hit live: following attune-ai's
CLAUDE.mdD21 rule (which namesform_to_widget_htmlwithout naming its module), I imported frombridgebecause 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 importattune_forms.widgetimportsis_fully_inferredfrombridge. 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 noattune_forms.widgetimport, 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
widget.form_to_widget_html, both renderers at the package root, unknown attributes still raiseAttributeError, and the laziness drift guard🤖 Generated with Claude Code