diff --git a/pyproject.toml b/pyproject.toml index 57d49e3f07..2238547a0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,13 +87,14 @@ build-backend = "poetry.core.masonry.api" target-version = "py39" output-format = "concise" lint.isort.split-on-trailing-comma = false -lint.select = ["B", "C4", "D", "E", "ERA", "F", "FURB", "I", "PERF", "PTH", "RUF", "SIM", "W"] +lint.select = ["ANN001", "B", "C4", "D", "E", "ERA", "F", "FURB", "I", "PERF", "PTH", "RUF", "SIM", "W"] lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012"] lint.pydocstyle.convention = "google" [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] -"tests/*.py" = ["D100", "D103", "D104", "B018", "PERF"] +"tests/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF"] +"benchmarks/*.py" = ["ANN001"] "reflex/.templates/*.py" = ["D100", "D103", "D104"] "*.pyi" = ["D301", "D415", "D417", "D418", "E742"] "*/blank.py" = ["I001"] diff --git a/reflex/__init__.py b/reflex/__init__.py index 0be568b1a7..4ed198124c 100644 --- a/reflex/__init__.py +++ b/reflex/__init__.py @@ -84,6 +84,9 @@ from __future__ import annotations +from types import ModuleType +from typing import Any + from reflex.utils import ( compat, # for side-effects lazy_loader, @@ -366,7 +369,7 @@ ) -def __getattr__(name): +def __getattr__(name: ModuleType | Any): if name == "chakra": from reflex.utils import console diff --git a/reflex/app.py b/reflex/app.py index 935fe7900c..f38b575c0a 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -650,8 +650,8 @@ def add_custom_404_page( Args: component: The component to display at the page. title: The title of the page. - description: The description of the page. image: The image to display on the page. + description: The description of the page. on_load: The event handler(s) that will be called each time the page load. meta: The metadata of the page. """ @@ -989,7 +989,7 @@ def get_compilation_time() -> str: with executor: result_futures = [] - def _submit_work(fn, *args, **kwargs): + def _submit_work(fn: Callable, *args, **kwargs): f = executor.submit(fn, *args, **kwargs) result_futures.append(f) @@ -1319,15 +1319,14 @@ async def process( if app._process_background(state, event) is not None: # `final=True` allows the frontend send more events immediately. yield StateUpdate(final=True) - return - - # Process the event synchronously. - async for update in state._process(event): - # Postprocess the event. - update = await app._postprocess(state, event, update) - - # Yield the update. - yield update + else: + # Process the event synchronously. + async for update in state._process(event): + # Postprocess the event. + update = await app._postprocess(state, event, update) + + # Yield the update. + yield update except Exception as ex: telemetry.send_error(ex, context="backend") @@ -1520,7 +1519,7 @@ def __init__(self, namespace: str, app: App): self.sid_to_token = {} self.app = app - def on_connect(self, sid, environ): + def on_connect(self, sid: str, environ: dict): """Event for when the websocket is connected. Args: @@ -1529,7 +1528,7 @@ def on_connect(self, sid, environ): """ pass - def on_disconnect(self, sid): + def on_disconnect(self, sid: str): """Event for when the websocket disconnects. Args: @@ -1551,7 +1550,7 @@ async def emit_update(self, update: StateUpdate, sid: str) -> None: self.emit(str(constants.SocketEvent.EVENT), update, to=sid) ) - async def on_event(self, sid, data): + async def on_event(self, sid: str, data: Any): """Event for receiving front-end websocket events. Raises: @@ -1594,7 +1593,7 @@ async def on_event(self, sid, data): # Emit the update from processing the event. await self.emit_update(update=update, sid=sid) - async def on_ping(self, sid): + async def on_ping(self, sid: str): """Event for testing the API endpoint. Args: diff --git a/reflex/app_mixins/lifespan.py b/reflex/app_mixins/lifespan.py index 52bf0be1db..b2304192d7 100644 --- a/reflex/app_mixins/lifespan.py +++ b/reflex/app_mixins/lifespan.py @@ -61,7 +61,7 @@ def register_lifespan_task(self, task: Callable | asyncio.Task, **task_kwargs): Args: task: The task to register. - task_kwargs: The kwargs of the task. + **task_kwargs: The kwargs of the task. Raises: InvalidLifespanTaskType: If the task is a generator function. diff --git a/reflex/base.py b/reflex/base.py index a88e557ef4..3df3113b49 100644 --- a/reflex/base.py +++ b/reflex/base.py @@ -80,7 +80,7 @@ def json(self) -> str: default=serialize, ) - def set(self, **kwargs): + def set(self, **kwargs: Any): """Set multiple fields and return the object. Args: diff --git a/reflex/compiler/utils.py b/reflex/compiler/utils.py index 1d698431cc..777a6f8d58 100644 --- a/reflex/compiler/utils.py +++ b/reflex/compiler/utils.py @@ -494,7 +494,7 @@ def empty_dir(path: str | Path, keep_files: list[str] | None = None): path_ops.rm(element) -def is_valid_url(url) -> bool: +def is_valid_url(url: str) -> bool: """Check if a url is valid. Args: diff --git a/reflex/components/component.py b/reflex/components/component.py index 34800ab6e6..4d37ef13b3 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -811,7 +811,7 @@ def create(cls, *children, **props) -> Component: # Filter out None props props = {key: value for key, value in props.items() if value is not None} - def validate_children(children): + def validate_children(children: tuple): for child in children: if isinstance(child, tuple): validate_children(child) @@ -956,7 +956,7 @@ def _get_style(self) -> dict: else {} ) - def render(self) -> Dict: + def render(self) -> dict: """Render the component. Returns: @@ -974,7 +974,7 @@ def render(self) -> Dict: self._replace_prop_names(rendered_dict) return rendered_dict - def _replace_prop_names(self, rendered_dict) -> None: + def _replace_prop_names(self, rendered_dict: dict) -> None: """Replace the prop names in the render dictionary. Args: @@ -1014,7 +1014,7 @@ def _validate_component_children(self, children: List[Component]): comp.__name__ for comp in (Fragment, Foreach, Cond, Match) ] - def validate_child(child): + def validate_child(child: Any): child_name = type(child).__name__ # Iterate through the immediate children of fragment diff --git a/reflex/components/core/client_side_routing.py b/reflex/components/core/client_side_routing.py index a10b90de81..0fc40de5f8 100644 --- a/reflex/components/core/client_side_routing.py +++ b/reflex/components/core/client_side_routing.py @@ -41,7 +41,7 @@ def render(self) -> str: return "" -def wait_for_client_redirect(component) -> Component: +def wait_for_client_redirect(component: Component) -> Component: """Wait for a redirect to occur before rendering a component. This prevents the 404 page from flashing while the redirect is happening. diff --git a/reflex/components/core/client_side_routing.pyi b/reflex/components/core/client_side_routing.pyi index 581b0e120d..0786981986 100644 --- a/reflex/components/core/client_side_routing.pyi +++ b/reflex/components/core/client_side_routing.pyi @@ -60,7 +60,7 @@ class ClientSideRouting(Component): """ ... -def wait_for_client_redirect(component) -> Component: ... +def wait_for_client_redirect(component: Component) -> Component: ... class Default404Page(Component): @overload diff --git a/reflex/components/core/cond.py b/reflex/components/core/cond.py index 488990f543..81393ab777 100644 --- a/reflex/components/core/cond.py +++ b/reflex/components/core/cond.py @@ -154,7 +154,7 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var: if c2 is None: raise ValueError("For conditional vars, the second argument must be set.") - def create_var(cond_part): + def create_var(cond_part: Any) -> Var[Any]: return LiteralVar.create(cond_part) # convert the truth and false cond parts into vars so the _var_data can be obtained. diff --git a/reflex/components/core/match.py b/reflex/components/core/match.py index 8b9382c899..055278c826 100644 --- a/reflex/components/core/match.py +++ b/reflex/components/core/match.py @@ -109,7 +109,7 @@ def _process_cases( return cases, default @classmethod - def _create_case_var_with_var_data(cls, case_element): + def _create_case_var_with_var_data(cls, case_element: Any) -> Var: """Convert a case element into a Var.If the case is a Style type, we extract the var data and merge it with the newly created Var. diff --git a/reflex/components/datadisplay/logo.py b/reflex/components/datadisplay/logo.py index d960b8cee5..1c4c020015 100644 --- a/reflex/components/datadisplay/logo.py +++ b/reflex/components/datadisplay/logo.py @@ -15,10 +15,8 @@ def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "whi The Reflex logo SVG. """ - def logo_path(d): - return rx.el.svg.path( - d=d, - ) + def logo_path(d: str): + return rx.el.svg.path(d=d) paths = [ "M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z", diff --git a/reflex/components/el/element.py b/reflex/components/el/element.py index 213cea65a0..c9a58b1f6f 100644 --- a/reflex/components/el/element.py +++ b/reflex/components/el/element.py @@ -6,7 +6,7 @@ class Element(Component): """The base class for all raw HTML elements.""" - def __eq__(self, other): + def __eq__(self, other: object): """Two elements are equal if they have the same tag. Args: diff --git a/reflex/components/markdown/markdown.py b/reflex/components/markdown/markdown.py index cd82d5903f..03e91a2b27 100644 --- a/reflex/components/markdown/markdown.py +++ b/reflex/components/markdown/markdown.py @@ -8,7 +8,7 @@ from hashlib import md5 from typing import Any, Callable, Dict, Sequence, Union -from reflex.components.component import Component, CustomComponent +from reflex.components.component import BaseComponent, Component, CustomComponent from reflex.components.tags.tag import Tag from reflex.utils import types from reflex.utils.imports import ImportDict, ImportVar @@ -379,7 +379,9 @@ def _get_map_fn_var_from_children(self, component: Component, tag: str) -> Var: # fallback to the default fn Var creation if the component is not a MarkdownComponentMap. return MarkdownComponentMap.create_map_fn_var(fn_body=formatted_component) - def _get_map_fn_custom_code_from_children(self, component) -> list[str]: + def _get_map_fn_custom_code_from_children( + self, component: BaseComponent + ) -> list[str]: """Recursively get markdown custom code from children components. Args: @@ -409,7 +411,7 @@ def _get_map_fn_custom_code_from_children(self, component) -> list[str]: return custom_code_list @staticmethod - def _component_map_hash(component_map) -> str: + def _component_map_hash(component_map: dict) -> str: inp = str( {tag: component(_MOCK_ARG) for tag, component in component_map.items()} ).encode() diff --git a/reflex/components/next/image.py b/reflex/components/next/image.py index 2011505d8b..7143be8283 100644 --- a/reflex/components/next/image.py +++ b/reflex/components/next/image.py @@ -1,5 +1,7 @@ """Image component from next/image.""" +from __future__ import annotations + from typing import Any, Literal, Optional, Union from reflex.event import EventHandler, no_args_event_spec @@ -83,7 +85,7 @@ def create( style = props.get("style", {}) DEFAULT_W_H = "100%" - def check_prop_type(prop_name, prop_value): + def check_prop_type(prop_name: str, prop_value: int | str | None): if types.check_prop_in_allowed_types(prop_value, allowed_types=[int]): props[prop_name] = prop_value diff --git a/reflex/components/props.py b/reflex/components/props.py index adce134fcd..59df73e294 100644 --- a/reflex/components/props.py +++ b/reflex/components/props.py @@ -48,7 +48,7 @@ def dict(self, *args, **kwargs): class NoExtrasAllowedProps(Base): """A class that holds props to be passed or applied to a component with no extra props allowed.""" - def __init__(self, component_name=None, **kwargs): + def __init__(self, component_name: str | None = None, **kwargs): """Initialize the props. Args: diff --git a/reflex/components/radix/themes/color_mode.py b/reflex/components/radix/themes/color_mode.py index 2dd0f5e835..800518defa 100644 --- a/reflex/components/radix/themes/color_mode.py +++ b/reflex/components/radix/themes/color_mode.py @@ -17,7 +17,7 @@ from __future__ import annotations -from typing import Dict, List, Literal, Optional, Union, get_args +from typing import Any, Dict, List, Literal, Optional, Union, get_args from reflex.components.component import BaseComponent from reflex.components.core.cond import Cond, color_mode_cond, cond @@ -78,17 +78,19 @@ def create( # needed to inverse contains for find -def _find(const: List[str], var): +def _find(const: List[str], var: Any): return LiteralArrayVar.create(const).contains(var) -def _set_var_default(props, position, prop, default1, default2=""): +def _set_var_default( + props: dict, position: Any, prop: str, default1: str, default2: str = "" +): props.setdefault( prop, cond(_find(position_map[prop], position), default1, default2) ) -def _set_static_default(props, position, prop, default): +def _set_static_default(props: dict, position: Any, prop: str, default: str): if prop in position: props.setdefault(prop, default) @@ -142,7 +144,7 @@ def create( if allow_system: - def color_mode_item(_color_mode): + def color_mode_item(_color_mode: str): return dropdown_menu.item( _color_mode.title(), on_click=set_color_mode(_color_mode) ) diff --git a/reflex/components/radix/themes/layout/list.py b/reflex/components/radix/themes/layout/list.py index a306e19a49..48194781fd 100644 --- a/reflex/components/radix/themes/layout/list.py +++ b/reflex/components/radix/themes/layout/list.py @@ -189,7 +189,7 @@ class List(ComponentNamespace): unordered_list = list_ns.unordered -def __getattr__(name): +def __getattr__(name: Any): # special case for when accessing list to avoid shadowing # python's built in list object. if name == "list": diff --git a/reflex/components/recharts/charts.py b/reflex/components/recharts/charts.py index 85e10c2c54..ea08e73d42 100644 --- a/reflex/components/recharts/charts.py +++ b/reflex/components/recharts/charts.py @@ -69,7 +69,7 @@ def _ensure_valid_dimension(name: str, value: Any) -> None: ) @classmethod - def create(cls, *children, **props) -> Component: + def create(cls, *children: Any, **props: Any) -> Component: """Create a chart component. Args: diff --git a/reflex/components/sonner/toast.py b/reflex/components/sonner/toast.py index 836c19bf9d..bb5f68cc88 100644 --- a/reflex/components/sonner/toast.py +++ b/reflex/components/sonner/toast.py @@ -132,7 +132,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps): # Function that gets called when the toast disappears automatically after it's timeout (duration` prop). on_auto_close: Optional[Any] - def dict(self, *args, **kwargs) -> dict[str, Any]: + def dict(self, *args: Any, **kwargs: Any) -> dict[str, Any]: """Convert the object to a dictionary. Args: @@ -167,7 +167,7 @@ def dict(self, *args, **kwargs) -> dict[str, Any]: class Toaster(Component): """A Toaster Component for displaying toast notifications.""" - library: str = "sonner@1.5.0" + library = "sonner@1.5.0" tag = "Toaster" @@ -228,7 +228,7 @@ def add_hooks(self) -> list[Var | str]: imports={ "$/utils/state": [ImportVar(tag="refs")], self.library: [ImportVar(tag="toast", install=False)], - } + } # type: ignore ), ) return [hook] @@ -274,12 +274,12 @@ def send_toast( return run_script(toast) @staticmethod - def toast_info(message: str | Var = "", **kwargs): + def toast_info(message: str | Var = "", **kwargs: Any): """Display an info toast message. Args: message: The message to display. - kwargs: Additional toast props. + **kwargs: Additional toast props. Returns: The toast event. @@ -287,12 +287,12 @@ def toast_info(message: str | Var = "", **kwargs): return Toaster.send_toast(message, level="info", **kwargs) @staticmethod - def toast_warning(message: str | Var = "", **kwargs): + def toast_warning(message: str | Var = "", **kwargs: Any): """Display a warning toast message. Args: message: The message to display. - kwargs: Additional toast props. + **kwargs: Additional toast props. Returns: The toast event. @@ -300,12 +300,12 @@ def toast_warning(message: str | Var = "", **kwargs): return Toaster.send_toast(message, level="warning", **kwargs) @staticmethod - def toast_error(message: str | Var = "", **kwargs): + def toast_error(message: str | Var = "", **kwargs: Any): """Display an error toast message. Args: message: The message to display. - kwargs: Additional toast props. + **kwargs: Additional toast props. Returns: The toast event. @@ -313,12 +313,12 @@ def toast_error(message: str | Var = "", **kwargs): return Toaster.send_toast(message, level="error", **kwargs) @staticmethod - def toast_success(message: str | Var = "", **kwargs): + def toast_success(message: str | Var = "", **kwargs: Any): """Display a success toast message. Args: message: The message to display. - kwargs: Additional toast props. + **kwargs: Additional toast props. Returns: The toast event. @@ -350,7 +350,7 @@ def toast_dismiss(id: Var | str | None = None): return run_script(dismiss_action) @classmethod - def create(cls, *children, **props) -> Component: + def create(cls, *children: Any, **props: Any) -> Component: """Create a toaster component. Args: diff --git a/reflex/components/sonner/toast.pyi b/reflex/components/sonner/toast.pyi index 7fd9fdf542..829e959d59 100644 --- a/reflex/components/sonner/toast.pyi +++ b/reflex/components/sonner/toast.pyi @@ -51,7 +51,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps): on_dismiss: Optional[Any] on_auto_close: Optional[Any] - def dict(self, *args, **kwargs) -> dict[str, Any]: ... + def dict(self, *args: Any, **kwargs: Any) -> dict[str, Any]: ... class Toaster(Component): is_used: ClassVar[bool] = False @@ -62,13 +62,13 @@ class Toaster(Component): message: str | Var = "", level: str | None = None, **props ) -> EventSpec: ... @staticmethod - def toast_info(message: str | Var = "", **kwargs): ... + def toast_info(message: str | Var = "", **kwargs: Any): ... @staticmethod - def toast_warning(message: str | Var = "", **kwargs): ... + def toast_warning(message: str | Var = "", **kwargs: Any): ... @staticmethod - def toast_error(message: str | Var = "", **kwargs): ... + def toast_error(message: str | Var = "", **kwargs: Any): ... @staticmethod - def toast_success(message: str | Var = "", **kwargs): ... + def toast_success(message: str | Var = "", **kwargs: Any): ... @staticmethod def toast_dismiss(id: Var | str | None = None): ... @overload diff --git a/reflex/components/suneditor/editor.py b/reflex/components/suneditor/editor.py index d40f0e9ad1..774aad0f99 100644 --- a/reflex/components/suneditor/editor.py +++ b/reflex/components/suneditor/editor.py @@ -3,7 +3,7 @@ from __future__ import annotations import enum -from typing import Dict, List, Literal, Optional, Tuple, Union +from typing import Any, Dict, List, Literal, Optional, Tuple, Union from reflex.base import Base from reflex.components.component import Component, NoSSRComponent @@ -244,11 +244,13 @@ def add_imports(self) -> ImportDict: } @classmethod - def create(cls, set_options: Optional[EditorOptions] = None, **props) -> Component: + def create( + cls, set_options: Optional[EditorOptions] = None, **props: Any + ) -> Component: """Create an instance of Editor. No children allowed. Args: - set_options(Optional[EditorOptions]): Configuration object to further configure the instance. + set_options: Configuration object to further configure the instance. **props: Any properties to be passed to the Editor Returns: diff --git a/reflex/components/suneditor/editor.pyi b/reflex/components/suneditor/editor.pyi index b52fd43da9..8a130ed3a2 100644 --- a/reflex/components/suneditor/editor.pyi +++ b/reflex/components/suneditor/editor.pyi @@ -171,8 +171,8 @@ class Editor(NoSSRComponent): """Create an instance of Editor. No children allowed. Args: - set_options(Optional[EditorOptions]): Configuration object to further configure the instance. - lang: Language of the editor. Alternatively to a string, a dict of your language can be passed to this prop. Please refer to the library docs for this. options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" | "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it" default: "en". + set_options: Configuration object to further configure the instance. + lang: Language of the editor. Alternatively to a string, a dict of your language can be passed to this prop. Please refer to the library docs for this. options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" | "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it" default : "en" name: This is used to set the HTML form name of the editor. This means on HTML form submission, it will be submitted together with contents of the editor by the name provided. default_value: Sets the default value of the editor. This is useful if you don't want the on_change method to be called on render. If you want the on_change method to be called on render please use the set_contents prop width: Sets the width of the editor. px and percentage values are accepted, eg width="100%" or width="500px" default: 100% diff --git a/reflex/components/tags/tag.py b/reflex/components/tags/tag.py index 0587c61eda..8569d5d509 100644 --- a/reflex/components/tags/tag.py +++ b/reflex/components/tags/tag.py @@ -49,7 +49,7 @@ def set(self, **kwargs: Any): """Set the tag's fields. Args: - kwargs: The fields to set. + **kwargs: The fields to set. Returns: The tag with the fields diff --git a/reflex/config.py b/reflex/config.py index 0579b019f1..c1e6de4a23 100644 --- a/reflex/config.py +++ b/reflex/config.py @@ -406,7 +406,7 @@ def __init__(self, default: Any, internal: bool = False) -> None: self.default = default self.internal = internal - def __set_name__(self, owner, name): + def __set_name__(self, owner: Any, name: str): """Set the name of the descriptor. Args: @@ -415,7 +415,7 @@ def __set_name__(self, owner, name): """ self.name = name - def __get__(self, instance, owner): + def __get__(self, instance: Any, owner: Any): """Get the EnvVar instance. Args: @@ -434,7 +434,7 @@ def __get__(self, instance, owner): if TYPE_CHECKING: - def env_var(default, internal=False) -> EnvVar: + def env_var(default: Any, internal: bool = False) -> EnvVar: """Typing helper for the env_var descriptor. Args: diff --git a/reflex/custom_components/custom_components.py b/reflex/custom_components/custom_components.py index 4a169802f4..1bddfedded 100644 --- a/reflex/custom_components/custom_components.py +++ b/reflex/custom_components/custom_components.py @@ -83,7 +83,7 @@ def _get_package_config(exit_on_fail: bool = True) -> dict: The package configuration. Raises: - Exit: If the pyproject.toml file is not found. + Exit: If the pyproject.toml file is not found and exit_on_fail is True. """ pyproject = Path(CustomComponents.PYPROJECT_TOML) try: diff --git a/reflex/event.py b/reflex/event.py index e4ca55c701..7a5eba8fef 100644 --- a/reflex/event.py +++ b/reflex/event.py @@ -94,7 +94,7 @@ def substate_token(self) -> str: BACKGROUND_TASK_MARKER = "_reflex_background_task" -def background(fn, *, __internal_reflex_call: bool = False): +def background(fn: Callable, *, __internal_reflex_call: bool = False): """Decorator to mark event handler as running in the background. Args: @@ -1036,7 +1036,8 @@ def download( ) -def _callback_arg_spec(eval_result): +# This function seems unused. Check if we still need it. If not, remove in 0.7.0 +def _callback_arg_spec(eval_result: Any): """ArgSpec for call_script callback function. Args: @@ -1141,7 +1142,7 @@ def run_script( return call_function(ArgsFunctionOperation.create((), javascript_code), callback) -def get_event(state, event): +def get_event(state: BaseState, event: str): """Get the event from the given state. Args: @@ -1154,7 +1155,7 @@ def get_event(state, event): return f"{state.get_name()}.{event}" -def get_hydrate_event(state) -> str: +def get_hydrate_event(state: BaseState) -> str: """Get the name of the hydrate event for the state. Args: @@ -1794,13 +1795,13 @@ def __call__(self, *values) -> EventCallback: # type: ignore @overload def __get__( - self: EventCallback[P, T], instance: None, owner + self: EventCallback[P, T], instance: None, owner: Any ) -> EventCallback[P, T]: ... @overload - def __get__(self, instance, owner) -> Callable[P, T]: ... + def __get__(self, instance: Any, owner: Any) -> Callable[P, T]: ... - def __get__(self, instance, owner) -> Callable: # type: ignore + def __get__(self, instance: Any, owner: Any) -> Callable: # type: ignore """Get the function with the instance bound to it. Args: diff --git a/reflex/experimental/hooks.py b/reflex/experimental/hooks.py index 7d648225ac..fb2dc8cae7 100644 --- a/reflex/experimental/hooks.py +++ b/reflex/experimental/hooks.py @@ -11,7 +11,7 @@ def _compose_react_imports(tags: list[str]) -> dict[str, list[ImportVar]]: return {"react": [ImportVar(tag=tag) for tag in tags]} -def const(name, value) -> Var: +def const(name: str | list[str], value: str | Var) -> Var: """Create a constant Var. Args: @@ -26,7 +26,7 @@ def const(name, value) -> Var: return Var(_js_expr=f"const {name} = {value}") -def useCallback(func, deps) -> Var: +def useCallback(func: str, deps: list) -> Var: """Create a useCallback hook with a function and dependencies. Args: @@ -42,7 +42,7 @@ def useCallback(func, deps) -> Var: ) -def useContext(context) -> Var: +def useContext(context: str) -> Var: """Create a useContext hook with a context. Args: @@ -57,7 +57,7 @@ def useContext(context) -> Var: ) -def useRef(default) -> Var: +def useRef(default: str) -> Var: """Create a useRef hook with a default value. Args: @@ -72,7 +72,7 @@ def useRef(default) -> Var: ) -def useState(var_name, default=None) -> Var: +def useState(var_name: str, default: str | None = None) -> Var: """Create a useState hook with a variable name and setter name. Args: diff --git a/reflex/experimental/misc.py b/reflex/experimental/misc.py index a2a5a0615d..986729881c 100644 --- a/reflex/experimental/misc.py +++ b/reflex/experimental/misc.py @@ -1,16 +1,16 @@ """Miscellaneous functions for the experimental package.""" import asyncio -from typing import Any +from typing import Any, Callable -async def run_in_thread(func) -> Any: +async def run_in_thread(func: Callable) -> Any: """Run a function in a separate thread. To not block the UI event queue, run_in_thread must be inside inside a rx.event(background=True) decorated method. Args: - func (callable): The non-async function to run. + func: The non-async function to run. Raises: ValueError: If the function is an async function. diff --git a/reflex/istate/wrappers.py b/reflex/istate/wrappers.py index d4e74cf8a8..865bd6c638 100644 --- a/reflex/istate/wrappers.py +++ b/reflex/istate/wrappers.py @@ -6,7 +6,7 @@ from reflex.state import _split_substate_key, _substate_key, get_state_manager -async def get_state(token, state_cls: Any | None = None) -> ReadOnlyStateProxy: +async def get_state(token: str, state_cls: Any | None = None) -> ReadOnlyStateProxy: """Get the instance of a state for a token. Args: diff --git a/reflex/model.py b/reflex/model.py index cb8bed29bb..4f9cf11722 100644 --- a/reflex/model.py +++ b/reflex/model.py @@ -18,6 +18,7 @@ import sqlalchemy.exc import sqlalchemy.ext.asyncio import sqlalchemy.orm +from alembic.runtime.migration import MigrationContext from reflex.base import Base from reflex.config import environment, get_config @@ -263,7 +264,7 @@ def __init_subclass__(cls): super().__init_subclass__() @classmethod - def _dict_recursive(cls, value): + def _dict_recursive(cls, value: Any): """Recursively serialize the relationship object(s). Args: @@ -395,7 +396,11 @@ def alembic_autogenerate( writer = alembic.autogenerate.rewriter.Rewriter() @writer.rewrites(alembic.operations.ops.AddColumnOp) - def render_add_column_with_server_default(context, revision, op): + def render_add_column_with_server_default( + context: MigrationContext, + revision: str | None, + op: Any, + ): # Carry the sqlmodel default as server_default so that newly added # columns get the desired default value in existing rows. if op.column.default is not None and op.column.server_default is None: @@ -404,7 +409,7 @@ def render_add_column_with_server_default(context, revision, op): ) return op - def run_autogenerate(rev, context): + def run_autogenerate(rev: str, context: MigrationContext): revision_context.run_autogenerate(rev, context) return [] @@ -446,7 +451,7 @@ def _alembic_upgrade( """ config, script_directory = cls._alembic_config() - def run_upgrade(rev, context): + def run_upgrade(rev: str, context: MigrationContext): return script_directory._upgrade_revs(to_rev, rev) with alembic.runtime.environment.EnvironmentContext( diff --git a/reflex/page.py b/reflex/page.py index 8cc0317571..06eadb1842 100644 --- a/reflex/page.py +++ b/reflex/page.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections import defaultdict -from typing import Any, Dict, List +from typing import Any, Callable, Dict, List from reflex.config import get_config from reflex.event import BASE_STATE, EventType @@ -42,7 +42,7 @@ def page( The decorated function. """ - def decorator(render_fn): + def decorator(render_fn: Callable): kwargs = {} if route: kwargs["route"] = route @@ -66,7 +66,7 @@ def decorator(render_fn): return decorator -def get_decorated_pages(omit_implicit_routes=True) -> list[dict[str, Any]]: +def get_decorated_pages(omit_implicit_routes: bool = True) -> list[dict[str, Any]]: """Get the decorated pages. Args: diff --git a/reflex/reflex.py b/reflex/reflex.py index 20866941f5..50cc5b3a88 100644 --- a/reflex/reflex.py +++ b/reflex/reflex.py @@ -125,8 +125,8 @@ def _run( env: constants.Env = constants.Env.DEV, frontend: bool = True, backend: bool = True, - frontend_port: str = str(config.frontend_port), - backend_port: str = str(config.backend_port), + frontend_port: int = config.frontend_port, + backend_port: int = config.backend_port, backend_host: str = config.backend_host, loglevel: constants.LogLevel = config.loglevel, ): @@ -160,18 +160,22 @@ def _run( # Find the next available open port if applicable. if frontend: frontend_port = processes.handle_port( - "frontend", frontend_port, str(constants.DefaultPorts.FRONTEND_PORT) + "frontend", + frontend_port, + constants.DefaultPorts.FRONTEND_PORT, ) if backend: backend_port = processes.handle_port( - "backend", backend_port, str(constants.DefaultPorts.BACKEND_PORT) + "backend", + backend_port, + constants.DefaultPorts.BACKEND_PORT, ) # Apply the new ports to the config. - if frontend_port != str(config.frontend_port): + if frontend_port != config.frontend_port: config._set_persistent(frontend_port=frontend_port) - if backend_port != str(config.backend_port): + if backend_port != config.backend_port: config._set_persistent(backend_port=backend_port) # Reload the config to make sure the env vars are persistent. @@ -262,10 +266,10 @@ def run( help="Execute only backend.", envvar=environment.REFLEX_BACKEND_ONLY.name, ), - frontend_port: str = typer.Option( + frontend_port: int = typer.Option( config.frontend_port, help="Specify a different frontend port." ), - backend_port: str = typer.Option( + backend_port: int = typer.Option( config.backend_port, help="Specify a different backend port." ), backend_host: str = typer.Option( diff --git a/reflex/route.py b/reflex/route.py index 0b71728248..3f49f66e90 100644 --- a/reflex/route.py +++ b/reflex/route.py @@ -103,7 +103,7 @@ def catchall_prefix(route: str) -> str: return route.replace(pattern, "") if pattern else "" -def replace_brackets_with_keywords(input_string): +def replace_brackets_with_keywords(input_string: str) -> str: """Replace brackets and everything inside it in a string with a keyword. Args: diff --git a/reflex/state.py b/reflex/state.py index b181090da1..c1496b547a 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -31,6 +31,7 @@ Optional, Sequence, Set, + SupportsIndex, Tuple, Type, TypeVar, @@ -1053,7 +1054,7 @@ def _set_var(cls, prop: Var): setattr(cls, prop._var_field_name, prop) @classmethod - def _create_event_handler(cls, fn): + def _create_event_handler(cls, fn: Any): """Create an event handler for the given function. Args: @@ -1171,14 +1172,14 @@ def setup_dynamic_args(cls, args: dict[str, str]): cls._check_overwritten_dynamic_args(list(args.keys())) - def argsingle_factory(param): - def inner_func(self) -> str: + def argsingle_factory(param: str): + def inner_func(self: BaseState) -> str: # type: ignore return self.router.page.params.get(param, "") return inner_func - def arglist_factory(param): - def inner_func(self) -> List[str]: + def arglist_factory(param: str): + def inner_func(self: BaseState) -> List[str]: return self.router.page.params.get(param, []) return inner_func @@ -2534,7 +2535,9 @@ async def bg_increment(self): """ def __init__( - self, state_instance, parent_state_proxy: Optional["StateProxy"] = None + self, + state_instance: BaseState, + parent_state_proxy: Optional["StateProxy"] = None, ): """Create a proxy for a state instance. @@ -3480,7 +3483,9 @@ async def modify_state(self, token: str) -> AsyncIterator[BaseState]: @validator("lock_warning_threshold") @classmethod - def validate_lock_warning_threshold(cls, lock_warning_threshold: int, values): + def validate_lock_warning_threshold( + cls, lock_warning_threshold: int, values: dict[str, int] + ): """Validate the lock warning threshold. Args: @@ -3713,10 +3718,10 @@ def __repr__(self) -> str: def _mark_dirty( self, - wrapped=None, - instance=None, - args=(), - kwargs=None, + wrapped: Callable | None = None, + instance: BaseState | None = None, + args: tuple = (), + kwargs: dict | None = None, ) -> Any: """Mark the state as dirty, then call a wrapped function. @@ -3766,7 +3771,9 @@ def _wrap_recursive(self, value: Any) -> Any: ) return value - def _wrap_recursive_decorator(self, wrapped, instance, args, kwargs) -> Any: + def _wrap_recursive_decorator( + self, wrapped: Callable, instance: BaseState, args: list, kwargs: dict + ) -> Any: """Wrap a function that returns a possibly mutable value. Intended for use with `FunctionWrapper` from the `wrapt` library. @@ -3825,7 +3832,7 @@ def __getattr__(self, __name: str) -> Any: return value - def __getitem__(self, key) -> Any: + def __getitem__(self, key: Any) -> Any: """Get the item on the proxied object and return a proxy if mutable. Args: @@ -3848,7 +3855,7 @@ def __iter__(self) -> Any: # Recursively wrap mutable items retrieved through this proxy. yield self._wrap_recursive(value) - def __delattr__(self, name): + def __delattr__(self, name: str): """Delete the attribute on the proxied object and mark state dirty. Args: @@ -3856,7 +3863,7 @@ def __delattr__(self, name): """ self._mark_dirty(super().__delattr__, args=(name,)) - def __delitem__(self, key): + def __delitem__(self, key: str): """Delete the item on the proxied object and mark state dirty. Args: @@ -3864,7 +3871,7 @@ def __delitem__(self, key): """ self._mark_dirty(super().__delitem__, args=(key,)) - def __setitem__(self, key, value): + def __setitem__(self, key: str, value: Any): """Set the item on the proxied object and mark state dirty. Args: @@ -3873,7 +3880,7 @@ def __setitem__(self, key, value): """ self._mark_dirty(super().__setitem__, args=(key, value)) - def __setattr__(self, name, value): + def __setattr__(self, name: str, value: Any): """Set the attribute on the proxied object and mark state dirty. If the attribute starts with "_self_", then the state is NOT marked @@ -3897,7 +3904,7 @@ def __copy__(self) -> Any: """ return copy.copy(self.__wrapped__) - def __deepcopy__(self, memo=None) -> Any: + def __deepcopy__(self, memo: dict[int, Any] | None = None) -> Any: """Return a deepcopy of the proxy. Args: @@ -3908,7 +3915,7 @@ def __deepcopy__(self, memo=None) -> Any: """ return copy.deepcopy(self.__wrapped__, memo=memo) - def __reduce_ex__(self, protocol_version): + def __reduce_ex__(self, protocol_version: SupportsIndex): """Get the state for redis serialization. This method is called by cloudpickle to serialize the object. @@ -3969,10 +3976,10 @@ class ImmutableMutableProxy(MutableProxy): def _mark_dirty( self, - wrapped=None, - instance=None, - args=(), - kwargs=None, + wrapped: Callable | None = None, + instance: BaseState | None = None, + args: tuple = (), + kwargs: dict | None = None, ) -> Any: """Raise an exception when an attempt is made to modify the object. diff --git a/reflex/style.py b/reflex/style.py index a205cdc4ae..1ca1d1dddb 100644 --- a/reflex/style.py +++ b/reflex/style.py @@ -182,7 +182,9 @@ def convert( var_data = None # Track import/hook data from any Vars in the style dict. out = {} - def update_out_dict(return_value, keys_to_update): + def update_out_dict( + return_value: Var | dict | list | str, keys_to_update: tuple[str, ...] + ): for k in keys_to_update: out[k] = return_value diff --git a/reflex/testing.py b/reflex/testing.py index ca31054b30..c2b2dd9e34 100644 --- a/reflex/testing.py +++ b/reflex/testing.py @@ -89,7 +89,7 @@ class chdir(contextlib.AbstractContextManager): """Non thread-safe context manager to change the current working directory.""" - def __init__(self, path): + def __init__(self, path: str | Path): """Prepare contextmanager. Args: @@ -321,7 +321,7 @@ async def _shutdown_redis(*args, **kwargs) -> None: return _shutdown_redis - def _start_backend(self, port=0): + def _start_backend(self, port: int = 0): if self.app_instance is None: raise RuntimeError("App was not initialized.") self.backend = uvicorn.Server( @@ -425,7 +425,7 @@ def start(self) -> "AppHarness": return self @staticmethod - def get_app_global_source(key, value): + def get_app_global_source(key: str, value: Any): """Get the source code of a global object. If value is a function or class we render the actual source of value otherwise we assign value to key. diff --git a/reflex/utils/build.py b/reflex/utils/build.py index e263374e14..e0c7d15e34 100644 --- a/reflex/utils/build.py +++ b/reflex/utils/build.py @@ -23,7 +23,7 @@ def set_env_json(): ) -def generate_sitemap_config(deploy_url: str, export=False): +def generate_sitemap_config(deploy_url: str, export: bool = False): """Generate the sitemap config file. Args: diff --git a/reflex/utils/compat.py b/reflex/utils/compat.py index e63492a6b2..17429c8a07 100644 --- a/reflex/utils/compat.py +++ b/reflex/utils/compat.py @@ -2,6 +2,7 @@ import contextlib import sys +from typing import Any async def windows_hot_reload_lifespan_hack(): @@ -74,7 +75,7 @@ def pydantic_v1_patch(): import sqlmodel as sqlmodel -def sqlmodel_field_has_primary_key(field) -> bool: +def sqlmodel_field_has_primary_key(field: Any) -> bool: """Determines if a field is a priamary. Args: diff --git a/reflex/utils/exec.py b/reflex/utils/exec.py index 621c4a608a..986f80aa9d 100644 --- a/reflex/utils/exec.py +++ b/reflex/utils/exec.py @@ -71,7 +71,7 @@ def notify_backend(): # run_process_and_launch_url is assumed to be used # only to launch the frontend # If this is not the case, might have to change the logic -def run_process_and_launch_url(run_command: list[str], backend_present=True): +def run_process_and_launch_url(run_command: list[str], backend_present: bool = True): """Run the process and launch the URL. Args: @@ -134,7 +134,7 @@ def run_process_and_launch_url(run_command: list[str], backend_present=True): break # while True -def run_frontend(root: Path, port: str, backend_present=True): +def run_frontend(root: Path, port: str, backend_present: bool = True): """Run the frontend. Args: @@ -156,7 +156,7 @@ def run_frontend(root: Path, port: str, backend_present=True): ) -def run_frontend_prod(root: Path, port: str, backend_present=True): +def run_frontend_prod(root: Path, port: str, backend_present: bool = True): """Run the frontend. Args: @@ -240,7 +240,7 @@ def run_backend( run_uvicorn_backend(host, port, loglevel) -def run_uvicorn_backend(host, port, loglevel: LogLevel): +def run_uvicorn_backend(host: str, port: int, loglevel: LogLevel): """Run the backend in development mode using Uvicorn. Args: @@ -260,7 +260,7 @@ def run_uvicorn_backend(host, port, loglevel: LogLevel): ) -def run_granian_backend(host, port, loglevel: LogLevel): +def run_granian_backend(host: str, port: int, loglevel: LogLevel): """Run the backend in development mode using Granian. Args: @@ -325,7 +325,7 @@ def run_backend_prod( run_uvicorn_backend_prod(host, port, loglevel) -def run_uvicorn_backend_prod(host, port, loglevel): +def run_uvicorn_backend_prod(host: str, port: int, loglevel: LogLevel): """Run the backend in production mode using Uvicorn. Args: @@ -377,7 +377,7 @@ def run_uvicorn_backend_prod(host, port, loglevel): ) -def run_granian_backend_prod(host, port, loglevel): +def run_granian_backend_prod(host: str, port: int, loglevel: LogLevel): """Run the backend in production mode using Granian. Args: diff --git a/reflex/utils/format.py b/reflex/utils/format.py index 1d6671a0bb..077ba9d15a 100644 --- a/reflex/utils/format.py +++ b/reflex/utils/format.py @@ -221,7 +221,7 @@ def _escape_js_string(string: str) -> str: """ # TODO: we may need to re-vist this logic after new Var API is implemented. - def escape_outside_segments(segment): + def escape_outside_segments(segment: str): """Escape backticks in segments outside of `${}`. Args: @@ -284,7 +284,7 @@ def format_var(var: Var) -> str: return str(var) -def format_route(route: str, format_case=True) -> str: +def format_route(route: str, format_case: bool = True) -> str: """Format the given route. Args: diff --git a/reflex/utils/lazy_loader.py b/reflex/utils/lazy_loader.py index 61e3967e58..eba89532d7 100644 --- a/reflex/utils/lazy_loader.py +++ b/reflex/utils/lazy_loader.py @@ -1,11 +1,17 @@ """Module to implement lazy loading in reflex.""" +from __future__ import annotations + import copy import lazy_loader as lazy -def attach(package_name, submodules=None, submod_attrs=None): +def attach( + package_name: str, + submodules: set | None = None, + submod_attrs: dict | None = None, +): """Replaces a package's __getattr__, __dir__, and __all__ attributes using lazy.attach. The lazy loader __getattr__ doesn't support tuples as list values. We needed to add this functionality (tuples) in Reflex to support 'import as _' statements. This function diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index 25e753d093..f9fb79cab5 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -669,7 +669,9 @@ def init_reflex_json(project_hash: int | None): path_ops.update_json_file(get_web_dir() / constants.Reflex.JSON, reflex_json) -def update_next_config(export=False, transpile_packages: Optional[List[str]] = None): +def update_next_config( + export: bool = False, transpile_packages: Optional[List[str]] = None +): """Update Next.js config from Reflex config. Args: @@ -911,7 +913,7 @@ def cached_procedure(cache_file: str, payload_fn: Callable[..., str]): The decorated function. """ - def _inner_decorator(func): + def _inner_decorator(func: Callable): def _inner(*args, **kwargs): payload = _read_cached_procedure_file(cache_file) new_payload = payload_fn(*args, **kwargs) @@ -1096,7 +1098,7 @@ def validate_bun(): raise typer.Exit(1) -def validate_frontend_dependencies(init=True): +def validate_frontend_dependencies(init: bool = True): """Validate frontend dependencies to ensure they meet requirements. Args: @@ -1398,7 +1400,9 @@ def initialize_default_app(app_name: str): initialize_app_directory(app_name) -def validate_and_create_app_using_remote_template(app_name, template, templates): +def validate_and_create_app_using_remote_template( + app_name: str, template: str, templates: dict[str, Template] +): """Validate and create an app using a remote template. Args: @@ -1610,7 +1614,7 @@ def initialize_main_module_index_from_generation(app_name: str, generation_hash: ) render_func_name = defined_funcs[-1] - def replace_content(_match): + def replace_content(_match: re.Match) -> str: return "\n".join( [ resp.text, @@ -1640,7 +1644,7 @@ def replace_content(_match): main_module_path.write_text(main_module_code) -def format_address_width(address_width) -> int | None: +def format_address_width(address_width: str | None) -> int | None: """Cast address width to an int. Args: diff --git a/reflex/utils/processes.py b/reflex/utils/processes.py index ef2d364014..547109bc08 100644 --- a/reflex/utils/processes.py +++ b/reflex/utils/processes.py @@ -15,12 +15,13 @@ import psutil import typer from redis.exceptions import RedisError +from rich.progress import Progress from reflex import constants from reflex.utils import console, path_ops, prerequisites -def kill(pid): +def kill(pid: int): """Kill a process. Args: @@ -48,7 +49,7 @@ def get_num_workers() -> int: return (os.cpu_count() or 1) * 2 + 1 -def get_process_on_port(port) -> Optional[psutil.Process]: +def get_process_on_port(port: int) -> Optional[psutil.Process]: """Get the process on the given port. Args: @@ -71,7 +72,7 @@ def get_process_on_port(port) -> Optional[psutil.Process]: return None -def is_process_on_port(port) -> bool: +def is_process_on_port(port: int) -> bool: """Check if a process is running on the given port. Args: @@ -83,7 +84,7 @@ def is_process_on_port(port) -> bool: return get_process_on_port(port) is not None -def kill_process_on_port(port): +def kill_process_on_port(port: int): """Kill the process on the given port. Args: @@ -94,7 +95,7 @@ def kill_process_on_port(port): get_process_on_port(port).kill() # type: ignore -def change_port(port: str, _type: str) -> str: +def change_port(port: int, _type: str) -> int: """Change the port. Args: @@ -105,7 +106,7 @@ def change_port(port: str, _type: str) -> str: The new port. """ - new_port = str(int(port) + 1) + new_port = port + 1 if is_process_on_port(new_port): return change_port(new_port, _type) console.info( @@ -114,7 +115,7 @@ def change_port(port: str, _type: str) -> str: return new_port -def handle_port(service_name: str, port: str, default_port: str) -> str: +def handle_port(service_name: str, port: int, default_port: int) -> int: """Change port if the specified port is in use and is not explicitly specified as a CLI arg or config arg. otherwise tell the user the port is in use and exit the app. @@ -133,7 +134,7 @@ def handle_port(service_name: str, port: str, default_port: str) -> str: Exit:when the port is in use. """ if is_process_on_port(port): - if int(port) == int(default_port): + if port == int(default_port): return change_port(port, service_name) else: console.error(f"{service_name.capitalize()} port: {port} is already in use") @@ -141,7 +142,12 @@ def handle_port(service_name: str, port: str, default_port: str) -> str: return port -def new_process(args, run: bool = False, show_logs: bool = False, **kwargs): +def new_process( + args: str | list[str | Path | None] | list[str], + run: bool = False, + show_logs: bool = False, + **kwargs, +): """Wrapper over subprocess.Popen to unify the launch of child processes. Args: @@ -163,7 +169,7 @@ def new_process(args, run: bool = False, show_logs: bool = False, **kwargs): "installed and added to your system's PATH environment variable or try running " "`reflex init` again." ) - if None in args: + if isinstance(args, list) and None in args: console.error(f"Invalid command: {args}") raise typer.Exit(1) # Add the node bin path to the PATH environment variable. @@ -185,7 +191,7 @@ def new_process(args, run: bool = False, show_logs: bool = False, **kwargs): } console.debug(f"Running command: {args}") fn = subprocess.run if run else subprocess.Popen - return fn(args, **kwargs) + return fn(args, **kwargs) # type: ignore @contextlib.contextmanager @@ -241,7 +247,7 @@ def run_concurrently(*fns: Union[Callable, Tuple]) -> None: def stream_logs( message: str, process: subprocess.Popen, - progress=None, + progress: Progress | None = None, suppress_errors: bool = False, analytics_enabled: bool = False, ): @@ -369,10 +375,10 @@ def get_command_with_loglevel(command: list[str]) -> list[str]: def run_process_with_fallback( - args, + args: list[str], *, - show_status_message, - fallback=None, + show_status_message: str, + fallback: str | list | None = None, analytics_enabled: bool = False, **kwargs, ): @@ -411,7 +417,7 @@ def run_process_with_fallback( ) -def execute_command_and_return_output(command) -> str | None: +def execute_command_and_return_output(command: str) -> str | None: """Execute a command and return the output. Args: diff --git a/reflex/utils/pyi_generator.py b/reflex/utils/pyi_generator.py index c3a7b0ed12..0facf58797 100644 --- a/reflex/utils/pyi_generator.py +++ b/reflex/utils/pyi_generator.py @@ -83,7 +83,7 @@ } -def _walk_files(path): +def _walk_files(path: str | Path): """Walk all files in a path. This can be replaced with Path.walk() in python3.12. @@ -114,7 +114,9 @@ def _relative_to_pwd(path: Path) -> Path: return path -def _get_type_hint(value, type_hint_globals, is_optional=True) -> str: +def _get_type_hint( + value: Any, type_hint_globals: dict, is_optional: bool = True +) -> str: """Resolve the type hint for value. Args: @@ -383,7 +385,7 @@ def _extract_class_props_as_ast_nodes( return kwargs -def type_to_ast(typ, cls: type) -> ast.AST: +def type_to_ast(typ: Any, cls: type) -> ast.AST: """Converts any type annotation into its AST representation. Handles nested generic types, unions, etc. @@ -441,7 +443,7 @@ def type_to_ast(typ, cls: type) -> ast.AST: ) -def _get_parent_imports(func): +def _get_parent_imports(func: Callable): _imports = {"reflex.vars": ["Var"]} for type_hint in inspect.get_annotations(func).values(): try: @@ -1050,7 +1052,7 @@ def _write_pyi_file(self, module_path: Path, source: str): pyi_path.write_text(pyi_content) logger.info(f"Wrote {relpath}") - def _get_init_lazy_imports(self, mod, new_tree): + def _get_init_lazy_imports(self, mod: tuple | ModuleType, new_tree: ast.AST): # retrieve the _SUBMODULES and _SUBMOD_ATTRS from an init file if present. sub_mods = getattr(mod, "_SUBMODULES", None) sub_mod_attrs = getattr(mod, "_SUBMOD_ATTRS", None) @@ -1136,7 +1138,7 @@ def _scan_files(self, files: list[Path]): if pyi_path: self.written_files.append(pyi_path) - def scan_all(self, targets, changed_files: list[Path] | None = None): + def scan_all(self, targets: list, changed_files: list[Path] | None = None): """Scan all targets for class inheriting Component and generate the .pyi files. Args: diff --git a/reflex/utils/registry.py b/reflex/utils/registry.py index d98178c618..47727d6599 100644 --- a/reflex/utils/registry.py +++ b/reflex/utils/registry.py @@ -22,15 +22,15 @@ def latency(registry: str) -> int: return 10_000_000 -def average_latency(registry, attempts: int = 3) -> int: +def average_latency(registry: str, attempts: int = 3) -> int: """Get the average latency of a registry. Args: - registry (str): The URL of the registry. - attempts (int): The number of attempts to make. Defaults to 10. + registry: The URL of the registry. + attempts: The number of attempts to make. Defaults to 10. Returns: - int: The average latency of the registry in microseconds. + The average latency of the registry in microseconds. """ return sum(latency(registry) for _ in range(attempts)) // attempts diff --git a/reflex/utils/telemetry.py b/reflex/utils/telemetry.py index b24b4d3bf0..eb4e1c27ed 100644 --- a/reflex/utils/telemetry.py +++ b/reflex/utils/telemetry.py @@ -160,7 +160,7 @@ def _send_event(event_data: dict) -> bool: return False -def _send(event, telemetry_enabled, **kwargs): +def _send(event: str, telemetry_enabled: bool | None, **kwargs): from reflex.config import get_config # Get the telemetry_enabled from the config if it is not specified. @@ -186,7 +186,7 @@ def send(event: str, telemetry_enabled: bool | None = None, **kwargs): kwargs: Additional data to send with the event. """ - async def async_send(event, telemetry_enabled, **kwargs): + async def async_send(event: str, telemetry_enabled: bool | None, **kwargs): return _send(event, telemetry_enabled, **kwargs) try: diff --git a/reflex/utils/types.py b/reflex/utils/types.py index b8bcbf2d69..011f4da7e8 100644 --- a/reflex/utils/types.py +++ b/reflex/utils/types.py @@ -153,7 +153,7 @@ def __bool__(self) -> bool: @lru_cache() -def get_origin(tp): +def get_origin(tp: Any): """Get the origin of a class. Args: @@ -236,7 +236,7 @@ def is_literal(cls: GenericType) -> bool: return get_origin(cls) is Literal -def has_args(cls) -> bool: +def has_args(cls: Type) -> bool: """Check if the class has generic parameters. Args: @@ -747,7 +747,7 @@ def check_prop_in_allowed_types(prop: Any, allowed_types: Iterable) -> bool: return type_ in allowed_types -def is_encoded_fstring(value) -> bool: +def is_encoded_fstring(value: Any) -> bool: """Check if a value is an encoded Var f-string. Args: @@ -790,7 +790,7 @@ def validate_literal(key: str, value: Any, expected_type: Type, comp_name: str): ) -def validate_parameter_literals(func): +def validate_parameter_literals(func: Callable): """Decorator to check that the arguments passed to a function correspond to the correct function parameter if it (the parameter) is a literal type. diff --git a/reflex/vars/base.py b/reflex/vars/base.py index 094a478c8c..6286eddd5e 100644 --- a/reflex/vars/base.py +++ b/reflex/vars/base.py @@ -432,7 +432,7 @@ def __init_subclass__( frozen=True, **{"slots": True} if sys.version_info >= (3, 10) else {}, ) - class ToVarOperation(ToOperation, cls): + class ToVarOperation(ToOperation, cls): # type: ignore """Base class of converting a var to another var type.""" _original: Var = dataclasses.field( @@ -490,20 +490,30 @@ def equals(self, other: Var) -> bool: @overload def _replace( - self, _var_type: Type[OTHER_VAR_TYPE], merge_var_data=None, **kwargs: Any + self, + _var_type: Type[OTHER_VAR_TYPE], + merge_var_data: VarData | None = None, + **kwargs: Any, ) -> Var[OTHER_VAR_TYPE]: ... @overload def _replace( - self, _var_type: GenericType | None = None, merge_var_data=None, **kwargs: Any + self, + _var_type: GenericType | None = None, + merge_var_data: VarData | None = None, + **kwargs: Any, ) -> Self: ... def _replace( - self, _var_type: GenericType | None = None, merge_var_data=None, **kwargs: Any + self, + _var_type: GenericType | None = None, + merge_var_data: VarData | None = None, + **kwargs: Any, ) -> Self | Var: """Make a copy of this Var with updated fields. Args: + _var_type: The new type of the Var. merge_var_data: VarData to merge into the existing VarData. **kwargs: Var fields to update. @@ -903,7 +913,7 @@ def _var_set_state(self, state: type[BaseState] | str): ), ).guess_type() - def __eq__(self, other: Var | Any) -> BooleanVar: + def __eq__(self, other: Var | Any) -> BooleanVar: # type: ignore """Check if the current variable is equal to the given variable. Args: @@ -916,7 +926,7 @@ def __eq__(self, other: Var | Any) -> BooleanVar: return equal_operation(self, other) - def __ne__(self, other: Var | Any) -> BooleanVar: + def __ne__(self, other: Var | Any) -> BooleanVar: # type: ignore """Check if the current object is not equal to the given object. Parameters: @@ -1334,7 +1344,7 @@ def __init_subclass__(cls, **kwargs): _var_literal_subclasses.append((cls, var_subclass)) @classmethod - def create( + def create( # type: ignore cls, value: Any, _var_data: VarData | None = None, @@ -1461,7 +1471,7 @@ def get_python_literal(value: Union[LiteralVar, Any]) -> Any | None: # NoReturn is used to match CustomVarOperationReturn with no type hint. @overload -def var_operation( +def var_operation( # type: ignore func: Callable[P, CustomVarOperationReturn[NoReturn]], ) -> Callable[P, Var]: ... @@ -1511,7 +1521,7 @@ def var_operation( ) -> Callable[P, Var[T]]: ... -def var_operation( +def var_operation( # type: ignore func: Callable[P, CustomVarOperationReturn[T]], ) -> Callable[P, Var[T]]: """Decorator for creating a var operation. @@ -1582,7 +1592,7 @@ def figure_out_type(value: Any) -> types.GenericType: class cached_property_no_lock(functools.cached_property): """A special version of functools.cached_property that does not use a lock.""" - def __init__(self, func): + def __init__(self, func: Callable): """Initialize the cached_property_no_lock. Args: @@ -1755,7 +1765,7 @@ def __init__(self, fn: Callable[..., Var]): object.__setattr__(self, "fn", fn) object.__setattr__(self, "original_var", original_var) - def __call__(self, *args, **kwargs) -> Var: + def __call__(self, *args: Any, **kwargs: Any) -> Var: """Call the decorated function. Args: @@ -1916,10 +1926,16 @@ def __init__( object.__setattr__(self, "_fget", fget) @override - def _replace(self, merge_var_data=None, **kwargs: Any) -> Self: + def _replace( + self, + _var_type: Any = None, + merge_var_data: VarData | None = None, + **kwargs: Any, + ) -> Self: """Replace the attributes of the ComputedVar. Args: + _var_type: ignored in ComputedVar. merge_var_data: VarData to merge into the existing VarData. **kwargs: Var fields to update. @@ -2032,7 +2048,7 @@ def __get__(self, instance: None, owner: Type) -> ComputedVar[RETURN_TYPE]: ... @overload def __get__(self, instance: BaseState, owner: Type) -> RETURN_TYPE: ... - def __get__(self, instance: BaseState | None, owner): + def __get__(self, instance: BaseState | None, owner: Type): """Get the ComputedVar value. If the value is already cached on the instance, return the cached value. @@ -2198,7 +2214,7 @@ def _deps( self_is_top_of_stack = False return d - def mark_dirty(self, instance) -> None: + def mark_dirty(self, instance: BaseState) -> None: """Mark this ComputedVar as dirty. Args: @@ -2917,7 +2933,7 @@ def dispatch( class Field(Generic[T]): """Shadow class for Var to allow for type hinting in the IDE.""" - def __set__(self, instance, value: T): + def __set__(self, instance: Any, value: T): """Set the Var. Args: @@ -2926,41 +2942,41 @@ def __set__(self, instance, value: T): """ @overload - def __get__(self: Field[bool], instance: None, owner) -> BooleanVar: ... + def __get__(self: Field[bool], instance: None, owner: Any) -> BooleanVar: ... @overload - def __get__(self: Field[int], instance: None, owner) -> NumberVar: ... + def __get__(self: Field[int], instance: None, owner: Any) -> NumberVar: ... @overload - def __get__(self: Field[str], instance: None, owner) -> StringVar: ... + def __get__(self: Field[str], instance: None, owner: Any) -> StringVar: ... @overload - def __get__(self: Field[None], instance: None, owner) -> NoneVar: ... + def __get__(self: Field[None], instance: None, owner: Any) -> NoneVar: ... @overload def __get__( self: Field[List[V]] | Field[Set[V]] | Field[Tuple[V, ...]], instance: None, - owner, + owner: Any, ) -> ArrayVar[List[V]]: ... @overload def __get__( - self: Field[Dict[str, V]], instance: None, owner + self: Field[Dict[str, V]], instance: None, owner: Any ) -> ObjectVar[Dict[str, V]]: ... @overload def __get__( - self: Field[BASE_TYPE], instance: None, owner + self: Field[BASE_TYPE], instance: None, owner: Any ) -> ObjectVar[BASE_TYPE]: ... @overload - def __get__(self, instance: None, owner) -> Var[T]: ... + def __get__(self, instance: None, owner: Any) -> Var[T]: ... @overload - def __get__(self, instance, owner) -> T: ... + def __get__(self, instance: Any, owner: Any) -> T: ... - def __get__(self, instance, owner): # type: ignore + def __get__(self, instance: Any, owner: Any): # type: ignore """Get the Var. Args: diff --git a/reflex/vars/function.py b/reflex/vars/function.py index 2a7d50e1b5..d23d1aa13d 100644 --- a/reflex/vars/function.py +++ b/reflex/vars/function.py @@ -210,6 +210,7 @@ def create( Args: func: The function to call. + _var_type: The type of the Var. _var_data: Additional hooks and imports associated with the Var. Returns: @@ -268,6 +269,7 @@ def create( Args: func: The function to call. *args: The arguments to call the function with. + _var_type: The type of the Var. _var_data: Additional hooks and imports associated with the Var. Returns: @@ -385,6 +387,7 @@ def create( return_expr: The return expression of the function. rest: The name of the rest argument. explicit_return: Whether to use explicit return syntax. + _var_type: The type of the Var. _var_data: Additional hooks and imports associated with the Var. Returns: @@ -440,6 +443,7 @@ def create( return_expr: The return expression of the function. rest: The name of the rest argument. explicit_return: Whether to use explicit return syntax. + _var_type: The type of the Var. _var_data: Additional hooks and imports associated with the Var. Returns: diff --git a/reflex/vars/object.py b/reflex/vars/object.py index 5de431f5ab..70bd2401c2 100644 --- a/reflex/vars/object.py +++ b/reflex/vars/object.py @@ -245,7 +245,7 @@ def __getattr__( name: str, ) -> ObjectItemOperation: ... - def __getattr__(self, name) -> Var: + def __getattr__(self, name: str) -> Var: """Get an attribute of the var. Args: diff --git a/reflex/vars/sequence.py b/reflex/vars/sequence.py index 476c1e32c4..765090eba8 100644 --- a/reflex/vars/sequence.py +++ b/reflex/vars/sequence.py @@ -743,7 +743,7 @@ def create( """Create a var from a string value. Args: - value: The values to concatenate. + *value: The values to concatenate. _var_data: Additional hooks and imports associated with the Var. Returns: @@ -1286,6 +1286,7 @@ def create( Args: value: The value to create the var from. + _var_type: The type of the var. _var_data: Additional hooks and imports associated with the Var. Returns: @@ -1581,7 +1582,9 @@ def array_contains_field_operation( @var_operation -def array_contains_operation(haystack: ArrayVar, needle: Any | Var): +def array_contains_operation( + haystack: ArrayVar, needle: Any | Var +) -> CustomVarOperationReturn[bool]: """Check if an array contains an element. Args: @@ -1624,7 +1627,7 @@ def repeat_array_operation( def map_array_operation( array: ArrayVar[ARRAY_VAR_TYPE], function: FunctionVar, -): +) -> CustomVarOperationReturn[List[Any]]: """Map a function over an array. Args: diff --git a/scripts/wait_for_listening_port.py b/scripts/wait_for_listening_port.py index 857ee7c6d8..657e8db502 100644 --- a/scripts/wait_for_listening_port.py +++ b/scripts/wait_for_listening_port.py @@ -14,7 +14,7 @@ import psutil -def _pid_exists(pid): +def _pid_exists(pid: int): # os.kill(pid, 0) doesn't work on Windows (actually kills the PID) # psutil.pid_exists() doesn't work on Windows (does os.kill underneath) # psutil.pids() seems to return the right thing. Inefficient but doesn't matter - keeps things simple. @@ -23,7 +23,7 @@ def _pid_exists(pid): return pid in psutil.pids() -def _wait_for_port(port, server_pid, timeout) -> Tuple[bool, str]: +def _wait_for_port(port: int, server_pid: int, timeout: float) -> Tuple[bool, str]: start = time.time() print(f"Waiting for up to {timeout} seconds for port {port} to start listening.") while True: