Restore deprecated DECORATED_PAGES and get_config(reload=True) shims - #6985
Conversation
0.9.9a1 pre-release testing (FINDING-023, FINDING-008) found two 0.9.8 public names that #6382 removed outright, breaking downstream code with confusing errors: - `from reflex.page import DECORATED_PAGES` raised "ImportError: cannot import name 'DECORATED_PAGES' from 'PageNamespace' (unknown location)" (breaks the published reflex-enterprise flow demo at import). Because the page namespace class replaces the module in sys.modules, a plain module __getattr__ is never consulted, so the shim lives in a PageNamespaceMeta.__getattr__ that emits console.deprecate (0.9.9 -> 1.0) and returns a defaultdict mapping the app name to the active RegistrationContext's decorated_pages list, matching the 0.9.8 shape. - `get_config(reload=True)` raised a bare TypeError. The reload keyword is restored as a deprecated alias that warns and delegates to reload_config(). Also document two approved #6382/#6593 behavior changes in the changelog: a second bare rx.App() in one process now raises ReflexRuntimeError (use a fresh RegistrationContext/fork() for multiple apps), and supersedes-based on_load cancellation on navigation also cancels on_load handlers that are background tasks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EMjBXPozsNeQNSBZecNH8x
Greptile SummaryRestores compatibility shims for
Confidence Score: 5/5The PR appears safe to merge with no blocking failure remaining. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| reflex/page.py | Adds metaclass-based compatibility access for the context-local decorated-pages registry. |
| packages/reflex-base/src/reflex_base/config.py | Restores the deprecated reload argument and delegates truthy requests to reload_config(). |
| tests/units/test_page.py | Covers both deprecated page-registry import forms and unknown namespace attributes. |
| tests/units/test_config.py | Verifies deprecated reload delegation, warning behavior, and refreshed caching. |
Reviews (2): Last reviewed commit: "Merge branch 'main' into claude/rel-fix-..." | Re-trigger Greptile
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
All reported issues were addressed across 8 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
avoid racing threads caching different copies of the reloaded config Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
All Submissions:
Type of change
Changes To Core Features:
Defect
0.9.9a1 pre-release testing surfaced two 0.9.8 public names that #6382 removed outright, with no shim and confusing errors (FINDING-023 HIGH, FINDING-008 MEDIUM), plus two under-documented behavior changes (FINDING-009, FINDING-003):
from reflex.page import DECORATED_PAGESnow raisesImportError: cannot import name 'DECORATED_PAGES' from 'PageNamespace' (unknown location). This breaks the published reflex-enterprise flow demo at import (it builds its index page fromDECORATED_PAGES), and the error text gives no pointer to the replacement API.get_config(reload=True)now raises a bareTypeError: get_config() got an unexpected keyword argument 'reload'with no mention ofreload_config().Both worked on 0.9.8, and the repo's deprecation policy asks for a fallback path during deprecation.
Fix
reflex/page.py: since thePageNamespaceclass replaces the module insys.modules, a plain module__getattr__(PEP 562) would never be consulted; the shim lives in a newPageNamespaceMeta.__getattr__. ReadingDECORATED_PAGESemitsconsole.deprecate(deprecated 0.9.9, removed 1.0) and returns adefaultdict(list)mapping the app name to the activeRegistrationContext's livedecorated_pageslist — the exact 0.9.8 shape (dict[str, list[tuple[Callable, dict]]]), so 0.9.8-era access patterns likenext(iter(DECORATED_PAGES.values()))keep working. ATYPE_CHECKING-only declaration keeps the from-import resolvable for type checkers. Modeled on thebundled_librariesshims in Add deprecation shims for bundled_libraries module globals #6967.reflex_base/config.py:get_configregains its 0.9.8reload: bool = Falseparameter; passing a truthy value emitsconsole.deprecate(0.9.9 -> 1.0) and delegates toreload_config().get_config()without arguments is unchanged.news/6382.breaking.mddocuments that a second barerx.App()in one process now raisesReflexRuntimeError(use a freshRegistrationContext/fork()for multiple apps) and theDECORATED_PAGESmove with its deprecation shim;news/6593.bugfix.1.mddocuments that supersedes-basedon_loadcancellation on navigation also cancelson_loadhandlers that are background tasks (0.9.8 let them survive), while background tasks started from non-superseding events are unaffected. Deprecation fragments added for both shims.Test plan
Regression tests were written first and shown to fail on unfixed
mainwith the exact errors from the findings:tests/units/test_page.py::test_decorated_pages_shim_from_import— failed withImportError: cannot import name 'DECORATED_PAGES' from 'PageNamespace' (unknown location); now passes and asserts the mapping resolves to the active context'sdecorated_pagesand warns once.tests/units/test_page.py::test_decorated_pages_shim_module_attribute— covers thereflex.pagemodule-attribute form, the app-name key, and defaultdict behavior for unknown keys.tests/units/test_page.py::test_page_namespace_unknown_attribute_raises— unknown attributes still raiseAttributeErrornamingreflex.page.tests/units/test_config.py::test_get_config_reload_deprecated— failed withTypeError: get_config() got an unexpected keyword argument 'reload'; now passes and assertsget_config(reload=True)delegates toreload_config(), warns, caches the fresh config, and thatget_config()does not warn.Checks run locally:
uv run ruff check .anduv run ruff format .clean;uv run pyright reflex testsanduv run pyright packages/reflex-base/src/reflex_base/config.py0 errors;uv run pytest tests/units/test_page.py tests/units/test_config.py tests/units/test_app.py tests/units/reflex_base/test_registry.pyall pass (275 tests). Also manually verified both 0.9.8 import forms and the flow demo's exact access pattern end-to-end through thereflexnamespace.🤖 Generated with Claude Code
https://claude.ai/code/session_01EMjBXPozsNeQNSBZecNH8x
Generated by Claude Code