rename private fields with leading underscore in App (#4642)
* rename private fields with leading underscore in App
* fix constants API
* fix public API for some attributes of App()
* fix conflicts properly 🙈
* remove extra private
---------
Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
This commit is contained in:
parent
c58db4d005
commit
858a85a4dc
@ -122,7 +122,7 @@ def AppWithTenComponentsOnePage():
|
||||
def index() -> rx.Component:
|
||||
return rx.center(rx.vstack(*render_component(1)))
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
@ -133,7 +133,7 @@ def AppWithHundredComponentOnePage():
|
||||
def index() -> rx.Component:
|
||||
return rx.center(rx.vstack(*render_component(100)))
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
@ -144,7 +144,7 @@ def AppWithThousandComponentsOnePage():
|
||||
def index() -> rx.Component:
|
||||
return rx.center(rx.vstack(*render_component(1000)))
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
|
@ -162,7 +162,7 @@ def AppWithOnePage():
|
||||
height="100vh",
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ def AppWithTenPages():
|
||||
"""A reflex app with 10 pages."""
|
||||
import reflex as rx
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
render_multiple_pages(app, 10)
|
||||
|
||||
|
||||
@ -178,7 +178,7 @@ def AppWithHundredPages():
|
||||
"""A reflex app with 100 pages."""
|
||||
import reflex as rx
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
render_multiple_pages(app, 100)
|
||||
|
||||
|
||||
@ -186,7 +186,7 @@ def AppWithThousandPages():
|
||||
"""A reflex app with Thousand pages."""
|
||||
import reflex as rx
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
render_multiple_pages(app, 1000)
|
||||
|
||||
|
||||
@ -194,7 +194,7 @@ def AppWithTenThousandPages():
|
||||
"""A reflex app with ten thousand pages."""
|
||||
import reflex as rx
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
render_multiple_pages(app, 10000)
|
||||
|
||||
|
||||
|
145
reflex/app.py
145
reflex/app.py
@ -251,36 +251,36 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
# Attributes to add to the html root tag of every page.
|
||||
html_custom_attrs: Optional[Dict[str, str]] = None
|
||||
|
||||
# A map from a route to an unevaluated page. PRIVATE.
|
||||
unevaluated_pages: Dict[str, UnevaluatedPage] = dataclasses.field(
|
||||
# A map from a route to an unevaluated page.
|
||||
_unevaluated_pages: Dict[str, UnevaluatedPage] = dataclasses.field(
|
||||
default_factory=dict
|
||||
)
|
||||
|
||||
# A map from a page route to the component to render. Users should use `add_page`. PRIVATE.
|
||||
pages: Dict[str, Component] = dataclasses.field(default_factory=dict)
|
||||
# A map from a page route to the component to render. Users should use `add_page`.
|
||||
_pages: Dict[str, Component] = dataclasses.field(default_factory=dict)
|
||||
|
||||
# The backend API object. PRIVATE.
|
||||
api: FastAPI = None # type: ignore
|
||||
# The backend API object.
|
||||
_api: FastAPI | None = None
|
||||
|
||||
# The state class to use for the app. PRIVATE.
|
||||
state: Optional[Type[BaseState]] = None
|
||||
# The state class to use for the app.
|
||||
_state: Optional[Type[BaseState]] = None
|
||||
|
||||
# Class to manage many client states.
|
||||
_state_manager: Optional[StateManager] = None
|
||||
|
||||
# Mapping from a route to event handlers to trigger when the page loads. PRIVATE.
|
||||
load_events: Dict[str, List[IndividualEventType[[], Any]]] = dataclasses.field(
|
||||
# Mapping from a route to event handlers to trigger when the page loads.
|
||||
_load_events: Dict[str, List[IndividualEventType[[], Any]]] = dataclasses.field(
|
||||
default_factory=dict
|
||||
)
|
||||
|
||||
# Admin dashboard to view and manage the database. PRIVATE.
|
||||
# Admin dashboard to view and manage the database.
|
||||
admin_dash: Optional[AdminDash] = None
|
||||
|
||||
# The async server name space. PRIVATE.
|
||||
event_namespace: Optional[EventNamespace] = None
|
||||
# The async server name space.
|
||||
_event_namespace: Optional[EventNamespace] = None
|
||||
|
||||
# Background tasks that are currently running. PRIVATE.
|
||||
background_tasks: Set[asyncio.Task] = dataclasses.field(default_factory=set)
|
||||
# Background tasks that are currently running.
|
||||
_background_tasks: Set[asyncio.Task] = dataclasses.field(default_factory=set)
|
||||
|
||||
# Frontend Error Handler Function
|
||||
frontend_exception_handler: Callable[[Exception], None] = (
|
||||
@ -292,6 +292,24 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
[Exception], Union[EventSpec, List[EventSpec], None]
|
||||
] = default_backend_exception_handler
|
||||
|
||||
@property
|
||||
def api(self) -> FastAPI | None:
|
||||
"""Get the backend api.
|
||||
|
||||
Returns:
|
||||
The backend api.
|
||||
"""
|
||||
return self._api
|
||||
|
||||
@property
|
||||
def event_namespace(self) -> EventNamespace | None:
|
||||
"""Get the event namespace.
|
||||
|
||||
Returns:
|
||||
The event namespace.
|
||||
"""
|
||||
return self._event_namespace
|
||||
|
||||
def __post_init__(self):
|
||||
"""Initialize the app.
|
||||
|
||||
@ -311,7 +329,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
set_breakpoints(self.style.pop("breakpoints"))
|
||||
|
||||
# Set up the API.
|
||||
self.api = FastAPI(lifespan=self._run_lifespan_tasks)
|
||||
self._api = FastAPI(lifespan=self._run_lifespan_tasks)
|
||||
self._add_cors()
|
||||
self._add_default_endpoints()
|
||||
|
||||
@ -334,8 +352,8 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
def _enable_state(self) -> None:
|
||||
"""Enable state for the app."""
|
||||
if not self.state:
|
||||
self.state = State
|
||||
if not self._state:
|
||||
self._state = State
|
||||
self._setup_state()
|
||||
|
||||
def _setup_state(self) -> None:
|
||||
@ -344,13 +362,13 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
Raises:
|
||||
RuntimeError: If the socket server is invalid.
|
||||
"""
|
||||
if not self.state:
|
||||
if not self._state:
|
||||
return
|
||||
|
||||
config = get_config()
|
||||
|
||||
# Set up the state manager.
|
||||
self._state_manager = StateManager.create(state=self.state)
|
||||
self._state_manager = StateManager.create(state=self._state)
|
||||
|
||||
# Set up the Socket.IO AsyncServer.
|
||||
if not self.sio:
|
||||
@ -381,12 +399,13 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
namespace = config.get_event_namespace()
|
||||
|
||||
# Create the event namespace and attach the main app. Not related to any paths.
|
||||
self.event_namespace = EventNamespace(namespace, self)
|
||||
self._event_namespace = EventNamespace(namespace, self)
|
||||
|
||||
# Register the event namespace with the socket.
|
||||
self.sio.register_namespace(self.event_namespace)
|
||||
# Mount the socket app with the API.
|
||||
self.api.mount(str(constants.Endpoint.EVENT), socket_app)
|
||||
if self.api:
|
||||
self.api.mount(str(constants.Endpoint.EVENT), socket_app)
|
||||
|
||||
# Check the exception handlers
|
||||
self._validate_exception_handlers()
|
||||
@ -397,24 +416,35 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
Returns:
|
||||
The string representation of the app.
|
||||
"""
|
||||
return f"<App state={self.state.__name__ if self.state else None}>"
|
||||
return f"<App state={self._state.__name__ if self._state else None}>"
|
||||
|
||||
def __call__(self) -> FastAPI:
|
||||
"""Run the backend api instance.
|
||||
|
||||
Raises:
|
||||
ValueError: If the app has not been initialized.
|
||||
|
||||
Returns:
|
||||
The backend api.
|
||||
"""
|
||||
if not self.api:
|
||||
raise ValueError("The app has not been initialized.")
|
||||
return self.api
|
||||
|
||||
def _add_default_endpoints(self):
|
||||
"""Add default api endpoints (ping)."""
|
||||
# To test the server.
|
||||
if not self.api:
|
||||
return
|
||||
|
||||
self.api.get(str(constants.Endpoint.PING))(ping)
|
||||
self.api.get(str(constants.Endpoint.HEALTH))(health)
|
||||
|
||||
def _add_optional_endpoints(self):
|
||||
"""Add optional api endpoints (_upload)."""
|
||||
if not self.api:
|
||||
return
|
||||
|
||||
if Upload.is_used:
|
||||
# To upload files.
|
||||
self.api.post(str(constants.Endpoint.UPLOAD))(upload(self))
|
||||
@ -432,6 +462,8 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
def _add_cors(self):
|
||||
"""Add CORS middleware to the app."""
|
||||
if not self.api:
|
||||
return
|
||||
self.api.add_middleware(
|
||||
cors.CORSMiddleware,
|
||||
allow_credentials=True,
|
||||
@ -521,13 +553,13 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
# Check if the route given is valid
|
||||
verify_route_validity(route)
|
||||
|
||||
if route in self.unevaluated_pages and environment.RELOAD_CONFIG.is_set():
|
||||
if route in self._unevaluated_pages and environment.RELOAD_CONFIG.is_set():
|
||||
# when the app is reloaded(typically for app harness tests), we should maintain
|
||||
# the latest render function of a route.This applies typically to decorated pages
|
||||
# since they are only added when app._compile is called.
|
||||
self.unevaluated_pages.pop(route)
|
||||
self._unevaluated_pages.pop(route)
|
||||
|
||||
if route in self.unevaluated_pages:
|
||||
if route in self._unevaluated_pages:
|
||||
route_name = (
|
||||
f"`{route}` or `/`"
|
||||
if route == constants.PageNames.INDEX_ROUTE
|
||||
@ -540,15 +572,15 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
# Setup dynamic args for the route.
|
||||
# this state assignment is only required for tests using the deprecated state kwarg for App
|
||||
state = self.state if self.state else State
|
||||
state = self._state if self._state else State
|
||||
state.setup_dynamic_args(get_route_args(route))
|
||||
|
||||
if on_load:
|
||||
self.load_events[route] = (
|
||||
self._load_events[route] = (
|
||||
on_load if isinstance(on_load, list) else [on_load]
|
||||
)
|
||||
|
||||
self.unevaluated_pages[route] = UnevaluatedPage(
|
||||
self._unevaluated_pages[route] = UnevaluatedPage(
|
||||
component=component,
|
||||
route=route,
|
||||
title=title,
|
||||
@ -563,10 +595,10 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
Args:
|
||||
route: The route of the page to compile.
|
||||
save_page: If True, the compiled page is saved to self.pages.
|
||||
save_page: If True, the compiled page is saved to self._pages.
|
||||
"""
|
||||
component, enable_state = compiler.compile_unevaluated_page(
|
||||
route, self.unevaluated_pages[route], self.state, self.style, self.theme
|
||||
route, self._unevaluated_pages[route], self._state, self.style, self.theme
|
||||
)
|
||||
|
||||
if enable_state:
|
||||
@ -575,7 +607,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
# Add the page.
|
||||
self._check_routes_conflict(route)
|
||||
if save_page:
|
||||
self.pages[route] = component
|
||||
self._pages[route] = component
|
||||
|
||||
def get_load_events(self, route: str) -> list[IndividualEventType[[], Any]]:
|
||||
"""Get the load events for a route.
|
||||
@ -589,7 +621,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
route = route.lstrip("/")
|
||||
if route == "":
|
||||
route = constants.PageNames.INDEX_ROUTE
|
||||
return self.load_events.get(route, [])
|
||||
return self._load_events.get(route, [])
|
||||
|
||||
def _check_routes_conflict(self, new_route: str):
|
||||
"""Verify if there is any conflict between the new route and any existing route.
|
||||
@ -613,7 +645,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
constants.RouteRegex.SINGLE_CATCHALL_SEGMENT,
|
||||
constants.RouteRegex.DOUBLE_CATCHALL_SEGMENT,
|
||||
)
|
||||
for route in self.pages:
|
||||
for route in self._pages:
|
||||
replaced_route = replace_brackets_with_keywords(route)
|
||||
for rw, r, nr in zip(
|
||||
replaced_route.split("/"), route.split("/"), new_route.split("/")
|
||||
@ -671,6 +703,9 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
def _setup_admin_dash(self):
|
||||
"""Setup the admin dash."""
|
||||
# Get the admin dash.
|
||||
if not self.api:
|
||||
return
|
||||
|
||||
admin_dash = self.admin_dash
|
||||
|
||||
if admin_dash and admin_dash.models:
|
||||
@ -775,10 +810,10 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
def _setup_overlay_component(self):
|
||||
"""If a State is not used and no overlay_component is specified, do not render the connection modal."""
|
||||
if self.state is None and self.overlay_component is default_overlay_component:
|
||||
if self._state is None and self.overlay_component is default_overlay_component:
|
||||
self.overlay_component = None
|
||||
for k, component in self.pages.items():
|
||||
self.pages[k] = self._add_overlay_to_component(component)
|
||||
for k, component in self._pages.items():
|
||||
self._pages[k] = self._add_overlay_to_component(component)
|
||||
|
||||
def _add_error_boundary_to_component(self, component: Component) -> Component:
|
||||
if self.error_boundary is None:
|
||||
@ -790,14 +825,14 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
def _setup_error_boundary(self):
|
||||
"""If a State is not used and no error_boundary is specified, do not render the error boundary."""
|
||||
if self.state is None and self.error_boundary is default_error_boundary:
|
||||
if self._state is None and self.error_boundary is default_error_boundary:
|
||||
self.error_boundary = None
|
||||
|
||||
for k, component in self.pages.items():
|
||||
for k, component in self._pages.items():
|
||||
# Skip the 404 page
|
||||
if k == constants.Page404.SLUG:
|
||||
continue
|
||||
self.pages[k] = self._add_error_boundary_to_component(component)
|
||||
self._pages[k] = self._add_error_boundary_to_component(component)
|
||||
|
||||
def _apply_decorated_pages(self):
|
||||
"""Add @rx.page decorated pages to the app.
|
||||
@ -823,11 +858,11 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
Raises:
|
||||
VarDependencyError: When a computed var has an invalid dependency.
|
||||
"""
|
||||
if not self.state:
|
||||
if not self._state:
|
||||
return
|
||||
|
||||
if not state:
|
||||
state = self.state
|
||||
state = self._state
|
||||
|
||||
for var in state.computed_vars.values():
|
||||
if not var._cache:
|
||||
@ -853,13 +888,13 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
"""
|
||||
from reflex.utils.exceptions import ReflexRuntimeError
|
||||
|
||||
self.pages = {}
|
||||
self._pages = {}
|
||||
|
||||
def get_compilation_time() -> str:
|
||||
return str(datetime.now().time()).split(".")[0]
|
||||
|
||||
# Render a default 404 page if the user didn't supply one
|
||||
if constants.Page404.SLUG not in self.unevaluated_pages:
|
||||
if constants.Page404.SLUG not in self._unevaluated_pages:
|
||||
self.add_page(route=constants.Page404.SLUG)
|
||||
|
||||
# Fix up the style.
|
||||
@ -877,7 +912,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
should_compile = self._should_compile()
|
||||
|
||||
for route in self.unevaluated_pages:
|
||||
for route in self._unevaluated_pages:
|
||||
console.debug(f"Evaluating page: {route}")
|
||||
self._compile_page(route, save_page=should_compile)
|
||||
|
||||
@ -904,7 +939,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
progress.start()
|
||||
task = progress.add_task(
|
||||
f"[{get_compilation_time()}] Compiling:",
|
||||
total=len(self.pages)
|
||||
total=len(self._pages)
|
||||
+ fixed_pages_within_executor
|
||||
+ adhoc_steps_without_executor,
|
||||
)
|
||||
@ -923,7 +958,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
# This has to happen before compiling stateful components as that
|
||||
# prevents recursive functions from reaching all components.
|
||||
for component in self.pages.values():
|
||||
for component in self._pages.values():
|
||||
# Add component._get_all_imports() to all_imports.
|
||||
all_imports.update(component._get_all_imports())
|
||||
|
||||
@ -938,12 +973,12 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
stateful_components_path,
|
||||
stateful_components_code,
|
||||
page_components,
|
||||
) = compiler.compile_stateful_components(self.pages.values())
|
||||
) = compiler.compile_stateful_components(self._pages.values())
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
# Catch "static" apps (that do not define a rx.State subclass) which are trying to access rx.State.
|
||||
if code_uses_state_contexts(stateful_components_code) and self.state is None:
|
||||
if code_uses_state_contexts(stateful_components_code) and self._state is None:
|
||||
raise ReflexRuntimeError(
|
||||
"To access rx.State in frontend components, at least one "
|
||||
"subclass of rx.State must be defined in the app."
|
||||
@ -980,10 +1015,10 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
max_workers=environment.REFLEX_COMPILE_THREADS.get() or None
|
||||
)
|
||||
|
||||
for route, component in zip(self.pages, page_components):
|
||||
for route, component in zip(self._pages, page_components):
|
||||
ExecutorSafeFunctions.COMPONENTS[route] = component
|
||||
|
||||
ExecutorSafeFunctions.STATE = self.state
|
||||
ExecutorSafeFunctions.STATE = self._state
|
||||
|
||||
with executor:
|
||||
result_futures = []
|
||||
@ -993,7 +1028,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
result_futures.append(f)
|
||||
|
||||
# Compile the pre-compiled pages.
|
||||
for route in self.pages:
|
||||
for route in self._pages:
|
||||
_submit_work(
|
||||
ExecutorSafeFunctions.compile_page,
|
||||
route,
|
||||
@ -1028,7 +1063,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
|
||||
# Compile the contexts.
|
||||
compile_results.append(
|
||||
compiler.compile_contexts(self.state, self.theme),
|
||||
compiler.compile_contexts(self._state, self.theme),
|
||||
)
|
||||
if self.theme is not None:
|
||||
# Fix #2992 by removing the top-level appearance prop
|
||||
@ -1150,9 +1185,9 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
)
|
||||
|
||||
task = asyncio.create_task(_coro())
|
||||
self.background_tasks.add(task)
|
||||
self._background_tasks.add(task)
|
||||
# Clean up task from background_tasks set when complete.
|
||||
task.add_done_callback(self.background_tasks.discard)
|
||||
task.add_done_callback(self._background_tasks.discard)
|
||||
return task
|
||||
|
||||
def _validate_exception_handlers(self):
|
||||
|
@ -296,7 +296,7 @@ class AppHarness:
|
||||
self.app_instance = self.app_module.app
|
||||
if isinstance(self.app_instance._state_manager, StateManagerRedis):
|
||||
# Create our own redis connection for testing.
|
||||
self.state_manager = StateManagerRedis.create(self.app_instance.state)
|
||||
self.state_manager = StateManagerRedis.create(self.app_instance._state)
|
||||
else:
|
||||
self.state_manager = self.app_instance._state_manager
|
||||
|
||||
@ -324,7 +324,7 @@ class AppHarness:
|
||||
return _shutdown_redis
|
||||
|
||||
def _start_backend(self, port=0):
|
||||
if self.app_instance is None:
|
||||
if self.app_instance is None or self.app_instance.api is None:
|
||||
raise RuntimeError("App was not initialized.")
|
||||
self.backend = uvicorn.Server(
|
||||
uvicorn.Config(
|
||||
@ -353,12 +353,12 @@ class AppHarness:
|
||||
self.app_instance.state_manager,
|
||||
StateManagerRedis,
|
||||
)
|
||||
and self.app_instance.state is not None
|
||||
and self.app_instance._state is not None
|
||||
):
|
||||
with contextlib.suppress(RuntimeError):
|
||||
await self.app_instance.state_manager.close()
|
||||
self.app_instance._state_manager = StateManagerRedis.create(
|
||||
state=self.app_instance.state,
|
||||
state=self.app_instance._state,
|
||||
)
|
||||
if not isinstance(self.app_instance.state_manager, StateManagerRedis):
|
||||
raise RuntimeError("Failed to reset state manager.")
|
||||
|
@ -172,7 +172,7 @@ def BackgroundTask():
|
||||
rx.button("Reset", on_click=State.reset_counter, id="reset"),
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
@ -288,7 +288,7 @@ def test_background_task(
|
||||
assert background_task._poll_for(lambda: counter.text == "620", timeout=40)
|
||||
# all tasks should have exited and cleaned up
|
||||
assert background_task._poll_for(
|
||||
lambda: not background_task.app_instance.background_tasks # type: ignore
|
||||
lambda: not background_task.app_instance._background_tasks # type: ignore
|
||||
)
|
||||
|
||||
|
||||
|
@ -188,7 +188,7 @@ def CallScript():
|
||||
yield rx.call_script("inline_counter = 0; external_counter = 0")
|
||||
self.reset()
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
Path("assets/external.js").write_text(external_scripts)
|
||||
|
||||
@app.add_page
|
||||
|
@ -127,7 +127,7 @@ def ClientSide():
|
||||
rx.box(ClientSideSubSubState.s1s, id="s1s"),
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
app.add_page(index, route="/foo")
|
||||
|
||||
|
@ -72,7 +72,7 @@ def ComponentStateApp():
|
||||
State=_Counter,
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State) # noqa
|
||||
app = rx.App(_state=rx.State) # noqa
|
||||
|
||||
@rx.page()
|
||||
def index():
|
||||
|
@ -36,7 +36,7 @@ def ConnectionBanner():
|
||||
rx.button("Delay", id="delay", on_click=State.delay),
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ def DeployUrlSample() -> None:
|
||||
rx.button("GOTO SELF", on_click=State.goto_self, id="goto_self")
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
|
@ -138,7 +138,7 @@ def DynamicRoute():
|
||||
def redirect_page():
|
||||
return rx.fragment(rx.text("redirecting..."))
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index, route="/page/[page_id]", on_load=DynamicState.on_load) # type: ignore
|
||||
app.add_page(index, route="/static/x", on_load=DynamicState.on_load) # type: ignore
|
||||
app.add_page(index)
|
||||
|
@ -156,7 +156,7 @@ def TestEventAction():
|
||||
on_click=EventActionState.on_click("outer"), # type: ignore
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
|
@ -144,7 +144,7 @@ def EventChain():
|
||||
time.sleep(0.5)
|
||||
self.interim_value = "final"
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
token_input = rx.input(
|
||||
value=State.router.session.client_token, is_read_only=True, id="token"
|
||||
|
@ -39,7 +39,7 @@ def TestApp():
|
||||
"""
|
||||
print(1 / number)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
@app.add_page
|
||||
def index():
|
||||
|
@ -30,7 +30,7 @@ def FormSubmit(form_component):
|
||||
def form_submit(self, form_data: Dict):
|
||||
self.form_data = form_data
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
@app.add_page
|
||||
def index():
|
||||
@ -90,7 +90,7 @@ def FormSubmitName(form_component):
|
||||
def form_submit(self, form_data: Dict):
|
||||
self.form_data = form_data
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
@app.add_page
|
||||
def index():
|
||||
|
@ -16,7 +16,7 @@ def FullyControlledInput():
|
||||
class State(rx.State):
|
||||
text: str = "initial"
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
@app.add_page
|
||||
def index():
|
||||
|
@ -45,7 +45,7 @@ def LoginSample():
|
||||
rx.button("Do it", on_click=State.login, id="doit"),
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
app.add_page(login)
|
||||
|
||||
|
@ -38,7 +38,7 @@ def ServerSideEvent():
|
||||
def set_value_return_c(self):
|
||||
return rx.set_value("c", "")
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
@app.add_page
|
||||
def index():
|
||||
|
@ -166,7 +166,7 @@ def UploadFile():
|
||||
rx.text(UploadState.event_order.to_string(), id="event-order"),
|
||||
)
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
app.add_page(index)
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ def VarOperations():
|
||||
dict2: Dict[int, int] = {3: 4}
|
||||
html_str: str = "<div>hello</div>"
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
@rx.memo
|
||||
def memo_comp(list1: List[int], int_var1: int, id: str):
|
||||
|
@ -16,7 +16,7 @@ def DatetimeOperationsApp():
|
||||
date2: datetime = datetime(2031, 1, 1)
|
||||
date3: datetime = datetime(2021, 1, 1)
|
||||
|
||||
app = rx.App(state=DtOperationsState)
|
||||
app = rx.App(_state=DtOperationsState)
|
||||
|
||||
@app.add_page
|
||||
def index():
|
||||
|
@ -20,7 +20,7 @@ def Table():
|
||||
"""App using table component."""
|
||||
import reflex as rx
|
||||
|
||||
app = rx.App(state=rx.State)
|
||||
app = rx.App(_state=rx.State)
|
||||
|
||||
@app.add_page
|
||||
def index():
|
||||
|
@ -41,7 +41,7 @@ async def test_preprocess_no_events(hydrate_middleware, event1, mocker):
|
||||
mocker.patch("reflex.state.State.class_subclasses", {TestState})
|
||||
state = State()
|
||||
update = await hydrate_middleware.preprocess(
|
||||
app=App(state=State),
|
||||
app=App(_state=State),
|
||||
event=event1,
|
||||
state=state,
|
||||
)
|
||||
|
@ -236,14 +236,14 @@ def test_add_page_default_route(app: App, index_page, about_page):
|
||||
index_page: The index page.
|
||||
about_page: The about page.
|
||||
"""
|
||||
assert app.pages == {}
|
||||
assert app.unevaluated_pages == {}
|
||||
assert app._pages == {}
|
||||
assert app._unevaluated_pages == {}
|
||||
app.add_page(index_page)
|
||||
app._compile_page("index")
|
||||
assert app.pages.keys() == {"index"}
|
||||
assert app._pages.keys() == {"index"}
|
||||
app.add_page(about_page)
|
||||
app._compile_page("about")
|
||||
assert app.pages.keys() == {"index", "about"}
|
||||
assert app._pages.keys() == {"index", "about"}
|
||||
|
||||
|
||||
def test_add_page_set_route(app: App, index_page, windows_platform: bool):
|
||||
@ -255,10 +255,10 @@ def test_add_page_set_route(app: App, index_page, windows_platform: bool):
|
||||
windows_platform: Whether the system is windows.
|
||||
"""
|
||||
route = "test" if windows_platform else "/test"
|
||||
assert app.unevaluated_pages == {}
|
||||
assert app._unevaluated_pages == {}
|
||||
app.add_page(index_page, route=route)
|
||||
app._compile_page("test")
|
||||
assert app.pages.keys() == {"test"}
|
||||
assert app._pages.keys() == {"test"}
|
||||
|
||||
|
||||
def test_add_page_set_route_dynamic(index_page, windows_platform: bool):
|
||||
@ -268,18 +268,18 @@ def test_add_page_set_route_dynamic(index_page, windows_platform: bool):
|
||||
index_page: The index page.
|
||||
windows_platform: Whether the system is windows.
|
||||
"""
|
||||
app = App(state=EmptyState)
|
||||
assert app.state is not None
|
||||
app = App(_state=EmptyState)
|
||||
assert app._state is not None
|
||||
route = "/test/[dynamic]"
|
||||
assert app.unevaluated_pages == {}
|
||||
assert app._unevaluated_pages == {}
|
||||
app.add_page(index_page, route=route)
|
||||
app._compile_page("test/[dynamic]")
|
||||
assert app.pages.keys() == {"test/[dynamic]"}
|
||||
assert "dynamic" in app.state.computed_vars
|
||||
assert app.state.computed_vars["dynamic"]._deps(objclass=EmptyState) == {
|
||||
assert app._pages.keys() == {"test/[dynamic]"}
|
||||
assert "dynamic" in app._state.computed_vars
|
||||
assert app._state.computed_vars["dynamic"]._deps(objclass=EmptyState) == {
|
||||
constants.ROUTER
|
||||
}
|
||||
assert constants.ROUTER in app.state()._computed_var_dependencies
|
||||
assert constants.ROUTER in app._state()._computed_var_dependencies
|
||||
|
||||
|
||||
def test_add_page_set_route_nested(app: App, index_page, windows_platform: bool):
|
||||
@ -291,9 +291,9 @@ def test_add_page_set_route_nested(app: App, index_page, windows_platform: bool)
|
||||
windows_platform: Whether the system is windows.
|
||||
"""
|
||||
route = "test\\nested" if windows_platform else "/test/nested"
|
||||
assert app.unevaluated_pages == {}
|
||||
assert app._unevaluated_pages == {}
|
||||
app.add_page(index_page, route=route)
|
||||
assert app.unevaluated_pages.keys() == {route.strip(os.path.sep)}
|
||||
assert app._unevaluated_pages.keys() == {route.strip(os.path.sep)}
|
||||
|
||||
|
||||
def test_add_page_invalid_api_route(app: App, index_page):
|
||||
@ -413,8 +413,8 @@ async def test_initialize_with_state(test_state: Type[ATestState], token: str):
|
||||
test_state: The default state.
|
||||
token: a Token.
|
||||
"""
|
||||
app = App(state=test_state)
|
||||
assert app.state == test_state
|
||||
app = App(_state=test_state)
|
||||
assert app._state == test_state
|
||||
|
||||
# Get a state for a given token.
|
||||
state = await app.state_manager.get_state(_substate_key(token, test_state))
|
||||
@ -432,7 +432,7 @@ async def test_set_and_get_state(test_state):
|
||||
Args:
|
||||
test_state: The default state.
|
||||
"""
|
||||
app = App(state=test_state)
|
||||
app = App(_state=test_state)
|
||||
|
||||
# Create two tokens.
|
||||
token1 = str(uuid.uuid4()) + f"_{test_state.get_full_name()}"
|
||||
@ -827,7 +827,7 @@ async def test_upload_file_without_annotation(state, tmp_path, token):
|
||||
token: a Token.
|
||||
"""
|
||||
state._tmp_path = tmp_path
|
||||
app = App(state=State)
|
||||
app = App(_state=State)
|
||||
|
||||
request_mock = unittest.mock.Mock()
|
||||
request_mock.headers = {
|
||||
@ -861,7 +861,7 @@ async def test_upload_file_background(state, tmp_path, token):
|
||||
token: a Token.
|
||||
"""
|
||||
state._tmp_path = tmp_path
|
||||
app = App(state=State)
|
||||
app = App(_state=State)
|
||||
|
||||
request_mock = unittest.mock.Mock()
|
||||
request_mock.headers = {
|
||||
@ -938,8 +938,8 @@ def test_dynamic_arg_shadow(
|
||||
"""
|
||||
arg_name = "counter"
|
||||
route = f"/test/[{arg_name}]"
|
||||
app = app_module_mock.app = App(state=DynamicState)
|
||||
assert app.state is not None
|
||||
app = app_module_mock.app = App(_state=DynamicState)
|
||||
assert app._state is not None
|
||||
with pytest.raises(NameError):
|
||||
app.add_page(index_page, route=route, on_load=DynamicState.on_load) # type: ignore
|
||||
|
||||
@ -963,7 +963,7 @@ def test_multiple_dynamic_args(
|
||||
arg_name = "my_arg"
|
||||
route = f"/test/[{arg_name}]"
|
||||
route2 = f"/test2/[{arg_name}]"
|
||||
app = app_module_mock.app = App(state=EmptyState)
|
||||
app = app_module_mock.app = App(_state=EmptyState)
|
||||
app.add_page(index_page, route=route)
|
||||
app.add_page(index_page, route=route2)
|
||||
|
||||
@ -990,16 +990,16 @@ async def test_dynamic_route_var_route_change_completed_on_load(
|
||||
"""
|
||||
arg_name = "dynamic"
|
||||
route = f"/test/[{arg_name}]"
|
||||
app = app_module_mock.app = App(state=DynamicState)
|
||||
assert app.state is not None
|
||||
assert arg_name not in app.state.vars
|
||||
app = app_module_mock.app = App(_state=DynamicState)
|
||||
assert app._state is not None
|
||||
assert arg_name not in app._state.vars
|
||||
app.add_page(index_page, route=route, on_load=DynamicState.on_load) # type: ignore
|
||||
assert arg_name in app.state.vars
|
||||
assert arg_name in app.state.computed_vars
|
||||
assert app.state.computed_vars[arg_name]._deps(objclass=DynamicState) == {
|
||||
assert arg_name in app._state.vars
|
||||
assert arg_name in app._state.computed_vars
|
||||
assert app._state.computed_vars[arg_name]._deps(objclass=DynamicState) == {
|
||||
constants.ROUTER
|
||||
}
|
||||
assert constants.ROUTER in app.state()._computed_var_dependencies
|
||||
assert constants.ROUTER in app._state()._computed_var_dependencies
|
||||
|
||||
substate_token = _substate_key(token, DynamicState)
|
||||
sid = "mock_sid"
|
||||
@ -1174,7 +1174,7 @@ async def test_process_events(mocker, token: str):
|
||||
"headers": {},
|
||||
"ip": "127.0.0.1",
|
||||
}
|
||||
app = App(state=GenState)
|
||||
app = App(_state=GenState)
|
||||
|
||||
mocker.patch.object(app, "_postprocess", AsyncMock())
|
||||
event = Event(
|
||||
@ -1220,7 +1220,7 @@ def test_overlay_component(
|
||||
overlay_component: The overlay_component to pass to App.
|
||||
exp_page_child: The type of the expected child in the page fragment.
|
||||
"""
|
||||
app = App(state=state, overlay_component=overlay_component)
|
||||
app = App(_state=state, overlay_component=overlay_component)
|
||||
app._setup_overlay_component()
|
||||
if exp_page_child is None:
|
||||
assert app.overlay_component is None
|
||||
@ -1243,7 +1243,7 @@ def test_overlay_component(
|
||||
# overlay components are wrapped during compile only
|
||||
app._compile_page("test")
|
||||
app._setup_overlay_component()
|
||||
page = app.pages["test"]
|
||||
page = app._pages["test"]
|
||||
|
||||
if exp_page_child is not None:
|
||||
assert len(page.children) == 3
|
||||
@ -1361,52 +1361,52 @@ def test_app_wrap_priority(compilable_app: tuple[App, Path]):
|
||||
def test_app_state_determination():
|
||||
"""Test that the stateless status of an app is determined correctly."""
|
||||
a1 = App()
|
||||
assert a1.state is None
|
||||
assert a1._state is None
|
||||
|
||||
# No state, no router, no event handlers.
|
||||
a1.add_page(rx.box("Index"), route="/")
|
||||
assert a1.state is None
|
||||
assert a1._state is None
|
||||
|
||||
# Add a page with `on_load` enables state.
|
||||
a1.add_page(rx.box("About"), route="/about", on_load=rx.console_log(""))
|
||||
a1._compile_page("about")
|
||||
assert a1.state is not None
|
||||
assert a1._state is not None
|
||||
|
||||
a2 = App()
|
||||
assert a2.state is None
|
||||
assert a2._state is None
|
||||
|
||||
# Referencing a state Var enables state.
|
||||
a2.add_page(rx.box(rx.text(GenState.value)), route="/")
|
||||
a2._compile_page("index")
|
||||
assert a2.state is not None
|
||||
assert a2._state is not None
|
||||
|
||||
a3 = App()
|
||||
assert a3.state is None
|
||||
assert a3._state is None
|
||||
|
||||
# Referencing router enables state.
|
||||
a3.add_page(rx.box(rx.text(State.router.page.full_path)), route="/")
|
||||
a3._compile_page("index")
|
||||
assert a3.state is not None
|
||||
assert a3._state is not None
|
||||
|
||||
a4 = App()
|
||||
assert a4.state is None
|
||||
assert a4._state is None
|
||||
|
||||
a4.add_page(rx.box(rx.button("Click", on_click=rx.console_log(""))), route="/")
|
||||
assert a4.state is None
|
||||
assert a4._state is None
|
||||
|
||||
a4.add_page(
|
||||
rx.box(rx.button("Click", on_click=DynamicState.on_counter)), route="/page2"
|
||||
)
|
||||
a4._compile_page("page2")
|
||||
assert a4.state is not None
|
||||
assert a4._state is not None
|
||||
|
||||
|
||||
def test_raise_on_state():
|
||||
"""Test that the state is set."""
|
||||
# state kwargs is deprecated, we just make sure the app is created anyway.
|
||||
_app = App(state=State)
|
||||
assert _app.state is not None
|
||||
assert issubclass(_app.state, State)
|
||||
_app = App(_state=State)
|
||||
assert _app._state is not None
|
||||
assert issubclass(_app._state, State)
|
||||
|
||||
|
||||
def test_call_app():
|
||||
@ -1473,7 +1473,7 @@ def test_add_page_component_returning_tuple():
|
||||
app._compile_page("index")
|
||||
app._compile_page("page2")
|
||||
|
||||
fragment_wrapper = app.pages["index"].children[0]
|
||||
fragment_wrapper = app._pages["index"].children[0]
|
||||
assert isinstance(fragment_wrapper, Fragment)
|
||||
first_text = fragment_wrapper.children[0]
|
||||
assert isinstance(first_text, Text)
|
||||
@ -1483,7 +1483,7 @@ def test_add_page_component_returning_tuple():
|
||||
assert str(second_text.children[0].contents) == '"second"' # type: ignore
|
||||
|
||||
# Test page with trailing comma.
|
||||
page2_fragment_wrapper = app.pages["page2"].children[0]
|
||||
page2_fragment_wrapper = app._pages["page2"].children[0]
|
||||
assert isinstance(page2_fragment_wrapper, Fragment)
|
||||
third_text = page2_fragment_wrapper.children[0]
|
||||
assert isinstance(third_text, Text)
|
||||
@ -1557,7 +1557,7 @@ def test_app_with_valid_var_dependencies(compilable_app: tuple[App, Path]):
|
||||
def bar(self) -> str:
|
||||
return "bar"
|
||||
|
||||
app.state = ValidDepState
|
||||
app._state = ValidDepState
|
||||
app._compile()
|
||||
|
||||
|
||||
@ -1569,7 +1569,7 @@ def test_app_with_invalid_var_dependencies(compilable_app: tuple[App, Path]):
|
||||
def bar(self) -> str:
|
||||
return "bar"
|
||||
|
||||
app.state = InvalidDepState
|
||||
app._state = InvalidDepState
|
||||
with pytest.raises(exceptions.VarDependencyError):
|
||||
app._compile()
|
||||
|
||||
|
@ -89,7 +89,7 @@ def app():
|
||||
],
|
||||
)
|
||||
def test_check_routes_conflict_invalid(mocker, app, route1, route2):
|
||||
mocker.patch.object(app, "pages", {route1: []})
|
||||
mocker.patch.object(app, "_pages", {route1: []})
|
||||
with pytest.raises(ValueError):
|
||||
app._check_routes_conflict(route2)
|
||||
|
||||
@ -117,6 +117,6 @@ def test_check_routes_conflict_invalid(mocker, app, route1, route2):
|
||||
],
|
||||
)
|
||||
def test_check_routes_conflict_valid(mocker, app, route1, route2):
|
||||
mocker.patch.object(app, "pages", {route1: []})
|
||||
mocker.patch.object(app, "_pages", {route1: []})
|
||||
# test that running this does not throw an error.
|
||||
app._check_routes_conflict(route2)
|
||||
|
@ -1907,12 +1907,12 @@ def mock_app_simple(monkeypatch) -> rx.App:
|
||||
Returns:
|
||||
The app, after mocking out prerequisites.get_app()
|
||||
"""
|
||||
app = App(state=TestState)
|
||||
app = App(_state=TestState)
|
||||
|
||||
app_module = Mock()
|
||||
|
||||
setattr(app_module, CompileVars.APP, app)
|
||||
app.state = TestState
|
||||
app._state = TestState
|
||||
app.event_namespace.emit = CopyingAsyncMock() # type: ignore
|
||||
|
||||
def _mock_get_app(*args, **kwargs):
|
||||
@ -2153,7 +2153,7 @@ async def test_background_task_no_block(mock_app: rx.App, token: str):
|
||||
token: A token.
|
||||
"""
|
||||
router_data = {"query": {}}
|
||||
mock_app.state_manager.state = mock_app.state = BackgroundTaskState
|
||||
mock_app.state_manager.state = mock_app._state = BackgroundTaskState
|
||||
async for update in rx.app.process( # type: ignore
|
||||
mock_app,
|
||||
Event(
|
||||
@ -2171,7 +2171,7 @@ async def test_background_task_no_block(mock_app: rx.App, token: str):
|
||||
|
||||
# wait for the coroutine to start
|
||||
await asyncio.sleep(0.5 if CI else 0.1)
|
||||
assert len(mock_app.background_tasks) == 1
|
||||
assert len(mock_app._background_tasks) == 1
|
||||
|
||||
# Process another normal event
|
||||
async for update in rx.app.process( # type: ignore
|
||||
@ -2203,9 +2203,9 @@ async def test_background_task_no_block(mock_app: rx.App, token: str):
|
||||
)
|
||||
|
||||
# Explicit wait for background tasks
|
||||
for task in tuple(mock_app.background_tasks):
|
||||
for task in tuple(mock_app._background_tasks):
|
||||
await task
|
||||
assert not mock_app.background_tasks
|
||||
assert not mock_app._background_tasks
|
||||
|
||||
exp_order = [
|
||||
"background_task:start",
|
||||
@ -2280,7 +2280,7 @@ async def test_background_task_reset(mock_app: rx.App, token: str):
|
||||
token: A token.
|
||||
"""
|
||||
router_data = {"query": {}}
|
||||
mock_app.state_manager.state = mock_app.state = BackgroundTaskState
|
||||
mock_app.state_manager.state = mock_app._state = BackgroundTaskState
|
||||
async for update in rx.app.process( # type: ignore
|
||||
mock_app,
|
||||
Event(
|
||||
@ -2297,9 +2297,9 @@ async def test_background_task_reset(mock_app: rx.App, token: str):
|
||||
assert update == StateUpdate()
|
||||
|
||||
# Explicit wait for background tasks
|
||||
for task in tuple(mock_app.background_tasks):
|
||||
for task in tuple(mock_app._background_tasks):
|
||||
await task
|
||||
assert not mock_app.background_tasks
|
||||
assert not mock_app._background_tasks
|
||||
|
||||
assert (
|
||||
await mock_app.state_manager.get_state(
|
||||
@ -2884,7 +2884,7 @@ async def test_preprocess(app_module_mock, token, test_state, expected, mocker):
|
||||
"reflex.state.State.class_subclasses", {test_state, OnLoadInternalState}
|
||||
)
|
||||
app = app_module_mock.app = App(
|
||||
state=State, load_events={"index": [test_state.test_handler]}
|
||||
_state=State, _load_events={"index": [test_state.test_handler]}
|
||||
)
|
||||
async with app.state_manager.modify_state(_substate_key(token, State)) as state:
|
||||
state.router_data = {"simulate": "hydrate"}
|
||||
@ -2931,8 +2931,8 @@ async def test_preprocess_multiple_load_events(app_module_mock, token, mocker):
|
||||
"reflex.state.State.class_subclasses", {OnLoadState, OnLoadInternalState}
|
||||
)
|
||||
app = app_module_mock.app = App(
|
||||
state=State,
|
||||
load_events={"index": [OnLoadState.test_handler, OnLoadState.test_handler]},
|
||||
_state=State,
|
||||
_load_events={"index": [OnLoadState.test_handler, OnLoadState.test_handler]},
|
||||
)
|
||||
async with app.state_manager.modify_state(_substate_key(token, State)) as state:
|
||||
state.router_data = {"simulate": "hydrate"}
|
||||
@ -2977,7 +2977,7 @@ async def test_get_state(mock_app: rx.App, token: str):
|
||||
mock_app: An app that will be returned by `get_app()`
|
||||
token: A token.
|
||||
"""
|
||||
mock_app.state_manager.state = mock_app.state = TestState
|
||||
mock_app.state_manager.state = mock_app._state = TestState
|
||||
|
||||
# Get instance of ChildState2.
|
||||
test_state = await mock_app.state_manager.get_state(
|
||||
@ -3147,7 +3147,7 @@ async def test_get_state_from_sibling_not_cached(mock_app: rx.App, token: str):
|
||||
|
||||
pass
|
||||
|
||||
mock_app.state_manager.state = mock_app.state = Parent
|
||||
mock_app.state_manager.state = mock_app._state = Parent
|
||||
|
||||
# Get the top level state via unconnected sibling.
|
||||
root = await mock_app.state_manager.get_state(_substate_key(token, Child))
|
||||
|
@ -222,7 +222,7 @@ async def state_manager_redis(
|
||||
Yields:
|
||||
A state manager instance
|
||||
"""
|
||||
app_module_mock.app = rx.App(state=Root)
|
||||
app_module_mock.app = rx.App(_state=Root)
|
||||
state_manager = app_module_mock.app.state_manager
|
||||
|
||||
if not isinstance(state_manager, StateManagerRedis):
|
||||
|
@ -23,7 +23,7 @@ def test_app_harness(tmp_path):
|
||||
class State(rx.State):
|
||||
pass
|
||||
|
||||
app = rx.App(state=State)
|
||||
app = rx.App(_state=State)
|
||||
app.add_page(lambda: rx.text("Basic App"), route="/", title="index")
|
||||
app._compile()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user