fix circular import and add read-only proxy

This commit is contained in:
Lendemor 2024-10-22 18:13:27 +02:00
parent 6b9865cf1d
commit 3ef56f6478
5 changed files with 45 additions and 8 deletions

View File

@ -330,7 +330,7 @@ _MAPPING: dict = {
"ComponentState",
"State",
],
"istate": ["get_state"],
"istate.wrappers": ["get_state"],
"style": ["Style", "toggle_color_mode"],
"utils.imports": ["ImportVar"],
"utils.serializers": ["serializer"],

View File

@ -174,7 +174,7 @@ from .event import stop_propagation as stop_propagation
from .event import upload_files as upload_files
from .event import window_alert as window_alert
from .experimental import _x as _x
from .istate import get_state as get_state
from .istate.wrappers import get_state as get_state
from .middleware import Middleware as Middleware
from .middleware import middleware as middleware
from .model import Model as Model

View File

@ -1,3 +1 @@
"""This module will provide interfaces for the state."""
from .wrappers import get_state

33
reflex/istate/proxy.py Normal file
View File

@ -0,0 +1,33 @@
"""A module to hold state proxy classes."""
from typing import Any
from reflex.state import StateProxy
class ReadOnlyStateProxy(StateProxy):
"""A read-only proxy for a state."""
def __setattr__(self, name: str, value: Any) -> None:
"""Prevent setting attributes on the state for read-only proxy.
Args:
name: The attribute name.
value: The attribute value.
Raises:
NotImplementedError: Always raised when trying to set an attribute on proxied state.
"""
if name.startswith("_self_"):
# Special case attributes of the proxy itself, not applied to the wrapped object.
super().__setattr__(name, value)
return
raise NotImplementedError("This is a read-only state proxy.")
def mark_dirty(self):
"""Mark the state as dirty.
Raises:
NotImplementedError: Always raised when trying to mark the proxied state as dirty.
"""
raise NotImplementedError("This is a read-only state proxy.")

View File

@ -2,10 +2,15 @@
from typing import Any
from reflex.state import _split_substate_key, _substate_key, get_state_manager
from reflex.istate.proxy import ReadOnlyStateProxy
from reflex.state import (
_split_substate_key,
_substate_key,
get_state_manager,
)
async def get_state(token, state_cls: Any | None = None):
async def get_state(token, state_cls: Any | None = None) -> ReadOnlyStateProxy:
"""Get the instance of a state for a token.
Args:
@ -13,7 +18,7 @@ async def get_state(token, state_cls: Any | None = None):
state_cls: The class of the state.
Returns:
The state instance.
A read-only proxy of the state instance.
"""
mng = get_state_manager()
if state_cls is not None:
@ -22,4 +27,5 @@ async def get_state(token, state_cls: Any | None = None):
root_state = await mng.get_state(token)
_, state_path = _split_substate_key(token)
state_cls = root_state.get_class_substate(tuple(state_path.split(".")))
return await root_state.get_state(state_cls)
instance = await root_state.get_state(state_cls)
return ReadOnlyStateProxy(instance)