Background
reflex_base.utils.console and reflex_base.utils.log each define their own deprecate, plus their own private copies of the three frame-walking helpers it depends on. They are independent objects with separate dedupe state, not aliases.
The ENG-10963 series moved Reflex onto a stdlib logging pipeline:
Part 1 wrote a fresh deprecate into log.py rather than moving it, and nothing has been pointed at it since. #6867 enumerated exactly which helpers were retired (debug, info, success, log, warn, error, timing), and console.py's module docstring lists print, rule, status, ask, progress as remaining first-class. deprecate is in neither list, so it was never migrated and never shimmed. There is no TODO tracking it.
Current state
|
console.deprecate |
log.deprecate |
| Call sites in this repo |
19 |
0 (its own tests only) |
| Dedupe |
module-level _EMITTED_DEPRECATION_WARNINGS set |
shared dedupe_once |
| Output |
rich markup via console.print, plus log file |
reflex.deprecation logger with structured extras, supports JSON mode |
Duplicated between the two modules:
_exclude_paths_from_frame_info console.py:301 log.py:748
_is_framework_filename console.py:343 log.py:790
_get_first_non_framework_frame console.py:370 log.py:817
deprecate console.py:378 log.py:828
console.deprecate is the one that runs in production. log.deprecate is the intended destination and is currently dead outside tests/units/reflex_base/utils/test_log.py.
Why it is worth doing
Every fix to the deprecation machinery has to be written twice. That just happened. A follow-up to #7138 fixed deprecation warnings reporting a bracketed pseudo-location instead of the user's file (<string> for a generated dataclass __init__, <frozen importlib._bootstrap> while an import runs). The same patch had to go into both copies: into console.py to fix the live behaviour, and into log.py so the bug would not reappear the moment the migration finishes.
Consolidating also gives every deprecation in the framework the structured JSON output that only log.deprecate emits today.
Proposed change
- Make
console.deprecate a thin delegate to log.deprecate.
- Delete
console.py's copies of the three frame helpers.
- Keep
console.deprecate as a delegating alias rather than removing it. Both modules are re-exported wholesale (reflex/utils/console.py and reflex/utils/log.py each do from reflex_base.utils.X import *), so reflex.utils.console.deprecate is public API and may have downstream callers.
Migrating the 19 in-repo call sites to log.deprecate afterwards is optional and separable; it is not required for the dedup.
Things to watch
- Dedupe state diverges. The two use different stores.
tests/units/test_state.py:1930 reaches into console._EMITTED_DEPRECATION_WARNINGS directly and will need updating.
console._shim_deprecation (console.py:73) calls the module-local deprecate, so it picks up the change automatically. Confirm the legacy-helper shims still warn once.
- Terminal output. Both render a
DeprecationWarning: ... line, but console.deprecate currently adds rich [yellow] markup and does its own log-file write. Confirm a normal reflex run looks unchanged.
Acceptance criteria
- One implementation of
deprecate and of the three frame helpers.
console.deprecate still works and still warns once per call site.
- Existing deprecation tests pass, including the JSON-mode assertions in
test_log.py.
Background
reflex_base.utils.consoleandreflex_base.utils.logeach define their owndeprecate, plus their own private copies of the three frame-walking helpers it depends on. They are independent objects with separate dedupe state, not aliases.The ENG-10963 series moved Reflex onto a stdlib logging pipeline:
reflex_base.utils.log(1/5)Part 1 wrote a fresh
deprecateintolog.pyrather than moving it, and nothing has been pointed at it since. #6867 enumerated exactly which helpers were retired (debug,info,success,log,warn,error,timing), andconsole.py's module docstring listsprint,rule,status,ask,progressas remaining first-class.deprecateis in neither list, so it was never migrated and never shimmed. There is no TODO tracking it.Current state
console.deprecatelog.deprecate_EMITTED_DEPRECATION_WARNINGSsetdedupe_onceconsole.print, plus log filereflex.deprecationlogger with structured extras, supports JSON modeDuplicated between the two modules:
console.deprecateis the one that runs in production.log.deprecateis the intended destination and is currently dead outsidetests/units/reflex_base/utils/test_log.py.Why it is worth doing
Every fix to the deprecation machinery has to be written twice. That just happened. A follow-up to #7138 fixed deprecation warnings reporting a bracketed pseudo-location instead of the user's file (
<string>for a generated dataclass__init__,<frozen importlib._bootstrap>while an import runs). The same patch had to go into both copies: intoconsole.pyto fix the live behaviour, and intolog.pyso the bug would not reappear the moment the migration finishes.Consolidating also gives every deprecation in the framework the structured JSON output that only
log.deprecateemits today.Proposed change
console.deprecatea thin delegate tolog.deprecate.console.py's copies of the three frame helpers.console.deprecateas a delegating alias rather than removing it. Both modules are re-exported wholesale (reflex/utils/console.pyandreflex/utils/log.pyeach dofrom reflex_base.utils.X import *), soreflex.utils.console.deprecateis public API and may have downstream callers.Migrating the 19 in-repo call sites to
log.deprecateafterwards is optional and separable; it is not required for the dedup.Things to watch
tests/units/test_state.py:1930reaches intoconsole._EMITTED_DEPRECATION_WARNINGSdirectly and will need updating.console._shim_deprecation(console.py:73) calls the module-localdeprecate, so it picks up the change automatically. Confirm the legacy-helper shims still warn once.DeprecationWarning: ...line, butconsole.deprecatecurrently adds rich[yellow]markup and does its own log-file write. Confirm a normalreflex runlooks unchanged.Acceptance criteria
deprecateand of the three frame helpers.console.deprecatestill works and still warns once per call site.test_log.py.