From 940afb2c92a4e8147e865e8e6d40ec8f3e23c90d Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Tue, 7 May 2024 08:55:42 -0700 Subject: [PATCH] Remove deprecations for 0.5.0 (#3222) --- reflex/__init__.py | 1 - reflex/__init__.pyi | 1 - reflex/app.py | 28 +---- reflex/compiler/utils.py | 21 ---- reflex/components/component.py | 2 +- reflex/components/lucide/icon.py | 2 +- reflex/components/markdown/markdown.py | 16 +-- reflex/components/markdown/markdown.pyi | 4 +- reflex/state.py | 120 ------------------- reflex/utils/prerequisites.py | 2 +- tests/compiler/test_compiler_utils.py | 8 -- tests/components/typography/test_markdown.py | 12 -- tests/test_state.py | 75 ++++-------- 13 files changed, 35 insertions(+), 257 deletions(-) diff --git a/reflex/__init__.py b/reflex/__init__.py index d6aa5a837..f5c753789 100644 --- a/reflex/__init__.py +++ b/reflex/__init__.py @@ -120,7 +120,6 @@ _MAPPING = { "reflex.app": ["app", "App", "UploadFile"], "reflex.base": ["base", "Base"], "reflex.compiler": ["compiler"], - "reflex.compiler.utils": ["get_asset_path"], "reflex.components": _ALL_COMPONENTS, "reflex.components.component": ["Component", "NoSSRComponent", "memo"], "reflex.components.chakra": ["chakra"], diff --git a/reflex/__init__.pyi b/reflex/__init__.pyi index 2fbb9bfca..835666e1c 100644 --- a/reflex/__init__.pyi +++ b/reflex/__init__.pyi @@ -7,7 +7,6 @@ from reflex.app import UploadFile as UploadFile from reflex import base as base from reflex.base import Base as Base from reflex import compiler as compiler -from reflex.compiler.utils import get_asset_path as get_asset_path from reflex.components import color as color from reflex.components import cond as cond from reflex.components import foreach as foreach diff --git a/reflex/app.py b/reflex/app.py index c6cf8af80..e7cb8f027 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -193,20 +193,12 @@ class App(Base): base_state_subclasses = BaseState.__subclasses__() # Special case to allow test cases have multiple subclasses of rx.BaseState. - if not is_testing_env(): + if not is_testing_env() and len(base_state_subclasses) > 1: # Only one Base State class is allowed. - if len(base_state_subclasses) > 1: - raise ValueError( - "rx.BaseState cannot be subclassed multiple times. use rx.State instead" - ) + raise ValueError( + "rx.BaseState cannot be subclassed multiple times. use rx.State instead" + ) - if "state" in kwargs: - console.deprecate( - feature_name="`state` argument for App()", - reason="due to all `rx.State` subclasses being inferred.", - deprecation_version="0.3.5", - removal_version="0.5.0", - ) # Add middleware. self.middleware.append(HydrateMiddleware()) @@ -439,7 +431,6 @@ class App(Base): EventHandler | EventSpec | list[EventHandler | EventSpec] | None ) = None, meta: list[dict[str, str]] = constants.DefaultPage.META_LIST, - script_tags: list[Component] | None = None, ): """Add a page to the app. @@ -454,7 +445,6 @@ class App(Base): image: The image to display on the page. on_load: The event handler(s) that will be called each time the page load. meta: The metadata of the page. - script_tags: List of script tags to be added to component Raises: ValueError: When the specified route name already exists. @@ -535,16 +525,6 @@ class App(Base): **meta_args, ) - # Add script tags if given - if script_tags: - console.deprecate( - feature_name="Passing script tags to add_page", - reason="Add script components as children to the page component instead", - deprecation_version="0.2.9", - removal_version="0.5.0", - ) - component.children.extend(script_tags) - # Add the page. self._check_routes_conflict(route) self.pages[route] = component diff --git a/reflex/compiler/utils.py b/reflex/compiler/utils.py index 14d7d4d36..733d76a37 100644 --- a/reflex/compiler/utils.py +++ b/reflex/compiler/utils.py @@ -392,27 +392,6 @@ def get_stateful_components_path() -> str: ) -def get_asset_path(filename: str | None = None) -> str: - """Get the path for an asset. - - Args: - filename: If given, is added to the root path of assets dir. - - Returns: - The path of the asset. - """ - console.deprecate( - feature_name="rx.get_asset_path", - reason="use rx.get_upload_dir() instead.", - deprecation_version="0.4.0", - removal_version="0.5.0", - ) - if filename is None: - return constants.Dirs.WEB_ASSETS - else: - return os.path.join(constants.Dirs.WEB_ASSETS, filename) - - def add_meta( page: Component, title: str, diff --git a/reflex/components/component.py b/reflex/components/component.py index ab69e3716..65b2cfa77 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -743,7 +743,7 @@ class Component(BaseComponent, ABC): f"Underscore suffix for prop `{under_prop}`", reason=f"for consistency. Use `{prop}` instead.", deprecation_version="0.4.0", - removal_version="0.5.0", + removal_version="0.6.0", dedupe=False, ) props[prop] = props.pop(under_prop) diff --git a/reflex/components/lucide/icon.py b/reflex/components/lucide/icon.py index 5c4ef3dab..e9cf9ab82 100644 --- a/reflex/components/lucide/icon.py +++ b/reflex/components/lucide/icon.py @@ -44,7 +44,7 @@ class Icon(LucideIconComponent): feature_name=f"icon {tag}", reason=f"it was renamed upstream. Use {new_tag} instead.", deprecation_version="0.4.6", - removal_version="0.5.0", + removal_version="0.6.0", ) return new_tag return tag diff --git a/reflex/components/markdown/markdown.py b/reflex/components/markdown/markdown.py index 5ae712fc2..9ea4a11a7 100644 --- a/reflex/components/markdown/markdown.py +++ b/reflex/components/markdown/markdown.py @@ -18,7 +18,7 @@ from reflex.components.radix.themes.typography.heading import Heading from reflex.components.radix.themes.typography.link import Link from reflex.components.radix.themes.typography.text import Text from reflex.components.tags.tag import Tag -from reflex.utils import console, imports, types +from reflex.utils import imports, types from reflex.utils.imports import ImportVar from reflex.vars import Var @@ -84,9 +84,6 @@ class Markdown(Component): # The component map from a tag to a lambda that creates a component. component_map: Dict[str, Any] = {} - # Custom styles for the markdown (deprecated in v0.2.9). - custom_styles: Dict[str, Any] = {} - # The hash of the component map, generated at create() time. component_map_hash: str = "" @@ -105,15 +102,6 @@ class Markdown(Component): len(children) == 1 and types._isinstance(children[0], Union[str, Var]) ), "Markdown component must have exactly one child containing the markdown source." - # Custom styles are deprecated. - if "custom_styles" in props: - console.deprecate( - feature_name="rx.markdown custom_styles", - reason="Use the component_map prop instead.", - deprecation_version="0.2.9", - removal_version="0.5.0", - ) - # Update the base component map with the custom component map. component_map = {**get_base_component_map(), **props.pop("component_map", {})} @@ -229,8 +217,6 @@ class Markdown(Component): component = self.component_map[tag](*children, **props).set( special_props=special_props ) - component.style.update(self.custom_styles.get(tag, {})) - return component def format_component(self, tag: str, **props) -> str: diff --git a/reflex/components/markdown/markdown.pyi b/reflex/components/markdown/markdown.pyi index fbb830201..9ca8b11b0 100644 --- a/reflex/components/markdown/markdown.pyi +++ b/reflex/components/markdown/markdown.pyi @@ -22,7 +22,7 @@ from reflex.components.radix.themes.typography.heading import Heading from reflex.components.radix.themes.typography.link import Link from reflex.components.radix.themes.typography.text import Text from reflex.components.tags.tag import Tag -from reflex.utils import console, imports, types +from reflex.utils import imports, types from reflex.utils.imports import ImportVar from reflex.vars import Var @@ -48,7 +48,6 @@ class Markdown(Component): cls, *children, component_map: Optional[Dict[str, Any]] = None, - custom_styles: Optional[Dict[str, Any]] = None, component_map_hash: Optional[str] = None, style: Optional[Style] = None, key: Optional[Any] = None, @@ -108,7 +107,6 @@ class Markdown(Component): Args: *children: The children of the component. component_map: The component map from a tag to a lambda that creates a component. - custom_styles: Custom styles for the markdown (deprecated in v0.2.9). component_map_hash: The hash of the component map, generated at create() time. style: The style of the component. key: A unique key for the component. diff --git a/reflex/state.py b/reflex/state.py index 08b110c09..5cbc0dc8c 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -7,9 +7,7 @@ import contextlib import copy import functools import inspect -import json import traceback -import urllib.parse import uuid from abc import ABC, abstractmethod from collections import defaultdict @@ -961,124 +959,6 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow): if not func[0].startswith("__") } - def get_token(self) -> str: - """Return the token of the client associated with this state. - - Returns: - The token of the client. - """ - console.deprecate( - feature_name="get_token", - reason="replaced by `State.router.session.client_token`", - deprecation_version="0.3.0", - removal_version="0.5.0", - ) - return self.router_data.get(constants.RouteVar.CLIENT_TOKEN, "") - - def get_sid(self) -> str: - """Return the session ID of the client associated with this state. - - Returns: - The session ID of the client. - """ - console.deprecate( - feature_name="get_sid", - reason="replaced by `State.router.session.session_id`", - deprecation_version="0.3.0", - removal_version="0.5.0", - ) - return self.router_data.get(constants.RouteVar.SESSION_ID, "") - - def get_headers(self) -> Dict: - """Return the headers of the client associated with this state. - - Returns: - The headers of the client. - """ - console.deprecate( - feature_name="get_headers", - reason="replaced by `State.router.headers`", - deprecation_version="0.3.0", - removal_version="0.5.0", - ) - return self.router_data.get(constants.RouteVar.HEADERS, {}) - - def get_client_ip(self) -> str: - """Return the IP of the client associated with this state. - - Returns: - The IP of the client. - """ - console.deprecate( - feature_name="get_client_ip", - reason="replaced by `State.router.session.client_ip`", - deprecation_version="0.3.0", - removal_version="0.5.0", - ) - return self.router_data.get(constants.RouteVar.CLIENT_IP, "") - - def get_current_page(self, origin=False) -> str: - """Obtain the path of current page from the router data. - - Args: - origin: whether to return the base route as shown in browser - - Returns: - The current page. - """ - console.deprecate( - feature_name="get_current_page", - reason="replaced by State.router.page / self.router.page", - deprecation_version="0.3.0", - removal_version="0.5.0", - ) - - return self.router.page.raw_path if origin else self.router.page.path - - def get_query_params(self) -> dict[str, str]: - """Obtain the query parameters for the queried page. - - The query object contains both the URI parameters and the GET parameters. - - Returns: - The dict of query parameters. - """ - console.deprecate( - feature_name="get_query_params", - reason="replaced by `State.router.page.params`", - deprecation_version="0.3.0", - removal_version="0.5.0", - ) - return self.router_data.get(constants.RouteVar.QUERY, {}) - - def get_cookies(self) -> dict[str, str]: - """Obtain the cookies of the client stored in the browser. - - Returns: - The dict of cookies. - """ - console.deprecate( - feature_name=f"rx.get_cookies", - reason="and has been replaced by rx.Cookie, which can be used as a state var", - deprecation_version="0.3.0", - removal_version="0.5.0", - ) - cookie_dict = {} - cookies = self.get_headers().get(constants.RouteVar.COOKIE, "").split(";") - - cookie_pairs = [cookie.split("=") for cookie in cookies if cookie] - - for pair in cookie_pairs: - key, value = pair[0].strip(), urllib.parse.unquote(pair[1].strip()) - try: - # cast non-string values to the actual types. - value = json.loads(value) - except json.JSONDecodeError: - pass - finally: - cookie_dict[key] = value - return cookie_dict - @classmethod def setup_dynamic_args(cls, args: dict[str, str]): """Set up args for easy access in renderer. diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index 388bd5388..2e59b9953 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -294,7 +294,7 @@ def parse_redis_url() -> str | dict | None: feature_name="host[:port] style redis urls", reason="redis-py url syntax is now being used", deprecation_version="0.3.6", - removal_version="0.5.0", + removal_version="0.6.0", ) redis_url, has_port, redis_port = config.redis_url.partition(":") if not has_port: diff --git a/tests/compiler/test_compiler_utils.py b/tests/compiler/test_compiler_utils.py index 83b8ba961..d94c779af 100644 --- a/tests/compiler/test_compiler_utils.py +++ b/tests/compiler/test_compiler_utils.py @@ -1,6 +1,3 @@ -from reflex.compiler.utils import get_asset_path - - def TestState(State): pass @@ -8,8 +5,3 @@ def TestState(State): def test_compile_state(): # TODO: Implement test for compile_state function. pass - - -def test_get_assets_path(): - path = get_asset_path() - assert path diff --git a/tests/components/typography/test_markdown.py b/tests/components/typography/test_markdown.py index 6aff18110..8033ec606 100644 --- a/tests/components/typography/test_markdown.py +++ b/tests/components/typography/test_markdown.py @@ -49,15 +49,3 @@ def test_set_component_map(): # Make sure the old tags are still there. assert md.get_component("h2").tag == "Heading" # type: ignore - - -def test_pass_custom_styles(): - """Test that passing custom styles works.""" - md = Markdown.create("# Hello", custom_styles={"h1": {"color": "red"}}) - - comp = md.get_component("h1") # type: ignore - assert comp.style == { - "color": "red", - "marginBottom": "0.5em", - "marginTop": "0.5em", - } diff --git a/tests/test_state.py b/tests/test_state.py index ce62e9c64..e6e16ddef 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -33,7 +33,7 @@ from reflex.state import ( StateUpdate, _substate_key, ) -from reflex.utils import prerequisites, types +from reflex.utils import format, prerequisites, types from reflex.utils.format import json_dumps from reflex.vars import BaseVar, ComputedVar @@ -788,94 +788,69 @@ async def test_process_event_generator(): assert count == 6 -def test_get_token(test_state, mocker, router_data): +def test_get_client_token(test_state, router_data): """Test that the token obtained from the router_data is correct. Args: test_state: The test state. - mocker: Pytest Mocker object. router_data: The router data fixture. """ - mocker.patch.object(test_state, "router_data", router_data) - - assert test_state.get_token() == "b181904c-3953-4a79-dc18-ae9518c22f05" + test_state.router = RouterData(router_data) + assert ( + test_state.router.session.client_token == "b181904c-3953-4a79-dc18-ae9518c22f05" + ) -def test_get_sid(test_state, mocker, router_data): +def test_get_sid(test_state, router_data): """Test getting session id. Args: test_state: A state. - mocker: Pytest Mocker object. router_data: The router data fixture. """ - mocker.patch.object(test_state, "router_data", router_data) - - assert test_state.get_sid() == "9fpxSzPb9aFMb4wFAAAH" + test_state.router = RouterData(router_data) + assert test_state.router.session.session_id == "9fpxSzPb9aFMb4wFAAAH" -def test_get_headers(test_state, mocker, router_data, router_data_headers): +def test_get_headers(test_state, router_data, router_data_headers): """Test getting client headers. Args: test_state: A state. - mocker: Pytest Mocker object. router_data: The router data fixture. router_data_headers: The expected headers. """ - mocker.patch.object(test_state, "router_data", router_data) - - assert test_state.get_headers() == router_data_headers + test_state.router = RouterData(router_data) + assert test_state.router.headers.dict() == { + format.to_snake_case(k): v for k, v in router_data_headers.items() + } -def test_get_client_ip(test_state, mocker, router_data): +def test_get_client_ip(test_state, router_data): """Test getting client IP. Args: test_state: A state. - mocker: Pytest Mocker object. router_data: The router data fixture. """ - mocker.patch.object(test_state, "router_data", router_data) - - assert test_state.get_client_ip() == "127.0.0.1" - - -def test_get_cookies(test_state, mocker, router_data): - """Test getting client cookies. - - Args: - test_state: A state. - mocker: Pytest Mocker object. - router_data: The router data fixture. - """ - mocker.patch.object(test_state, "router_data", router_data) - - assert test_state.get_cookies() == { - "csrftoken": "mocktoken", - "name": "reflex", - "list_cookies": ["some", "random", "cookies"], - "dict_cookies": {"name": "reflex"}, - "val": True, - } + test_state.router = RouterData(router_data) + assert test_state.router.session.client_ip == "127.0.0.1" def test_get_current_page(test_state): - assert test_state.get_current_page() == "" + assert test_state.router.page.path == "" route = "mypage/subpage" test_state.router = RouterData({RouteVar.PATH: route}) - - assert test_state.get_current_page() == route + assert test_state.router.page.path == route def test_get_query_params(test_state): - assert test_state.get_query_params() == {} + assert test_state.router.page.params == {} params = {"p1": "a", "p2": "b"} - test_state.router_data = {RouteVar.QUERY: params} - - assert test_state.get_query_params() == params + test_state.router = RouterData({RouteVar.QUERY: params}) + assert dict(test_state.router.page.params) == params def test_add_var(): @@ -1723,7 +1698,9 @@ async def test_state_proxy(grandchild_state: GrandchildState, mock_app: rx.App): parent_state = child_state.parent_state assert parent_state is not None if isinstance(mock_app.state_manager, StateManagerMemory): - mock_app.state_manager.states[parent_state.get_token()] = parent_state + mock_app.state_manager.states[ + parent_state.router.session.client_token + ] = parent_state sp = StateProxy(grandchild_state) assert sp.__wrapped__ == grandchild_state @@ -1802,7 +1779,7 @@ async def test_state_proxy(grandchild_state: GrandchildState, mock_app: rx.App): }, } ) - assert mcall.kwargs["to"] == grandchild_state.get_sid() + assert mcall.kwargs["to"] == grandchild_state.router.session.session_id class BackgroundTaskState(BaseState):