Skip to content

Commit 2fcb573

Browse files
authored
handle range value types [ENG-5143] (#4990)
* handle range value types * add range var * units
1 parent 4529f7c commit 2fcb573

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

reflex/state.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,6 +1671,7 @@ def _is_valid_type(events: Any) -> bool:
16711671

16721672
raise TypeError(
16731673
f"Your handler {handler.fn.__qualname__} must only return/yield: None, Events or other EventHandlers referenced by their class (i.e. using `type(self)` or other class references)."
1674+
f" Returned events of types {', '.join(map(str, map(type, events)))!s}."
16741675
)
16751676

16761677
async def _as_state_update(

reflex/vars/sequence.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,8 @@ def _determine_value_of_array_index(
16831683
if t is not type(None)
16841684
]
16851685
)
1686+
if origin_var_type is range:
1687+
return int
16861688
if origin_var_type in [
16871689
Sequence,
16881690
Iterable,
@@ -1974,3 +1976,85 @@ def json(self) -> str:
19741976
):
19751977
raise TypeError("Color is not a valid color.")
19761978
return f"var(--{color}-{'a' if alpha else ''}{shade})"
1979+
1980+
1981+
class RangeVar(ArrayVar[Sequence[int]], python_types=range):
1982+
"""Base class for immutable range vars."""
1983+
1984+
1985+
@dataclasses.dataclass(
1986+
eq=False,
1987+
frozen=True,
1988+
slots=True,
1989+
)
1990+
class LiteralRangeVar(CachedVarOperation, LiteralVar, RangeVar):
1991+
"""Base class for immutable literal range vars."""
1992+
1993+
_var_value: range = dataclasses.field(default_factory=lambda: range(0))
1994+
1995+
@classmethod
1996+
def create(
1997+
cls,
1998+
value: range,
1999+
_var_type: Type[range] | None = None,
2000+
_var_data: VarData | None = None,
2001+
) -> RangeVar:
2002+
"""Create a var from a string value.
2003+
2004+
Args:
2005+
value: The value to create the var from.
2006+
_var_type: The type of the var.
2007+
_var_data: Additional hooks and imports associated with the Var.
2008+
2009+
Returns:
2010+
The var.
2011+
"""
2012+
return cls(
2013+
_js_expr="",
2014+
_var_type=_var_type or range,
2015+
_var_data=_var_data,
2016+
_var_value=value,
2017+
)
2018+
2019+
def __hash__(self) -> int:
2020+
"""Get the hash of the var.
2021+
2022+
Returns:
2023+
The hash of the var.
2024+
"""
2025+
return hash(
2026+
(
2027+
self.__class__.__name__,
2028+
self._var_value.start,
2029+
self._var_value.stop,
2030+
self._var_value.step,
2031+
)
2032+
)
2033+
2034+
@cached_property_no_lock
2035+
def _cached_var_name(self) -> str:
2036+
"""The name of the var.
2037+
2038+
Returns:
2039+
The name of the var.
2040+
"""
2041+
return f"Array.from({{ length: Math.ceil(({self._var_value.stop!s} - {self._var_value.start!s}) / {self._var_value.step!s}) }}, (_, i) => {self._var_value.start!s} + i * {self._var_value.step!s})"
2042+
2043+
@cached_property_no_lock
2044+
def _cached_get_all_var_data(self) -> VarData | None:
2045+
"""Get all the var data.
2046+
2047+
Returns:
2048+
The var data.
2049+
"""
2050+
return self._var_data
2051+
2052+
def json(self) -> str:
2053+
"""Get the JSON representation of the var.
2054+
2055+
Returns:
2056+
The JSON representation of the var.
2057+
"""
2058+
return json.dumps(
2059+
list(self._var_value),
2060+
)

tests/units/test_state.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1612,7 +1612,7 @@ def invalid_handler(self):
16121612
"An error occurred.",
16131613
level="error",
16141614
fallback_to_alert=True,
1615-
description="TypeError: Your handler test_state_with_invalid_yield.<locals>.StateWithInvalidYield.invalid_handler must only return/yield: None, Events or other EventHandlers referenced by their class (i.e. using `type(self)` or other class references)..<br/>See logs for details.",
1615+
description="TypeError: Your handler test_state_with_invalid_yield.<locals>.StateWithInvalidYield.invalid_handler must only return/yield: None, Events or other EventHandlers referenced by their class (i.e. using `type(self)` or other class references). Returned events of types <class 'int'>..<br/>See logs for details.",
16161616
id="backend_error",
16171617
position="top-center",
16181618
style={"width": "500px"},

0 commit comments

Comments
 (0)