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", "ComponentState",
"State", "State",
], ],
"istate": ["get_state"], "istate.wrappers": ["get_state"],
"style": ["Style", "toggle_color_mode"], "style": ["Style", "toggle_color_mode"],
"utils.imports": ["ImportVar"], "utils.imports": ["ImportVar"],
"utils.serializers": ["serializer"], "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 upload_files as upload_files
from .event import window_alert as window_alert from .event import window_alert as window_alert
from .experimental import _x as _x 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 .middleware import middleware as middleware from .middleware import middleware as middleware
from .model import Model as Model from .model import Model as Model

View File

@ -1,3 +1 @@
"""This module will provide interfaces for the state.""" """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 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. """Get the instance of a state for a token.
Args: Args:
@ -13,7 +18,7 @@ async def get_state(token, state_cls: Any | None = None):
state_cls: The class of the state. state_cls: The class of the state.
Returns: Returns:
The state instance. A read-only proxy of the state instance.
""" """
mng = get_state_manager() mng = get_state_manager()
if state_cls is not None: 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) root_state = await mng.get_state(token)
_, state_path = _split_substate_key(token) _, state_path = _split_substate_key(token)
state_cls = root_state.get_class_substate(tuple(state_path.split("."))) 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)