Conversation
Replace 6 separate recursive tree walks (_get_all_imports, _get_all_hooks, _get_all_custom_code, _get_all_dynamic_imports, _get_all_refs, _get_all_app_wrap_components) with a single collect_component_tree_artifacts walk that gathers all compilation data in one pass. Wire the new collector into app.py, compiler.py, and utils.py. Add CompilerPlugin protocol, CompilerHooks dispatcher, and BaseContext/ PageContext/CompileContext types as foundations for the async plugin pipeline.
Refactor the monolithic plugins.py into a plugins/ package: - base.py: core framework (CompilerPlugin base class, CompilerHooks, contexts) - builtin.py: concrete plugins matching legacy recursive collectors - __init__.py: re-exports all public names Adds ApplyStylePlugin, DefaultPagePlugin, and Consolidate*Plugin classes that replicate legacy page compilation behavior. Expands test coverage with per-plugin verification and full pipeline integration tests.
Greptile SummaryThis PR introduces a new compiler plugin infrastructure ( Key changes:
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant CC as CompileContext
participant CH as CompilerHooks
participant P1 as DefaultPagePlugin
participant P2 as ApplyStylePlugin
participant P3 as Consolidate*Plugins
CC->>CH: eval_page(page_fn, page=page)
CH->>P1: eval_page(page_fn) → PageContext
P1-->>CH: PageContext(name, route, root_component)
CH-->>CC: PageContext
CC->>CC: async with page_ctx
CC->>CH: compile_component(root_component)
Note over CH,P3: Pre-child phase (anext each plugin)
CH->>P2: compile_component(comp) → yield pre_replacement
CH->>P3: compile_component(comp) → yield pre_replacement
Note over CH: Recurse into structural children
CH->>CH: _compile_children(structural_children)
CH->>CH: traverse prop components (in_prop_tree=True)
Note over CH,P3: Post-child phase (asend each plugin in reverse)
CH->>P3: asend((compiled_comp, compiled_children))
CH->>P2: asend((compiled_comp, compiled_children))
CH-->>CC: compiled root component
CC->>CH: compile_page(page_ctx)
CH->>P3: compile_page(page_ctx) [e.g. ConsolidateImportsPlugin collapses imports]
CC->>CC: compiled_pages[route] = page_ctx
|
| if type(comp)._add_style != Component._add_style: | ||
| msg = "Do not override _add_style directly. Use add_style instead." | ||
| raise UserWarning(msg) |
There was a problem hiding this comment.
UserWarning raised as exception instead of warnings.warn
raise UserWarning(msg) raises UserWarning as an exception, which will abort compilation with an unhandled UserWarning. The conventional pattern for user-facing developer warnings is warnings.warn(msg, UserWarning, stacklevel=2), which emits the warning but allows compilation to continue.
If hard-failing is intentional, use a more semantically appropriate exception like TypeError or RuntimeError — raising UserWarning as an exception is confusing and unexpected for callers.
| if type(comp)._add_style != Component._add_style: | |
| msg = "Do not override _add_style directly. Use add_style instead." | |
| raise UserWarning(msg) | |
| if type(comp)._add_style != Component._add_style: | |
| import warnings | |
| msg = "Do not override _add_style directly. Use add_style instead." | |
| warnings.warn(msg, UserWarning, stacklevel=2) |
All Submissions:
Type of change
Please delete options that are not relevant.
New Feature Submission:
Changes To Core Features:
closes #6211