Repository navigation
Conversation
rx.asset builds its URL with get_config(). Called at the top level of rxconfig.py, that started a second config load, which imported rxconfig.py again and recursed until RecursionError. While rxconfig.py is importing, _get_config() now returns the env and default config instead of importing it again, and get_config() does not cache that stand-in on the context. Signed-off-by: vjymisal0 <misalvijay153@gmail.com>
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
[Medium impact] The PR appears safe to merge; no blocking issues remain. SummaryPrevents
The earlier finding about generated setters is fixed. No new actionable issues were found. Reviews (4) · Last reviewed commit: "fix(config): restore state_auto_setters ..." · Reviewed by Greptile |
Merging this PR will degrade performance by 5.07%2 warnings
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing |
…nd-in Constructing the stand-in Config published its default state_auto_setters, replacing the value a Config created earlier in rxconfig.py had set. State classes defined later lost their generated setters. Restore the published value after building the stand-in. Signed-off-by: vjymisal0 <misalvijay153@gmail.com>
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
… fails The mid-import stand-in Config publishes its state_auto_setters before validation, so a ConfigError (e.g. redis mode without a redis URL) left that value in place. Restore the saved value in a finally block. Signed-off-by: vjymisal0 <misalvijay153@gmail.com>
Summary
Calling
rx.asset(...)at the top level ofrxconfig.pyraisesRecursionError.AssetPathStr.__new__callsget_config()to prependfrontend_path. During the first config load, the context has no config yet, soget_config()calls_get_config(). That popsrxconfigfromsys.modulesand imports it again (_load_config_lockis anRLock, so the same thread re-enters). The re-import callsrx.assetagain, and the loop continues until the stack overflows.Changes:
_get_config()sets_loading_configwhile it importsrxconfig.py(under_load_config_lock). If it is called again during that import, it returnsConfig(app_name="", _skip_plugins_checks=True)instead of importing the file again. This is the env and default config it already returns when norxconfig.pyexists.get_config()does not cache that stand-in on theRegistrationContext. Without this, a load through_get_config()directly (or the deprecated_load_config()) would leave the context holding the stand-in.Known limitation: an asset created in
rxconfig.pybeforerx.Config(...)runs only seesfrontend_pathfrom the environment (REFLEX_FRONTEND_PATH) or the default. It cannot see afrontend_pathpassed to therx.Config(...)call further down the same file, because that config does not exist yet.Verification
test_get_config_inside_rxconfig_does_not_reload_itintests/units/test_config.py:mainit fails withRecursionError.get_config()no-cache branch, it fails withassert ctx._config is None.ASSET = rx.asset("favicon.ico")aboverx.Config(...)) now loads and returns'/favicon.ico?v=e3b0c442'.uv run pytest tests/units/test_config.py: 160 passed.uv run pytest tests/units: 12348 passed, 17 failed. The same 17 fail onmainon my Windows machine:tests/units/assetsshared-asset symlink tests,test_create_resolves_shared_assetandtest_initialize_agents_md_handles_symlinked_claude. None of them are related to this change.ruff check,ruff format --checkandpyrightare clean on the changed files.packages/reflex-base/news/7669.bugfix.md.Closes #7669