adjust setter to include type annotation (#4726)

* adjust setter to include type annotation

* apparently this discovered some bugs

* remove some pyright ignores

* add str to int/float conversion

* dang it darglint
This commit is contained in:
Khaleel Al-Adhami 2025-02-13 12:44:27 -08:00 committed by GitHub
parent 2ba73f7ff9
commit 10c45b185c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 14 deletions

View File

@ -46,10 +46,26 @@ def render_multiple_pages(app, num: int):
class State(rx.State):
"""The app state."""
position: str
college: str
age: Tuple[int, int] = (18, 50)
salary: Tuple[int, int] = (0, 25000000)
position: rx.Field[str]
college: rx.Field[str]
age: rx.Field[Tuple[int, int]] = rx.field((18, 50))
salary: rx.Field[Tuple[int, int]] = rx.field((0, 25000000))
@rx.event
def set_position(self, value: str):
self.position = value
@rx.event
def set_college(self, value: str):
self.college = value
@rx.event
def set_age(self, value: list[int]):
self.age = (value[0], value[1])
@rx.event
def set_salary(self, value: list[int]):
self.salary = (value[0], value[1])
comp1 = rx.center(
rx.theme_panel(),
@ -74,13 +90,13 @@ def render_multiple_pages(app, num: int):
rx.select(
["C", "PF", "SF", "PG", "SG"],
placeholder="Select a position. (All)",
on_change=State.set_position, # pyright: ignore [reportAttributeAccessIssue]
on_change=State.set_position,
size="3",
),
rx.select(
college,
placeholder="Select a college. (All)",
on_change=State.set_college, # pyright: ignore [reportAttributeAccessIssue]
on_change=State.set_college,
size="3",
),
),
@ -95,7 +111,7 @@ def render_multiple_pages(app, num: int):
default_value=[18, 50],
min=18,
max=50,
on_value_commit=State.set_age, # pyright: ignore [reportAttributeAccessIssue]
on_value_commit=State.set_age,
),
align_items="left",
width="100%",
@ -110,7 +126,7 @@ def render_multiple_pages(app, num: int):
default_value=[0, 25000000],
min=0,
max=25000000,
on_value_commit=State.set_salary, # pyright: ignore [reportAttributeAccessIssue]
on_value_commit=State.set_salary,
),
align_items="left",
width="100%",

View File

@ -1742,6 +1742,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
Yields:
StateUpdate object
Raises:
ValueError: If a string value is received for an int or float type and cannot be converted.
"""
from reflex.utils import telemetry
@ -1779,12 +1782,25 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
hinted_args, (Base, BaseModelV1, BaseModelV2)
):
payload[arg] = hinted_args(**value)
if isinstance(value, list) and (hinted_args is set or hinted_args is Set):
elif isinstance(value, list) and (hinted_args is set or hinted_args is Set):
payload[arg] = set(value)
if isinstance(value, list) and (
elif isinstance(value, list) and (
hinted_args is tuple or hinted_args is Tuple
):
payload[arg] = tuple(value)
elif isinstance(value, str) and (
hinted_args is int or hinted_args is float
):
try:
payload[arg] = hinted_args(value)
except ValueError:
raise ValueError(
f"Received a string value ({value}) for {arg} but expected a {hinted_args}"
) from None
else:
console.warn(
f"Received a string value ({value}) for {arg} but expected a {hinted_args}. A simple conversion was successful."
)
# Wrap the function in a try/except block.
try:

View File

@ -951,7 +951,7 @@ class Var(Generic[VAR_TYPE]):
"""
actual_name = self._var_field_name
def setter(state: BaseState, value: Any):
def setter(state: Any, value: Any):
"""Get the setter for the var.
Args:
@ -969,6 +969,8 @@ class Var(Generic[VAR_TYPE]):
else:
setattr(state, actual_name, value)
setter.__annotations__["value"] = self._var_type
setter.__qualname__ = self._get_setter_name()
return setter

View File

@ -20,7 +20,11 @@ def BackgroundTask():
class State(rx.State):
counter: int = 0
_task_id: int = 0
iterations: int = 10
iterations: rx.Field[int] = rx.field(10)
@rx.event
def set_iterations(self, value: str):
self.iterations = int(value)
@rx.event(background=True)
async def handle_event(self):
@ -125,8 +129,8 @@ def BackgroundTask():
rx.input(
id="iterations",
placeholder="Iterations",
value=State.iterations.to_string(), # pyright: ignore [reportAttributeAccessIssue]
on_change=State.set_iterations, # pyright: ignore [reportAttributeAccessIssue]
value=State.iterations.to_string(),
on_change=State.set_iterations,
),
rx.button(
"Delayed Increment",