Skip to content

support async context for mutable proxies#6691

Open
harsh21234i wants to merge 7 commits into
reflex-dev:mainfrom
harsh21234i:fix/mutable-proxy-async-context-6689
Open

support async context for mutable proxies#6691
harsh21234i wants to merge 7 commits into
reflex-dev:mainfrom
harsh21234i:fix/mutable-proxy-async-context-6689

Conversation

@harsh21234i

Copy link
Copy Markdown

Fixes #6689

Summary

  • add async context-manager support to MutableProxy and
    ImmutableMutableProxy
  • refresh the proxy from its bound state field after entering the state
    context
  • cover ImmutableMutableProxy mutation through async with proxy

Testing

  • uv run pytest tests/units/
    test_state.py::test_immutable_mutable_proxy_async_context_manager tests/
    units/test_state.py::test_rebind_mutable_proxy tests/units/istate/
    test_proxy.py -q
  • uv run ruff check reflex/istate/proxy.py tests/units/test_state.py
  • uv run towncrier check --config pyproject.toml --dir . --compare-with
    upstream/main

@harsh21234i harsh21234i requested a review from a team as a code owner June 30, 2026 08:04

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e0d0b19a90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread reflex/istate/proxy.py
@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds async with proxy support to MutableProxy and ImmutableMutableProxy so background tasks can enter the owning StateProxy context directly through a nested field or item proxy, refreshing the proxy's wrapped value from the live state before mutating it.

  • Introduces __aenter__/__aexit__ on MutableProxy backed by a path-tracking refresh mechanism; AccessSpec tuples record the attr/item navigation steps taken to reach each sub-proxy so __aenter__ can replay them against the freshly-acquired state.
  • Adds four new test cases covering successful mutation, intentional rejection of iteration-sourced proxies, recovery from a failed StateProxy.__aenter__, and _self_actx_state cleanup when the owning context's exit itself raises.

Confidence Score: 5/5

The core async context manager logic is correct and all critical edge cases (failed enter, failed cleanup, double-entry guard) are covered by tests.

Path tracking works correctly for attr/item access patterns. The _wrap_recursive_decorator gap for dict.get/setdefault results is an unlikely usage pattern and does not affect normal operation of the feature.

reflex/istate/proxy.py — the _wrap_recursive_decorator method and whether it should forward the item key as a path segment for wrap_mutable_attrs methods.

Important Files Changed

Filename Overview
reflex/istate/proxy.py Adds aenter/aexit to MutableProxy with path-tracking refresh logic; path tracking is correct for attr/item access but wrap_mutable_attrs method results (dict.get, dict.setdefault) inherit parent path and would silently refresh to wrong object
tests/units/test_state.py Adds four comprehensive async context manager tests covering happy-path mutation, iter-proxy rejection, aenter failure recovery, and cleanup-failure recovery
news/6689.feature.md Changelog entry for the new async context manager feature

Reviews (7): Last reviewed commit: "Clear mutable proxy context after cleanu..." | Re-trigger Greptile

Comment thread reflex/istate/proxy.py Outdated
Comment thread reflex/istate/proxy.py Outdated
@codspeed-hq

codspeed-hq Bot commented Jun 30, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 19.5%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 25 untouched benchmarks
⏩ 8 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_var_access[mutable_dataclass_list] 206.7 ms 256.7 ms -19.5%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing harsh21234i:fix/mutable-proxy-async-context-6689 (78dec36) with main (46be552)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Comment thread reflex/istate/proxy.py
Comment thread reflex/istate/proxy.py Outdated
Comment thread reflex/istate/proxy.py Outdated
Comment thread reflex/istate/proxy.py
Comment thread reflex/istate/proxy.py Outdated
Comment thread reflex/istate/proxy.py Outdated
Comment thread reflex/istate/proxy.py Outdated
Comment thread reflex/istate/proxy.py Outdated
@harsh21234i

Copy link
Copy Markdown
Author

Addressed the review feedback in d8f12f3.

Changes made:

  • Added typed AccessSpec path entries for attr, item, and iter.
  • Updated _wrap_recursive to append a single new path segment internally.
  • Added _self_actx_state to internal proxy attrs.
  • Rejected nested async with proxy usage explicitly.
  • Made proxy __aexit__ idempotent when already exited.
  • Made async refresh path replay defensive and fail clearly for iteration-sourced proxies.
  • Added coverage for nested context rejection, idempotent exit, and iteration-derived proxy rejection.

Checks passed:

  • uv run pytest tests/units/test_state.py::test_immutable_mutable_proxy_async_context_manager tests/units/ test_state.py::test_immutable_mutable_proxy_async_context_rejects_iter_proxy tests/units/test_state.py::test_rebind_mutable_proxy tests/units/istate/ test_proxy.py -q
  • uv run ruff check reflex/istate/proxy.py tests/units/test_state.py
  • uv run ruff format --check reflex/istate/proxy.py tests/units/test_state.py
  • uv run pyright reflex/istate/proxy.py tests/units/test_state.py tests/units/istate/test_proxy.py

@harsh21234i harsh21234i requested a review from masenf July 2, 2026 04:02
Comment thread reflex/istate/proxy.py
@FarhanAliRaza

Copy link
Copy Markdown
Contributor

@codspeedbot fix this regression

Comment thread reflex/istate/proxy.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(Immutable)MutableProxy should support __aenter__ protocol

3 participants