Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/check_outdated_dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ jobs:
echo "Outdated:"
echo "$outdated"

filtered_outdated=$(echo "$outdated" | grep -vE 'pyright|ruff' || true)
filtered_outdated=$(echo "$outdated" | grep -vE 'ty|ruff' || true)

if [ ! -z "$filtered_outdated" ]; then
echo "Outdated dependencies found:"
echo "$filtered_outdated"
exit 1
else
echo "All dependencies are up to date. (pyright and ruff are ignored)"
echo "All dependencies are up to date. (ty and ruff are ignored)"
fi

frontend:
Expand Down
7 changes: 4 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ repos:
require_serial: true
- repo: local
hooks:
- id: pyright
name: pyright
entry: pyright
- id: ty
name: ty
entry: ty check
language: system
types: [python]
pass_filenames: false
require_serial: true
- repo: https://github.com/biomejs/pre-commit
rev: 19865851e014cbe6138e295365f95ca51bf953f8 # v0.6.1
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ uv run pytest tests/units --cov --no-cov-on-fail --cov-report= # unit tests (>
uv run pytest tests/integration # integration tests (slow)
uv run ruff check . # lint
uv run ruff format . # format
uv run pyright reflex tests # type check
uv run ty check # type check
uv run python scripts/make_pyi.py # regenerate .pyi stubs
uv run pre-commit run --all-files # all pre-commit hooks
```
Expand Down Expand Up @@ -122,7 +122,7 @@ if TYPE_CHECKING:
Before submitting:
1. Tests pass with adequate coverage
2. `uv run ruff check .` and `uv run ruff format .` clean
3. `uv run pyright reflex tests` passes
3. `uv run ty check` passes
4. `pyi_hashes.json` updated if components changed
5. Documentation updated if user-facing behavior changed
6. Deprecation warnings added if breaking changes introduced
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Next make sure all the following tests pass. This ensures that every new change

```bash
uv run ruff check .
uv run pyright reflex tests
uv run ty check
```

Finally, run `ruff` to format your code.
Expand All @@ -82,7 +82,7 @@ Finally, run `ruff` to format your code.
uv run ruff format .
```

Consider installing git pre-commit hooks so Ruff, Pyright, and `make_pyi` will run automatically before each commit.
Consider installing git pre-commit hooks so Ruff, ty, and `make_pyi` will run automatically before each commit.

```bash
uv run pre-commit install
Expand Down
2 changes: 1 addition & 1 deletion docs/app/reflex_docs/pages/docs/cloud_cliref.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def process_command(command: click.Command, name: str) -> str:


if find_spec("typer") is not None and find_spec("typer.main") is not None:
import typer # pyright: ignore[reportMissingImports]
import typer # ty: ignore[unresolved-import]

if isinstance(cli, typer.Typer):
cli = typer.main.get_command(cli)
Expand Down
12 changes: 6 additions & 6 deletions docs/app/reflex_docs/templates/docpage/sidebar/sidebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,17 +609,17 @@ def sidebar_comp(
html_lib_index,
url,
),
rx.link( # pyright: ignore [reportCallIssue]
rx.box( # pyright: ignore [reportCallIssue]
rx.box( # pyright: ignore [reportCallIssue]
rx.icon("atom", size=16), # pyright: ignore [reportCallIssue]
rx.link( # ty:ignore[missing-argument, unknown-argument, call-non-callable, too-many-positional-arguments, no-matching-overload]
rx.box( # ty:ignore[missing-argument, unknown-argument, call-non-callable, too-many-positional-arguments, no-matching-overload]
rx.box( # ty:ignore[missing-argument, unknown-argument, call-non-callable, too-many-positional-arguments, no-matching-overload]
rx.icon("atom", size=16), # ty:ignore[missing-argument, unknown-argument, call-non-callable, too-many-positional-arguments, no-matching-overload]
rx.el.h5(
"Custom Components",
class_name="font-smbold text-[0.875rem] text-slate-12 leading-5 tracking-[-0.01313rem] transition-color",
),
class_name="flex flex-row items-center gap-3 text-slate-12",
),
rx.text( # pyright: ignore [reportCallIssue]
rx.text( # ty:ignore[missing-argument, unknown-argument, call-non-callable, too-many-positional-arguments, no-matching-overload]
"See what components people have made with Reflex!",
class_name="font-small text-slate-9",
),
Expand Down Expand Up @@ -693,7 +693,7 @@ def sidebar_comp(
class_name="m-0 p-0 flex flex-col items-start gap-8 w-full list-none list-style-none",
)

return rx.box( # pyright: ignore [reportCallIssue]
return rx.box( # ty:ignore[missing-argument, unknown-argument, call-non-callable, too-many-positional-arguments, no-matching-overload]
categories,
content,
style={
Expand Down
2 changes: 1 addition & 1 deletion docs/app/reflex_docs/utils/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def once(f: Callable[[], T]) -> Callable[[], T]:
def wrapper() -> T:
nonlocal value
value = f() if value is unset else value
return value # pyright: ignore[reportReturnType]
return value # ty: ignore[invalid-return-type]

return wrapper

Expand Down
2 changes: 1 addition & 1 deletion docs/getting_started/chat_tutorial_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import os

import openai # pyright: ignore[reportMissingImports]
import openai # ty: ignore[unresolved-import]

import reflex as rx

Expand Down
62 changes: 32 additions & 30 deletions packages/reflex-base/src/reflex_base/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import builtins
import contextlib
import dataclasses
import enum
Expand Down Expand Up @@ -111,7 +112,7 @@ def field(
default_factory: Callable[[], FIELD_TYPE] | None = None,
is_javascript_property: bool | None = None,
doc: str | None = None,
) -> FIELD_TYPE:
) -> Any:
"""Create a field for a component.

Args:
Expand All @@ -129,7 +130,7 @@ def field(
if default is not MISSING and default_factory is not None:
msg = "cannot specify both default and default_factory"
raise ValueError(msg)
return ComponentField( # pyright: ignore [reportReturnType]
return ComponentField(
default=default,
default_factory=default_factory,
is_javascript=is_javascript_property,
Expand Down Expand Up @@ -401,7 +402,7 @@ def _get_all_imports(self) -> ParsedImportDict:
"""

@abstractmethod
def _get_all_dynamic_imports(self) -> set[str]:
def _get_all_dynamic_imports(self) -> builtins.set[str]:
"""Get dynamic imports for the component.

Returns:
Expand All @@ -428,7 +429,7 @@ def _get_all_refs(self) -> dict[str, None]:
class ComponentNamespace(SimpleNamespace):
"""A namespace to manage components with subcomponents."""

def __hash__(self) -> int: # pyright: ignore [reportIncompatibleVariableOverride]
def __hash__(self) -> int:
"""Get the hash of the namespace.

Returns:
Expand Down Expand Up @@ -614,15 +615,15 @@ class TriggerDefinition:
description="Fired when focus has left the element (or left some element inside of it). For example, it is called when the user clicks outside of a focused text input.",
),
EventTriggers.ON_CLICK: TriggerDefinition(
spec=pointer_event_spec, # pyright: ignore [reportArgumentType]
spec=pointer_event_spec,
description="Fired when the user clicks on an element. For example, it's called when the user clicks on a button.",
),
EventTriggers.ON_CONTEXT_MENU: TriggerDefinition(
spec=pointer_event_spec, # pyright: ignore [reportArgumentType]
spec=pointer_event_spec,
description="Fired when the user right-clicks on an element.",
),
EventTriggers.ON_DOUBLE_CLICK: TriggerDefinition(
spec=pointer_event_spec, # pyright: ignore [reportArgumentType]
spec=pointer_event_spec,
description="Fired when the user double-clicks on an element.",
),
EventTriggers.ON_MOUSE_DOWN: TriggerDefinition(
Expand Down Expand Up @@ -1045,7 +1046,7 @@ def get_event_triggers(cls) -> dict[str, types.ArgsSpec | Sequence[types.ArgsSpe
"""
# Look for component specific triggers,
# e.g. variable declared as EventHandler types.
return DEFAULT_TRIGGERS | args_specs_from_fields(cls.get_fields()) # pyright: ignore [reportOperatorIssue]
return DEFAULT_TRIGGERS | args_specs_from_fields(cls.get_fields())

def __repr__(self) -> str:
"""Represent the component in React.
Expand Down Expand Up @@ -1289,9 +1290,9 @@ def _get_component_style(self, styles: ComponentStyle | Style) -> Style | None:
The style of the component.
"""
component_style = None
if (style := styles.get(type(self))) is not None: # pyright: ignore [reportArgumentType]
if (style := styles.get(type(self))) is not None: # ty:ignore[invalid-argument-type]
component_style = Style(style)
if (style := styles.get(self.create)) is not None: # pyright: ignore [reportArgumentType]
if (style := styles.get(self.create)) is not None: # ty:ignore[invalid-argument-type]
component_style = Style(style)
return component_style

Expand Down Expand Up @@ -2213,13 +2214,13 @@ def get_args_spec(key: str) -> types.ArgsSpec | Sequence[types.ArgsSpec]:
to_camel_cased_props = {
format.to_camel_case(key): None for key in props if key not in event_types
}
self.get_props = lambda: to_camel_cased_props # pyright: ignore [reportIncompatibleVariableOverride]
self.get_props = lambda: to_camel_cased_props # ty:ignore[invalid-assignment]

# Unset the style.
self.style = Style()

# Set the tag to the name of the function.
self.tag = format.to_title_case(self.component_fn.__name__)
self.tag = format.to_title_case(self.component_fn.__name__) # ty:ignore[unresolved-attribute]

for key, value in props.items():
# Skip kwargs that are not props.
Expand Down Expand Up @@ -2293,7 +2294,7 @@ def fn(*args):
else event.args_spec[0]
)
names = inspect.getfullargspec(arg_spec).args
fn.__signature__ = inspect.Signature( # pyright: ignore[reportFunctionMemberAccess]
fn.__signature__ = inspect.Signature( # ty:ignore[unresolved-attribute]
parameters=[
inspect.Parameter(
name=name,
Expand Down Expand Up @@ -2545,7 +2546,7 @@ def empty_component() -> Component:
return Bare.create("")


def render_dict_to_var(tag: dict | Component | str) -> Var:
def render_dict_to_var(tag: dict[str, Any] | Component | str) -> Var:
"""Convert a render dict to a Var.

Args:
Expand All @@ -2560,31 +2561,32 @@ def render_dict_to_var(tag: dict | Component | str) -> Var:
return Var.create(tag)

if "contents" in tag:
return Var(tag["contents"])
return Var(tag["contents"]) # ty:ignore[invalid-argument-type]

if "iterable" in tag:
function_return = LiteralArrayVar.create([
render_dict_to_var(child.render()) for child in tag["children"]
render_dict_to_var(child.render())
for child in tag["children"] # ty:ignore[invalid-argument-type, not-iterable]
])

func = ArgsFunctionOperation.create(
(tag["arg_var_name"], tag["index_var_name"]),
(tag["arg_var_name"], tag["index_var_name"]), # ty:ignore[invalid-argument-type]
function_return,
)

return FunctionStringVar.create("Array.prototype.map.call").call(
tag["iterable"]
if not isinstance(tag["iterable"], ObjectVar)
else tag["iterable"].items(),
tag["iterable"] # ty:ignore[invalid-argument-type]
if not isinstance(tag["iterable"], ObjectVar) # ty:ignore[invalid-argument-type]
else tag["iterable"].items(), # ty:ignore[invalid-argument-type]
func,
)

if "match_cases" in tag:
element = Var(tag["cond"])
element = Var(tag["cond"]) # ty:ignore[invalid-argument-type]

conditionals = render_dict_to_var(tag["default"])
conditionals = render_dict_to_var(tag["default"]) # ty:ignore[invalid-argument-type]

for case in tag["match_cases"][::-1]:
for case in tag["match_cases"][::-1]: # ty:ignore[invalid-argument-type, not-subscriptable]
conditions, return_value = case
condition = Var.create(False)
for pattern in conditions:
Expand All @@ -2602,24 +2604,24 @@ def render_dict_to_var(tag: dict | Component | str) -> Var:

if "cond_state" in tag:
return ternary_operation(
Var(tag["cond_state"]),
render_dict_to_var(tag["true_value"]),
render_dict_to_var(tag["false_value"])
if tag["false_value"] is not None
Var(tag["cond_state"]), # ty:ignore[invalid-argument-type]
render_dict_to_var(tag["true_value"]), # ty:ignore[invalid-argument-type]
render_dict_to_var(tag["false_value"]) # ty:ignore[invalid-argument-type]
if tag["false_value"] is not None # ty:ignore[invalid-argument-type]
else LiteralNoneVar.create(),
)

props = Var("({" + ",".join(tag["props"]) + "})")
props = Var("({" + ",".join(tag["props"]) + "})") # ty:ignore[invalid-argument-type, no-matching-overload]

raw_tag_name = tag.get("name")
raw_tag_name = tag.get("name") # ty:ignore[invalid-argument-type]
tag_name = Var(raw_tag_name or "Fragment")

return FunctionStringVar.create(
"jsx",
).call(
tag_name,
props,
*[render_dict_to_var(child) for child in tag["children"]],
*[render_dict_to_var(child) for child in tag["children"]], # ty:ignore[invalid-argument-type, not-iterable]
)


Expand Down
2 changes: 1 addition & 1 deletion packages/reflex-base/src/reflex_base/components/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(
# Process type annotation
type_origin = get_origin(annotated_type) or annotated_type
if type_origin is Annotated:
type_origin = annotated_type.__origin__ # pyright: ignore [reportAttributeAccessIssue]
type_origin = annotated_type.__origin__ # ty:ignore[unresolved-attribute]
# For Annotated types, use the actual type inside the annotation
self.type_ = annotated_type
else:
Expand Down
7 changes: 4 additions & 3 deletions packages/reflex-base/src/reflex_base/components/props.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import builtins
from collections.abc import Callable
from dataclasses import _MISSING_TYPE, MISSING
from typing import Any, TypeVar, get_args, get_origin
Expand Down Expand Up @@ -158,11 +159,11 @@ def props_field(
if default is not MISSING and default_factory is not None:
msg = "cannot specify both default and default_factory"
raise ValueError(msg)
return PropsField( # pyright: ignore [reportReturnType]
return PropsField(
default=default,
default_factory=default_factory,
annotated_type=MISSING,
)
) # ty:ignore[invalid-return-type]


@dataclass_transform(field_specifiers=(props_field,))
Expand Down Expand Up @@ -283,7 +284,7 @@ def __init__(self, **kwargs):
)

@classmethod
def get_fields(cls) -> dict[str, Any]:
def get_fields(cls) -> builtins.dict[str, Any]:
"""Get the fields of the object.

Returns:
Expand Down
4 changes: 2 additions & 2 deletions packages/reflex-base/src/reflex_base/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ def get_type_hints_environment(cls: type) -> dict[str, Any]:
return get_type_hints(cls)


class env_var: # noqa: N801 # pyright: ignore [reportRedeclaration]
class env_var: # noqa: N801
"""Descriptor for environment variables."""

name: str
Expand Down Expand Up @@ -709,7 +709,7 @@ class EnvironmentVariables:
try:
from dotenv import load_dotenv
except ImportError:
load_dotenv = None
load_dotenv = None # ty:ignore[invalid-assignment]


def _paths_from_env_files(env_files: str) -> list[Path]:
Expand Down
Loading
Loading