Restore deprecated DECORATED_PAGES and get_config(reload=True) shims
All Submissions:
- Have you followed the guidelines stated in CONTRIBUTING.md file?
- Have you checked to ensure there aren't any other open Pull Requests for the desired changed?
Type of change
- Bug fix (non-breaking change which fixes an issue)
- This change requires a documentation update
Changes To Core Features:
- Have you added an explanation of what your changes do and why you'd like us to include them?
- Have you written new tests for your core changes, as applicable?
- Have you successfully ran tests with your changes locally?
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 #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 fragments for the two approved documentation decisions:
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 main with 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 . and uv run ruff format . clean; uv run pyright reflex tests and uv run pyright packages/reflex-base/src/reflex_base/config.py 0 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.py all pass (275 tests). Also manually verified both 0.9.8 import forms and the flow demo's exact access pattern end-to-end through the reflex namespace.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EMjBXPozsNeQNSBZecNH8x
Generated by Claude Code