reflex 0.6.6.post3__py3-none-any.whl → 0.6.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 +5 -1
- reflex/.templates/web/utils/state.js +36 -28
- reflex/__init__.py +1 -1
- reflex/__init__.pyi +1 -0
- reflex/app.py +41 -16
- reflex/assets.py +2 -2
- reflex/base.py +8 -7
- reflex/compiler/templates.py +1 -0
- reflex/compiler/utils.py +2 -3
- reflex/components/base/bare.py +2 -2
- reflex/components/component.py +54 -29
- reflex/components/core/banner.py +2 -2
- reflex/components/core/banner.pyi +1 -1
- reflex/components/core/client_side_routing.py +2 -2
- reflex/components/core/client_side_routing.pyi +1 -1
- reflex/components/core/clipboard.py +11 -9
- reflex/components/core/clipboard.pyi +1 -1
- reflex/components/core/cond.py +3 -3
- reflex/components/core/foreach.py +1 -1
- reflex/components/core/html.pyi +1 -1
- reflex/components/core/upload.py +8 -8
- reflex/components/datadisplay/code.py +5 -5
- reflex/components/datadisplay/dataeditor.py +8 -28
- reflex/components/datadisplay/dataeditor.pyi +1 -1
- reflex/components/datadisplay/shiki_code_block.py +7 -7
- reflex/components/dynamic.py +2 -2
- reflex/components/el/elements/__init__.py +1 -1
- reflex/components/el/elements/__init__.pyi +1 -1
- reflex/components/el/elements/base.py +2 -2
- reflex/components/el/elements/base.pyi +1 -1
- reflex/components/el/elements/forms.py +40 -10
- reflex/components/el/elements/forms.pyi +17 -15
- reflex/components/el/elements/inline.py +1 -1
- reflex/components/el/elements/inline.pyi +28 -28
- reflex/components/el/elements/media.py +1 -4
- reflex/components/el/elements/media.pyi +25 -26
- reflex/components/el/elements/metadata.py +6 -6
- reflex/components/el/elements/metadata.pyi +4 -4
- reflex/components/el/elements/other.py +17 -9
- reflex/components/el/elements/other.pyi +7 -7
- reflex/components/el/elements/scripts.py +1 -2
- reflex/components/el/elements/scripts.pyi +3 -3
- reflex/components/el/elements/sectioning.py +16 -16
- reflex/components/el/elements/sectioning.pyi +15 -15
- reflex/components/el/elements/tables.py +1 -1
- reflex/components/el/elements/tables.pyi +10 -10
- reflex/components/el/elements/typography.py +1 -1
- reflex/components/el/elements/typography.pyi +15 -15
- reflex/components/markdown/markdown.py +3 -3
- reflex/components/next/image.py +1 -1
- reflex/components/next/image.pyi +1 -1
- reflex/components/plotly/plotly.py +2 -2
- reflex/components/radix/primitives/accordion.py +2 -1
- reflex/components/radix/primitives/form.pyi +3 -3
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/themes/base.py +4 -10
- reflex/components/radix/themes/color_mode.pyi +2 -2
- reflex/components/radix/themes/components/alert_dialog.pyi +1 -1
- reflex/components/radix/themes/components/badge.pyi +1 -1
- reflex/components/radix/themes/components/button.pyi +1 -1
- reflex/components/radix/themes/components/callout.pyi +5 -5
- reflex/components/radix/themes/components/card.pyi +1 -1
- reflex/components/radix/themes/components/checkbox.pyi +3 -3
- reflex/components/radix/themes/components/context_menu.py +11 -0
- reflex/components/radix/themes/components/context_menu.pyi +155 -0
- reflex/components/radix/themes/components/dialog.pyi +1 -1
- reflex/components/radix/themes/components/hover_card.pyi +1 -1
- reflex/components/radix/themes/components/icon_button.py +1 -1
- reflex/components/radix/themes/components/icon_button.pyi +1 -1
- reflex/components/radix/themes/components/inset.pyi +1 -1
- reflex/components/radix/themes/components/popover.pyi +1 -1
- reflex/components/radix/themes/components/radio_group.py +2 -4
- reflex/components/radix/themes/components/radio_group.pyi +1 -1
- reflex/components/radix/themes/components/select.pyi +3 -3
- reflex/components/radix/themes/components/slider.pyi +1 -1
- reflex/components/radix/themes/components/switch.pyi +1 -1
- reflex/components/radix/themes/components/table.pyi +7 -7
- reflex/components/radix/themes/components/tabs.pyi +2 -2
- reflex/components/radix/themes/components/text_area.py +3 -0
- reflex/components/radix/themes/components/text_area.pyi +3 -1
- reflex/components/radix/themes/components/text_field.py +16 -1
- reflex/components/radix/themes/components/text_field.pyi +105 -17
- reflex/components/radix/themes/layout/box.pyi +1 -1
- reflex/components/radix/themes/layout/center.pyi +1 -1
- reflex/components/radix/themes/layout/flex.pyi +1 -1
- reflex/components/radix/themes/layout/grid.pyi +1 -1
- reflex/components/radix/themes/layout/list.py +0 -4
- reflex/components/radix/themes/layout/list.pyi +3 -8
- reflex/components/radix/themes/layout/section.pyi +1 -1
- reflex/components/radix/themes/layout/spacer.pyi +1 -1
- reflex/components/radix/themes/layout/stack.pyi +3 -3
- reflex/components/radix/themes/typography/blockquote.pyi +1 -1
- reflex/components/radix/themes/typography/code.pyi +1 -1
- reflex/components/radix/themes/typography/heading.pyi +1 -1
- reflex/components/radix/themes/typography/link.py +5 -1
- reflex/components/radix/themes/typography/link.pyi +1 -1
- reflex/components/radix/themes/typography/text.pyi +7 -7
- reflex/components/recharts/cartesian.py +1 -1
- reflex/components/recharts/charts.py +4 -4
- reflex/components/recharts/polar.py +1 -1
- reflex/components/recharts/polar.pyi +1 -1
- reflex/components/sonner/toast.py +4 -7
- reflex/components/suneditor/editor.py +6 -6
- reflex/components/suneditor/editor.pyi +6 -6
- reflex/config.py +25 -10
- reflex/constants/compiler.py +6 -0
- reflex/constants/config.py +2 -0
- reflex/constants/custom_components.py +1 -1
- reflex/constants/route.py +1 -1
- reflex/custom_components/custom_components.py +21 -21
- reflex/event.py +57 -22
- reflex/experimental/client_state.py +2 -1
- reflex/experimental/layout.py +0 -6
- reflex/model.py +125 -9
- reflex/reflex.py +5 -6
- reflex/state.py +200 -88
- reflex/style.py +1 -4
- reflex/testing.py +10 -11
- reflex/utils/build.py +1 -1
- reflex/utils/console.py +75 -6
- reflex/utils/exceptions.py +12 -0
- reflex/utils/exec.py +10 -10
- reflex/utils/export.py +1 -2
- reflex/utils/format.py +11 -8
- reflex/utils/path_ops.py +2 -2
- reflex/utils/prerequisites.py +31 -28
- reflex/utils/processes.py +4 -4
- reflex/utils/pyi_generator.py +12 -11
- reflex/utils/types.py +6 -3
- reflex/vars/__init__.py +1 -0
- reflex/vars/base.py +75 -38
- reflex/vars/datetime.py +222 -0
- reflex/vars/function.py +3 -3
- reflex/vars/number.py +3 -3
- reflex/vars/object.py +5 -5
- reflex/vars/sequence.py +7 -7
- {reflex-0.6.6.post3.dist-info → reflex-0.6.7.dist-info}/METADATA +2 -2
- {reflex-0.6.6.post3.dist-info → reflex-0.6.7.dist-info}/RECORD +141 -140
- {reflex-0.6.6.post3.dist-info → reflex-0.6.7.dist-info}/LICENSE +0 -0
- {reflex-0.6.6.post3.dist-info → reflex-0.6.7.dist-info}/WHEEL +0 -0
- {reflex-0.6.6.post3.dist-info → reflex-0.6.7.dist-info}/entry_points.txt +0 -0
reflex/vars/base.py
CHANGED
|
@@ -42,7 +42,8 @@ from typing_extensions import ParamSpec, TypeGuard, deprecated, get_type_hints,
|
|
|
42
42
|
|
|
43
43
|
from reflex import constants
|
|
44
44
|
from reflex.base import Base
|
|
45
|
-
from reflex.
|
|
45
|
+
from reflex.constants.compiler import Hooks
|
|
46
|
+
from reflex.utils import console, exceptions, imports, serializers, types
|
|
46
47
|
from reflex.utils.exceptions import (
|
|
47
48
|
VarAttributeError,
|
|
48
49
|
VarDependencyError,
|
|
@@ -115,12 +116,20 @@ class VarData:
|
|
|
115
116
|
# Hooks that need to be present in the component to render this var
|
|
116
117
|
hooks: Tuple[str, ...] = dataclasses.field(default_factory=tuple)
|
|
117
118
|
|
|
119
|
+
# Dependencies of the var
|
|
120
|
+
deps: Tuple[Var, ...] = dataclasses.field(default_factory=tuple)
|
|
121
|
+
|
|
122
|
+
# Position of the hook in the component
|
|
123
|
+
position: Hooks.HookPosition | None = None
|
|
124
|
+
|
|
118
125
|
def __init__(
|
|
119
126
|
self,
|
|
120
127
|
state: str = "",
|
|
121
128
|
field_name: str = "",
|
|
122
129
|
imports: ImportDict | ParsedImportDict | None = None,
|
|
123
130
|
hooks: dict[str, None] | None = None,
|
|
131
|
+
deps: list[Var] | None = None,
|
|
132
|
+
position: Hooks.HookPosition | None = None,
|
|
124
133
|
):
|
|
125
134
|
"""Initialize the var data.
|
|
126
135
|
|
|
@@ -129,6 +138,8 @@ class VarData:
|
|
|
129
138
|
field_name: The name of the field in the state.
|
|
130
139
|
imports: Imports needed to render this var.
|
|
131
140
|
hooks: Hooks that need to be present in the component to render this var.
|
|
141
|
+
deps: Dependencies of the var for useCallback.
|
|
142
|
+
position: Position of the hook in the component.
|
|
132
143
|
"""
|
|
133
144
|
immutable_imports: ImmutableParsedImportDict = tuple(
|
|
134
145
|
sorted(
|
|
@@ -139,6 +150,8 @@ class VarData:
|
|
|
139
150
|
object.__setattr__(self, "field_name", field_name)
|
|
140
151
|
object.__setattr__(self, "imports", immutable_imports)
|
|
141
152
|
object.__setattr__(self, "hooks", tuple(hooks or {}))
|
|
153
|
+
object.__setattr__(self, "deps", tuple(deps or []))
|
|
154
|
+
object.__setattr__(self, "position", position or None)
|
|
142
155
|
|
|
143
156
|
def old_school_imports(self) -> ImportDict:
|
|
144
157
|
"""Return the imports as a mutable dict.
|
|
@@ -146,7 +159,7 @@ class VarData:
|
|
|
146
159
|
Returns:
|
|
147
160
|
The imports as a mutable dict.
|
|
148
161
|
"""
|
|
149
|
-
return
|
|
162
|
+
return {k: list(v) for k, v in self.imports}
|
|
150
163
|
|
|
151
164
|
def merge(*all: VarData | None) -> VarData | None:
|
|
152
165
|
"""Merge multiple var data objects.
|
|
@@ -154,6 +167,9 @@ class VarData:
|
|
|
154
167
|
Args:
|
|
155
168
|
*all: The var data objects to merge.
|
|
156
169
|
|
|
170
|
+
Raises:
|
|
171
|
+
ReflexError: If trying to merge VarData with different positions.
|
|
172
|
+
|
|
157
173
|
Returns:
|
|
158
174
|
The merged var data object.
|
|
159
175
|
|
|
@@ -184,12 +200,32 @@ class VarData:
|
|
|
184
200
|
*(var_data.imports for var_data in all_var_datas)
|
|
185
201
|
)
|
|
186
202
|
|
|
187
|
-
|
|
203
|
+
deps = [dep for var_data in all_var_datas for dep in var_data.deps]
|
|
204
|
+
|
|
205
|
+
positions = list(
|
|
206
|
+
{
|
|
207
|
+
var_data.position
|
|
208
|
+
for var_data in all_var_datas
|
|
209
|
+
if var_data.position is not None
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
if positions:
|
|
213
|
+
if len(positions) > 1:
|
|
214
|
+
raise exceptions.ReflexError(
|
|
215
|
+
f"Cannot merge var data with different positions: {positions}"
|
|
216
|
+
)
|
|
217
|
+
position = positions[0]
|
|
218
|
+
else:
|
|
219
|
+
position = None
|
|
220
|
+
|
|
221
|
+
if state or _imports or hooks or field_name or deps or position:
|
|
188
222
|
return VarData(
|
|
189
223
|
state=state,
|
|
190
224
|
field_name=field_name,
|
|
191
225
|
imports=_imports,
|
|
192
226
|
hooks=hooks,
|
|
227
|
+
deps=deps,
|
|
228
|
+
position=position,
|
|
193
229
|
)
|
|
194
230
|
|
|
195
231
|
return None
|
|
@@ -200,7 +236,14 @@ class VarData:
|
|
|
200
236
|
Returns:
|
|
201
237
|
True if any field is set to a non-default value.
|
|
202
238
|
"""
|
|
203
|
-
return bool(
|
|
239
|
+
return bool(
|
|
240
|
+
self.state
|
|
241
|
+
or self.imports
|
|
242
|
+
or self.hooks
|
|
243
|
+
or self.field_name
|
|
244
|
+
or self.deps
|
|
245
|
+
or self.position
|
|
246
|
+
)
|
|
204
247
|
|
|
205
248
|
@classmethod
|
|
206
249
|
def from_state(cls, state: Type[BaseState] | str, field_name: str = "") -> VarData:
|
|
@@ -480,7 +523,6 @@ class Var(Generic[VAR_TYPE]):
|
|
|
480
523
|
raise TypeError(
|
|
481
524
|
"The _var_full_name_needs_state_prefix argument is not supported for Var."
|
|
482
525
|
)
|
|
483
|
-
|
|
484
526
|
value_with_replaced = dataclasses.replace(
|
|
485
527
|
self,
|
|
486
528
|
_var_type=_var_type or self._var_type,
|
|
@@ -1057,7 +1099,7 @@ class Var(Generic[VAR_TYPE]):
|
|
|
1057
1099
|
|
|
1058
1100
|
if self._var_type is Any:
|
|
1059
1101
|
raise TypeError(
|
|
1060
|
-
f"You must provide an annotation for the state var `{
|
|
1102
|
+
f"You must provide an annotation for the state var `{self!s}`. Annotation cannot be `{self._var_type}`."
|
|
1061
1103
|
)
|
|
1062
1104
|
|
|
1063
1105
|
if name in REPLACED_NAMES:
|
|
@@ -1569,7 +1611,7 @@ class CachedVarOperation:
|
|
|
1569
1611
|
if name == "_js_expr":
|
|
1570
1612
|
return self._cached_var_name
|
|
1571
1613
|
|
|
1572
|
-
parent_classes = inspect.getmro(self
|
|
1614
|
+
parent_classes = inspect.getmro(type(self))
|
|
1573
1615
|
|
|
1574
1616
|
next_class = parent_classes[parent_classes.index(CachedVarOperation) + 1]
|
|
1575
1617
|
|
|
@@ -1591,14 +1633,12 @@ class CachedVarOperation:
|
|
|
1591
1633
|
The cached VarData.
|
|
1592
1634
|
"""
|
|
1593
1635
|
return VarData.merge(
|
|
1594
|
-
*
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
dataclasses.fields(self), # type: ignore
|
|
1601
|
-
),
|
|
1636
|
+
*(
|
|
1637
|
+
value._get_all_var_data() if isinstance(value, Var) else None
|
|
1638
|
+
for value in (
|
|
1639
|
+
getattr(self, field.name)
|
|
1640
|
+
for field in dataclasses.fields(self) # type: ignore
|
|
1641
|
+
)
|
|
1602
1642
|
),
|
|
1603
1643
|
self._var_data,
|
|
1604
1644
|
)
|
|
@@ -1611,7 +1651,7 @@ class CachedVarOperation:
|
|
|
1611
1651
|
"""
|
|
1612
1652
|
return hash(
|
|
1613
1653
|
(
|
|
1614
|
-
self.
|
|
1654
|
+
type(self).__name__,
|
|
1615
1655
|
*[
|
|
1616
1656
|
getattr(self, field.name)
|
|
1617
1657
|
for field in dataclasses.fields(self) # type: ignore
|
|
@@ -1733,7 +1773,7 @@ class CallableVar(Var):
|
|
|
1733
1773
|
Returns:
|
|
1734
1774
|
The hash of the object.
|
|
1735
1775
|
"""
|
|
1736
|
-
return hash((self.
|
|
1776
|
+
return hash((type(self).__name__, self.original_var))
|
|
1737
1777
|
|
|
1738
1778
|
|
|
1739
1779
|
RETURN_TYPE = TypeVar("RETURN_TYPE")
|
|
@@ -1889,20 +1929,20 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|
|
1889
1929
|
Raises:
|
|
1890
1930
|
TypeError: If kwargs contains keys that are not allowed.
|
|
1891
1931
|
"""
|
|
1892
|
-
field_values =
|
|
1893
|
-
fget
|
|
1894
|
-
initial_value
|
|
1895
|
-
cache
|
|
1896
|
-
deps
|
|
1897
|
-
auto_deps
|
|
1898
|
-
interval
|
|
1899
|
-
backend
|
|
1900
|
-
_js_expr
|
|
1901
|
-
_var_type
|
|
1902
|
-
_var_data
|
|
1932
|
+
field_values = {
|
|
1933
|
+
"fget": kwargs.pop("fget", self._fget),
|
|
1934
|
+
"initial_value": kwargs.pop("initial_value", self._initial_value),
|
|
1935
|
+
"cache": kwargs.pop("cache", self._cache),
|
|
1936
|
+
"deps": kwargs.pop("deps", self._static_deps),
|
|
1937
|
+
"auto_deps": kwargs.pop("auto_deps", self._auto_deps),
|
|
1938
|
+
"interval": kwargs.pop("interval", self._update_interval),
|
|
1939
|
+
"backend": kwargs.pop("backend", self._backend),
|
|
1940
|
+
"_js_expr": kwargs.pop("_js_expr", self._js_expr),
|
|
1941
|
+
"_var_type": kwargs.pop("_var_type", self._var_type),
|
|
1942
|
+
"_var_data": kwargs.pop(
|
|
1903
1943
|
"_var_data", VarData.merge(self._var_data, merge_var_data)
|
|
1904
1944
|
),
|
|
1905
|
-
|
|
1945
|
+
}
|
|
1906
1946
|
|
|
1907
1947
|
if kwargs:
|
|
1908
1948
|
unexpected_kwargs = ", ".join(kwargs.keys())
|
|
@@ -2117,7 +2157,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|
|
2117
2157
|
ref_obj = None
|
|
2118
2158
|
if instruction.argval in invalid_names:
|
|
2119
2159
|
raise VarValueError(
|
|
2120
|
-
f"Cached var {
|
|
2160
|
+
f"Cached var {self!s} cannot access arbitrary state via `{instruction.argval}`."
|
|
2121
2161
|
)
|
|
2122
2162
|
if callable(ref_obj):
|
|
2123
2163
|
# recurse into callable attributes
|
|
@@ -2371,10 +2411,7 @@ class CustomVarOperation(CachedVarOperation, Var[T]):
|
|
|
2371
2411
|
The cached VarData.
|
|
2372
2412
|
"""
|
|
2373
2413
|
return VarData.merge(
|
|
2374
|
-
*
|
|
2375
|
-
lambda arg: arg[1]._get_all_var_data(),
|
|
2376
|
-
self._args,
|
|
2377
|
-
),
|
|
2414
|
+
*(arg[1]._get_all_var_data() for arg in self._args),
|
|
2378
2415
|
self._return._get_all_var_data(),
|
|
2379
2416
|
self._var_data,
|
|
2380
2417
|
)
|
|
@@ -2492,7 +2529,7 @@ class StateOperation(CachedVarOperation, Var):
|
|
|
2492
2529
|
Returns:
|
|
2493
2530
|
The cached var name.
|
|
2494
2531
|
"""
|
|
2495
|
-
return f"{
|
|
2532
|
+
return f"{self._state_name!s}.{self._field!s}"
|
|
2496
2533
|
|
|
2497
2534
|
def __getattr__(self, name: str) -> Any:
|
|
2498
2535
|
"""Get an attribute of the var.
|
|
@@ -2804,9 +2841,9 @@ def dispatch(
|
|
|
2804
2841
|
|
|
2805
2842
|
if result_origin_var_type in dispatchers:
|
|
2806
2843
|
fn = dispatchers[result_origin_var_type]
|
|
2807
|
-
fn_first_arg_type =
|
|
2808
|
-
|
|
2809
|
-
|
|
2844
|
+
fn_first_arg_type = next(
|
|
2845
|
+
iter(inspect.signature(fn).parameters.values())
|
|
2846
|
+
).annotation
|
|
2810
2847
|
|
|
2811
2848
|
fn_return = inspect.signature(fn).return_annotation
|
|
2812
2849
|
|
reflex/vars/datetime.py
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""Immutable datetime and date vars."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import dataclasses
|
|
6
|
+
import sys
|
|
7
|
+
from datetime import date, datetime
|
|
8
|
+
from typing import Any, NoReturn, TypeVar, Union, overload
|
|
9
|
+
|
|
10
|
+
from reflex.utils.exceptions import VarTypeError
|
|
11
|
+
from reflex.vars.number import BooleanVar
|
|
12
|
+
|
|
13
|
+
from .base import (
|
|
14
|
+
CustomVarOperationReturn,
|
|
15
|
+
LiteralVar,
|
|
16
|
+
Var,
|
|
17
|
+
VarData,
|
|
18
|
+
var_operation,
|
|
19
|
+
var_operation_return,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
DATETIME_T = TypeVar("DATETIME_T", datetime, date)
|
|
23
|
+
|
|
24
|
+
datetime_types = Union[datetime, date]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def raise_var_type_error():
|
|
28
|
+
"""Raise a VarTypeError.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
VarTypeError: Cannot compare a datetime object with a non-datetime object.
|
|
32
|
+
"""
|
|
33
|
+
raise VarTypeError("Cannot compare a datetime object with a non-datetime object.")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
|
|
37
|
+
"""A variable that holds a datetime or date object."""
|
|
38
|
+
|
|
39
|
+
@overload
|
|
40
|
+
def __lt__(self, other: datetime_types) -> BooleanVar: ...
|
|
41
|
+
|
|
42
|
+
@overload
|
|
43
|
+
def __lt__(self, other: NoReturn) -> NoReturn: ...
|
|
44
|
+
|
|
45
|
+
def __lt__(self, other: Any):
|
|
46
|
+
"""Less than comparison.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
other: The other datetime to compare.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
The result of the comparison.
|
|
53
|
+
"""
|
|
54
|
+
if not isinstance(other, DATETIME_TYPES):
|
|
55
|
+
raise_var_type_error()
|
|
56
|
+
return date_lt_operation(self, other)
|
|
57
|
+
|
|
58
|
+
@overload
|
|
59
|
+
def __le__(self, other: datetime_types) -> BooleanVar: ...
|
|
60
|
+
|
|
61
|
+
@overload
|
|
62
|
+
def __le__(self, other: NoReturn) -> NoReturn: ...
|
|
63
|
+
|
|
64
|
+
def __le__(self, other: Any):
|
|
65
|
+
"""Less than or equal comparison.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
other: The other datetime to compare.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
The result of the comparison.
|
|
72
|
+
"""
|
|
73
|
+
if not isinstance(other, DATETIME_TYPES):
|
|
74
|
+
raise_var_type_error()
|
|
75
|
+
return date_le_operation(self, other)
|
|
76
|
+
|
|
77
|
+
@overload
|
|
78
|
+
def __gt__(self, other: datetime_types) -> BooleanVar: ...
|
|
79
|
+
|
|
80
|
+
@overload
|
|
81
|
+
def __gt__(self, other: NoReturn) -> NoReturn: ...
|
|
82
|
+
|
|
83
|
+
def __gt__(self, other: Any):
|
|
84
|
+
"""Greater than comparison.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
other: The other datetime to compare.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
The result of the comparison.
|
|
91
|
+
"""
|
|
92
|
+
if not isinstance(other, DATETIME_TYPES):
|
|
93
|
+
raise_var_type_error()
|
|
94
|
+
return date_gt_operation(self, other)
|
|
95
|
+
|
|
96
|
+
@overload
|
|
97
|
+
def __ge__(self, other: datetime_types) -> BooleanVar: ...
|
|
98
|
+
|
|
99
|
+
@overload
|
|
100
|
+
def __ge__(self, other: NoReturn) -> NoReturn: ...
|
|
101
|
+
|
|
102
|
+
def __ge__(self, other: Any):
|
|
103
|
+
"""Greater than or equal comparison.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
other: The other datetime to compare.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
The result of the comparison.
|
|
110
|
+
"""
|
|
111
|
+
if not isinstance(other, DATETIME_TYPES):
|
|
112
|
+
raise_var_type_error()
|
|
113
|
+
return date_ge_operation(self, other)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@var_operation
|
|
117
|
+
def date_gt_operation(lhs: Var | Any, rhs: Var | Any) -> CustomVarOperationReturn:
|
|
118
|
+
"""Greater than comparison.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
lhs: The left-hand side of the operation.
|
|
122
|
+
rhs: The right-hand side of the operation.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
The result of the operation.
|
|
126
|
+
"""
|
|
127
|
+
return date_compare_operation(rhs, lhs, strict=True)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@var_operation
|
|
131
|
+
def date_lt_operation(lhs: Var | Any, rhs: Var | Any) -> CustomVarOperationReturn:
|
|
132
|
+
"""Less than comparison.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
lhs: The left-hand side of the operation.
|
|
136
|
+
rhs: The right-hand side of the operation.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
The result of the operation.
|
|
140
|
+
"""
|
|
141
|
+
return date_compare_operation(lhs, rhs, strict=True)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@var_operation
|
|
145
|
+
def date_le_operation(lhs: Var | Any, rhs: Var | Any) -> CustomVarOperationReturn:
|
|
146
|
+
"""Less than or equal comparison.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
lhs: The left-hand side of the operation.
|
|
150
|
+
rhs: The right-hand side of the operation.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
The result of the operation.
|
|
154
|
+
"""
|
|
155
|
+
return date_compare_operation(lhs, rhs)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@var_operation
|
|
159
|
+
def date_ge_operation(lhs: Var | Any, rhs: Var | Any) -> CustomVarOperationReturn:
|
|
160
|
+
"""Greater than or equal comparison.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
lhs: The left-hand side of the operation.
|
|
164
|
+
rhs: The right-hand side of the operation.
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
The result of the operation.
|
|
168
|
+
"""
|
|
169
|
+
return date_compare_operation(rhs, lhs)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def date_compare_operation(
|
|
173
|
+
lhs: DateTimeVar[DATETIME_T] | Any,
|
|
174
|
+
rhs: DateTimeVar[DATETIME_T] | Any,
|
|
175
|
+
strict: bool = False,
|
|
176
|
+
) -> CustomVarOperationReturn:
|
|
177
|
+
"""Check if the value is less than the other value.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
lhs: The left-hand side of the operation.
|
|
181
|
+
rhs: The right-hand side of the operation.
|
|
182
|
+
strict: Whether to use strict comparison.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
The result of the operation.
|
|
186
|
+
"""
|
|
187
|
+
return var_operation_return(
|
|
188
|
+
f"({lhs} { '<' if strict else '<='} {rhs})",
|
|
189
|
+
bool,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclasses.dataclass(
|
|
194
|
+
eq=False,
|
|
195
|
+
frozen=True,
|
|
196
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
197
|
+
)
|
|
198
|
+
class LiteralDatetimeVar(LiteralVar, DateTimeVar):
|
|
199
|
+
"""Base class for immutable datetime and date vars."""
|
|
200
|
+
|
|
201
|
+
_var_value: datetime | date = dataclasses.field(default=datetime.now())
|
|
202
|
+
|
|
203
|
+
@classmethod
|
|
204
|
+
def create(cls, value: datetime | date, _var_data: VarData | None = None):
|
|
205
|
+
"""Create a new instance of the class.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
value: The value to set.
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
LiteralDatetimeVar: The new instance of the class.
|
|
212
|
+
"""
|
|
213
|
+
js_expr = f'"{value!s}"'
|
|
214
|
+
return cls(
|
|
215
|
+
_js_expr=js_expr,
|
|
216
|
+
_var_type=type(value),
|
|
217
|
+
_var_value=value,
|
|
218
|
+
_var_data=_var_data,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
DATETIME_TYPES = (datetime, date, DateTimeVar)
|
reflex/vars/function.py
CHANGED
|
@@ -240,7 +240,7 @@ class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
|
|
|
240
240
|
Returns:
|
|
241
241
|
The name of the var.
|
|
242
242
|
"""
|
|
243
|
-
return f"({
|
|
243
|
+
return f"({self._func!s}({', '.join([str(LiteralVar.create(arg)) for arg in self._args])}))"
|
|
244
244
|
|
|
245
245
|
@cached_property_no_lock
|
|
246
246
|
def _cached_get_all_var_data(self) -> VarData | None:
|
|
@@ -292,7 +292,7 @@ class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
|
|
|
292
292
|
class DestructuredArg:
|
|
293
293
|
"""Class for destructured arguments."""
|
|
294
294
|
|
|
295
|
-
fields: Tuple[str, ...] =
|
|
295
|
+
fields: Tuple[str, ...] = ()
|
|
296
296
|
rest: Optional[str] = None
|
|
297
297
|
|
|
298
298
|
def to_javascript(self) -> str:
|
|
@@ -314,7 +314,7 @@ class DestructuredArg:
|
|
|
314
314
|
class FunctionArgs:
|
|
315
315
|
"""Class for function arguments."""
|
|
316
316
|
|
|
317
|
-
args: Tuple[Union[str, DestructuredArg], ...] =
|
|
317
|
+
args: Tuple[Union[str, DestructuredArg], ...] = ()
|
|
318
318
|
rest: Optional[str] = None
|
|
319
319
|
|
|
320
320
|
|
reflex/vars/number.py
CHANGED
|
@@ -51,7 +51,7 @@ def raise_unsupported_operand_types(
|
|
|
51
51
|
VarTypeError: The operand types are unsupported.
|
|
52
52
|
"""
|
|
53
53
|
raise VarTypeError(
|
|
54
|
-
f"Unsupported Operand type(s) for {operator}: {', '.join(
|
|
54
|
+
f"Unsupported Operand type(s) for {operator}: {', '.join(t.__name__ for t in operands_types)}"
|
|
55
55
|
)
|
|
56
56
|
|
|
57
57
|
|
|
@@ -1012,7 +1012,7 @@ class LiteralNumberVar(LiteralVar, NumberVar):
|
|
|
1012
1012
|
Returns:
|
|
1013
1013
|
int: The hash value of the object.
|
|
1014
1014
|
"""
|
|
1015
|
-
return hash((self.
|
|
1015
|
+
return hash((type(self).__name__, self._var_value))
|
|
1016
1016
|
|
|
1017
1017
|
@classmethod
|
|
1018
1018
|
def create(cls, value: float | int, _var_data: VarData | None = None):
|
|
@@ -1064,7 +1064,7 @@ class LiteralBooleanVar(LiteralVar, BooleanVar):
|
|
|
1064
1064
|
Returns:
|
|
1065
1065
|
int: The hash value of the object.
|
|
1066
1066
|
"""
|
|
1067
|
-
return hash((self.
|
|
1067
|
+
return hash((type(self).__name__, self._var_value))
|
|
1068
1068
|
|
|
1069
1069
|
@classmethod
|
|
1070
1070
|
def create(cls, value: bool, _var_data: VarData | None = None):
|
reflex/vars/object.py
CHANGED
|
@@ -272,7 +272,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
|
|
272
272
|
attribute_type = get_attribute_access_type(var_type, name)
|
|
273
273
|
if attribute_type is None:
|
|
274
274
|
raise VarAttributeError(
|
|
275
|
-
f"The State var `{
|
|
275
|
+
f"The State var `{self!s}` has no attribute '{name}' or may have been annotated "
|
|
276
276
|
f"wrongly."
|
|
277
277
|
)
|
|
278
278
|
return ObjectItemOperation.create(self, name, attribute_type).guess_type()
|
|
@@ -332,7 +332,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
|
|
332
332
|
"({ "
|
|
333
333
|
+ ", ".join(
|
|
334
334
|
[
|
|
335
|
-
f"[{
|
|
335
|
+
f"[{LiteralVar.create(key)!s}] : {LiteralVar.create(value)!s}"
|
|
336
336
|
for key, value in self._var_value.items()
|
|
337
337
|
]
|
|
338
338
|
)
|
|
@@ -362,7 +362,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
|
|
362
362
|
Returns:
|
|
363
363
|
The hash of the var.
|
|
364
364
|
"""
|
|
365
|
-
return hash((self.
|
|
365
|
+
return hash((type(self).__name__, self._js_expr))
|
|
366
366
|
|
|
367
367
|
@cached_property_no_lock
|
|
368
368
|
def _cached_get_all_var_data(self) -> VarData | None:
|
|
@@ -494,8 +494,8 @@ class ObjectItemOperation(CachedVarOperation, Var):
|
|
|
494
494
|
The name of the operation.
|
|
495
495
|
"""
|
|
496
496
|
if types.is_optional(self._object._var_type):
|
|
497
|
-
return f"{
|
|
498
|
-
return f"{
|
|
497
|
+
return f"{self._object!s}?.[{self._key!s}]"
|
|
498
|
+
return f"{self._object!s}[{self._key!s}]"
|
|
499
499
|
|
|
500
500
|
@classmethod
|
|
501
501
|
def create(
|
reflex/vars/sequence.py
CHANGED
|
@@ -667,7 +667,7 @@ class LiteralStringVar(LiteralVar, StringVar[str]):
|
|
|
667
667
|
Returns:
|
|
668
668
|
The hash of the var.
|
|
669
669
|
"""
|
|
670
|
-
return hash((self.
|
|
670
|
+
return hash((type(self).__name__, self._var_value))
|
|
671
671
|
|
|
672
672
|
def json(self) -> str:
|
|
673
673
|
"""Get the JSON representation of the var.
|
|
@@ -1177,7 +1177,7 @@ class ArrayVar(Var[ARRAY_VAR_TYPE], python_types=(list, tuple, set)):
|
|
|
1177
1177
|
|
|
1178
1178
|
if num_args == 0:
|
|
1179
1179
|
return_value = fn()
|
|
1180
|
-
function_var = ArgsFunctionOperation.create(
|
|
1180
|
+
function_var = ArgsFunctionOperation.create((), return_value)
|
|
1181
1181
|
else:
|
|
1182
1182
|
# generic number var
|
|
1183
1183
|
number_var = Var("").to(NumberVar, int)
|
|
@@ -1349,7 +1349,7 @@ class ArraySliceOperation(CachedVarOperation, ArrayVar):
|
|
|
1349
1349
|
LiteralVar.create(end) if end is not None else Var(_js_expr="undefined")
|
|
1350
1350
|
)
|
|
1351
1351
|
if step is None:
|
|
1352
|
-
return f"{
|
|
1352
|
+
return f"{self._array!s}.slice({normalized_start!s}, {normalized_end!s})"
|
|
1353
1353
|
if not isinstance(step, Var):
|
|
1354
1354
|
if step < 0:
|
|
1355
1355
|
actual_start = end + 1 if end is not None else 0
|
|
@@ -1357,12 +1357,12 @@ class ArraySliceOperation(CachedVarOperation, ArrayVar):
|
|
|
1357
1357
|
return str(self._array[actual_start:actual_end].reverse()[::-step])
|
|
1358
1358
|
if step == 0:
|
|
1359
1359
|
raise ValueError("slice step cannot be zero")
|
|
1360
|
-
return f"{
|
|
1360
|
+
return f"{self._array!s}.slice({normalized_start!s}, {normalized_end!s}).filter((_, i) => i % {step!s} === 0)"
|
|
1361
1361
|
|
|
1362
1362
|
actual_start_reverse = end + 1 if end is not None else 0
|
|
1363
1363
|
actual_end_reverse = start + 1 if start is not None else self._array.length()
|
|
1364
1364
|
|
|
1365
|
-
return f"{
|
|
1365
|
+
return f"{self.step!s} > 0 ? {self._array!s}.slice({normalized_start!s}, {normalized_end!s}).filter((_, i) => i % {step!s} === 0) : {self._array!s}.slice({actual_start_reverse!s}, {actual_end_reverse!s}).reverse().filter((_, i) => i % {-step!s} === 0)"
|
|
1366
1366
|
|
|
1367
1367
|
@classmethod
|
|
1368
1368
|
def create(
|
|
@@ -1535,7 +1535,7 @@ def array_item_operation(array: ArrayVar, index: NumberVar | int):
|
|
|
1535
1535
|
element_type = unionize(*args)
|
|
1536
1536
|
|
|
1537
1537
|
return var_operation_return(
|
|
1538
|
-
js_expression=f"{
|
|
1538
|
+
js_expression=f"{array!s}.at({index!s})",
|
|
1539
1539
|
var_type=element_type,
|
|
1540
1540
|
)
|
|
1541
1541
|
|
|
@@ -1555,7 +1555,7 @@ def array_range_operation(
|
|
|
1555
1555
|
The range of numbers.
|
|
1556
1556
|
"""
|
|
1557
1557
|
return var_operation_return(
|
|
1558
|
-
js_expression=f"Array.from({{ length: ({
|
|
1558
|
+
js_expression=f"Array.from({{ length: ({stop!s} - {start!s}) / {step!s} }}, (_, i) => {start!s} + i * {step!s})",
|
|
1559
1559
|
var_type=List[int],
|
|
1560
1560
|
)
|
|
1561
1561
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: reflex
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.7
|
|
4
4
|
Summary: Web apps in pure Python.
|
|
5
5
|
Home-page: https://reflex.dev
|
|
6
6
|
License: Apache-2.0
|
|
@@ -39,7 +39,7 @@ Requires-Dist: setuptools (>=75.0)
|
|
|
39
39
|
Requires-Dist: sqlmodel (>=0.0.14,<0.1)
|
|
40
40
|
Requires-Dist: starlette-admin (>=0.11.0,<1.0)
|
|
41
41
|
Requires-Dist: tomlkit (>=0.12.4,<1.0)
|
|
42
|
-
Requires-Dist: twine (>=4.0.0,<
|
|
42
|
+
Requires-Dist: twine (>=4.0.0,<7.0)
|
|
43
43
|
Requires-Dist: typer (>=0.4.2,<1.0)
|
|
44
44
|
Requires-Dist: typing_extensions (>=4.6.0)
|
|
45
45
|
Requires-Dist: uvicorn (>=0.20.0)
|