reflex 0.5.10a2__py3-none-any.whl → 0.6.0__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/custom_components/pyproject.toml.jinja2 +2 -2
- reflex/.templates/jinja/web/pages/_app.js.jinja2 +1 -1
- reflex/.templates/jinja/web/pages/utils.js.jinja2 +4 -4
- reflex/.templates/jinja/web/utils/context.js.jinja2 +1 -1
- reflex/.templates/jinja/web/utils/theme.js.jinja2 +1 -1
- reflex/.templates/web/utils/state.js +3 -1
- reflex/__init__.py +10 -3
- reflex/__init__.pyi +3 -2
- reflex/app.py +47 -11
- reflex/app_module_for_backend.py +1 -1
- reflex/base.py +3 -2
- reflex/compiler/compiler.py +5 -5
- reflex/compiler/utils.py +5 -3
- reflex/components/base/app_wrap.py +2 -4
- reflex/components/base/app_wrap.pyi +16 -26
- reflex/components/base/bare.py +6 -4
- reflex/components/base/body.pyi +16 -26
- reflex/components/base/document.pyi +76 -126
- reflex/components/base/error_boundary.py +9 -8
- reflex/components/base/error_boundary.pyi +18 -30
- reflex/components/base/fragment.pyi +16 -26
- reflex/components/base/head.pyi +31 -51
- reflex/components/base/link.py +1 -1
- reflex/components/base/link.pyi +31 -51
- reflex/components/base/meta.pyi +61 -101
- reflex/components/base/script.py +2 -2
- reflex/components/base/script.pyi +20 -36
- reflex/components/component.py +107 -130
- reflex/components/core/banner.py +61 -66
- reflex/components/core/banner.pyi +129 -230
- reflex/components/core/client_side_routing.py +2 -2
- reflex/components/core/client_side_routing.pyi +31 -51
- reflex/components/core/clipboard.py +4 -3
- reflex/components/core/clipboard.pyi +19 -31
- reflex/components/core/cond.py +21 -44
- reflex/components/core/debounce.py +7 -9
- reflex/components/core/debounce.pyi +19 -31
- reflex/components/core/foreach.py +4 -14
- reflex/components/core/html.py +1 -1
- reflex/components/core/html.pyi +34 -44
- reflex/components/core/match.py +36 -43
- reflex/components/core/upload.py +27 -26
- reflex/components/core/upload.pyi +81 -116
- reflex/components/datadisplay/code.py +55 -29
- reflex/components/datadisplay/code.pyi +303 -410
- reflex/components/datadisplay/dataeditor.py +13 -9
- reflex/components/datadisplay/dataeditor.pyi +39 -51
- reflex/components/el/__init__.py +0 -1
- reflex/components/el/__init__.pyi +0 -11
- reflex/components/el/element.pyi +16 -26
- reflex/components/el/elements/__init__.py +1 -7
- reflex/components/el/elements/__init__.pyi +1 -15
- reflex/components/el/elements/base.py +1 -1
- reflex/components/el/elements/base.pyi +33 -43
- reflex/components/el/elements/forms.py +26 -33
- reflex/components/el/elements/forms.pyi +542 -694
- reflex/components/el/elements/inline.py +1 -1
- reflex/components/el/elements/inline.pyi +909 -1189
- reflex/components/el/elements/media.py +1 -22
- reflex/components/el/elements/media.pyi +765 -975
- reflex/components/el/elements/metadata.py +3 -5
- reflex/components/el/elements/metadata.pyi +175 -235
- reflex/components/el/elements/other.py +1 -1
- reflex/components/el/elements/other.pyi +228 -298
- reflex/components/el/elements/scripts.py +1 -1
- reflex/components/el/elements/scripts.pyi +106 -136
- reflex/components/el/elements/sectioning.py +0 -2
- reflex/components/el/elements/sectioning.pyi +481 -631
- reflex/components/el/elements/tables.py +1 -1
- reflex/components/el/elements/tables.pyi +341 -441
- reflex/components/el/elements/typography.py +1 -1
- reflex/components/el/elements/typography.pyi +491 -641
- reflex/components/gridjs/datatable.py +9 -13
- reflex/components/gridjs/datatable.pyi +33 -53
- reflex/components/lucide/icon.py +3 -127
- reflex/components/lucide/icon.pyi +31 -160
- reflex/components/markdown/markdown.py +32 -42
- reflex/components/markdown/markdown.pyi +28 -41
- reflex/components/moment/moment.py +13 -12
- reflex/components/moment/moment.pyi +22 -33
- reflex/components/next/base.pyi +16 -26
- reflex/components/next/image.py +1 -5
- reflex/components/next/image.pyi +21 -35
- reflex/components/next/link.py +1 -1
- reflex/components/next/link.pyi +16 -26
- reflex/components/next/video.py +1 -1
- reflex/components/next/video.pyi +16 -26
- reflex/components/plotly/plotly.py +17 -30
- reflex/components/plotly/plotly.pyi +38 -52
- reflex/components/props.py +21 -10
- reflex/components/radix/__init__.pyi +2 -1
- reflex/components/radix/primitives/accordion.py +6 -7
- reflex/components/radix/primitives/accordion.pyi +415 -485
- reflex/components/radix/primitives/base.py +1 -1
- reflex/components/radix/primitives/base.pyi +31 -51
- reflex/components/radix/primitives/drawer.py +1 -1
- reflex/components/radix/primitives/drawer.pyi +162 -262
- reflex/components/radix/primitives/form.py +1 -1
- reflex/components/radix/primitives/form.pyi +247 -353
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/progress.pyi +226 -276
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/primitives/slider.pyi +82 -132
- reflex/components/radix/themes/base.py +8 -25
- reflex/components/radix/themes/base.pyi +171 -242
- reflex/components/radix/themes/color_mode.py +11 -20
- reflex/components/radix/themes/color_mode.pyi +198 -231
- reflex/components/radix/themes/components/__init__.pyi +1 -0
- reflex/components/radix/themes/components/alert_dialog.py +1 -1
- reflex/components/radix/themes/components/alert_dialog.pyi +129 -199
- reflex/components/radix/themes/components/aspect_ratio.py +1 -1
- reflex/components/radix/themes/components/aspect_ratio.pyi +16 -26
- reflex/components/radix/themes/components/avatar.py +1 -1
- reflex/components/radix/themes/components/avatar.pyi +69 -79
- reflex/components/radix/themes/components/badge.py +1 -1
- reflex/components/radix/themes/components/badge.pyi +87 -97
- reflex/components/radix/themes/components/button.py +1 -1
- reflex/components/radix/themes/components/button.pyi +97 -107
- reflex/components/radix/themes/components/callout.py +1 -1
- reflex/components/radix/themes/components/callout.pyi +317 -367
- reflex/components/radix/themes/components/card.py +1 -1
- reflex/components/radix/themes/components/card.pyi +37 -47
- reflex/components/radix/themes/components/checkbox.py +2 -4
- reflex/components/radix/themes/components/checkbox.pyi +205 -241
- reflex/components/radix/themes/components/checkbox_cards.py +1 -1
- reflex/components/radix/themes/components/checkbox_cards.pyi +92 -112
- reflex/components/radix/themes/components/checkbox_group.py +1 -1
- reflex/components/radix/themes/components/checkbox_group.pyi +84 -104
- reflex/components/radix/themes/components/context_menu.py +1 -1
- reflex/components/radix/themes/components/context_menu.pyi +230 -310
- reflex/components/radix/themes/components/data_list.py +6 -1
- reflex/components/radix/themes/components/data_list.pyi +131 -166
- reflex/components/radix/themes/components/dialog.py +1 -1
- reflex/components/radix/themes/components/dialog.pyi +132 -202
- reflex/components/radix/themes/components/dropdown_menu.py +1 -1
- reflex/components/radix/themes/components/dropdown_menu.pyi +241 -323
- reflex/components/radix/themes/components/hover_card.py +1 -1
- reflex/components/radix/themes/components/hover_card.pyi +86 -126
- reflex/components/radix/themes/components/icon_button.py +1 -1
- reflex/components/radix/themes/components/icon_button.pyi +97 -107
- reflex/components/radix/themes/components/inset.py +1 -1
- reflex/components/radix/themes/components/inset.pyi +46 -56
- reflex/components/radix/themes/components/popover.py +1 -1
- reflex/components/radix/themes/components/popover.pyi +91 -131
- reflex/components/radix/themes/components/progress.py +1 -1
- reflex/components/radix/themes/components/progress.pyi +70 -80
- reflex/components/radix/themes/components/radio.py +1 -1
- reflex/components/radix/themes/components/radio.pyi +68 -78
- reflex/components/radix/themes/components/radio_cards.py +1 -1
- reflex/components/radix/themes/components/radio_cards.pyi +96 -116
- reflex/components/radix/themes/components/radio_group.py +32 -31
- reflex/components/radix/themes/components/radio_group.pyi +230 -266
- reflex/components/radix/themes/components/scroll_area.py +1 -1
- reflex/components/radix/themes/components/scroll_area.pyi +20 -30
- reflex/components/radix/themes/components/segmented_control.py +1 -1
- reflex/components/radix/themes/components/segmented_control.pyi +88 -110
- reflex/components/radix/themes/components/select.py +1 -1
- reflex/components/radix/themes/components/select.pyi +365 -461
- reflex/components/radix/themes/components/separator.py +2 -4
- reflex/components/radix/themes/components/separator.pyi +68 -78
- reflex/components/radix/themes/components/skeleton.py +1 -1
- reflex/components/radix/themes/components/skeleton.pyi +22 -32
- reflex/components/radix/themes/components/slider.py +1 -1
- reflex/components/radix/themes/components/slider.pyi +74 -86
- reflex/components/radix/themes/components/spinner.py +1 -1
- reflex/components/radix/themes/components/spinner.pyi +18 -28
- reflex/components/radix/themes/components/switch.py +1 -1
- reflex/components/radix/themes/components/switch.pyi +70 -82
- reflex/components/radix/themes/components/table.py +1 -1
- reflex/components/radix/themes/components/table.pyi +254 -324
- reflex/components/radix/themes/components/tabs.py +1 -1
- reflex/components/radix/themes/components/tabs.pyi +134 -188
- reflex/components/radix/themes/components/text_area.py +1 -1
- reflex/components/radix/themes/components/text_area.pyi +95 -109
- reflex/components/radix/themes/components/text_field.py +1 -80
- reflex/components/radix/themes/components/text_field.pyi +245 -290
- reflex/components/radix/themes/components/tooltip.py +1 -1
- reflex/components/radix/themes/components/tooltip.pyi +25 -35
- reflex/components/radix/themes/layout/__init__.pyi +1 -0
- reflex/components/radix/themes/layout/base.py +1 -1
- reflex/components/radix/themes/layout/base.pyi +55 -65
- reflex/components/radix/themes/layout/box.pyi +33 -43
- reflex/components/radix/themes/layout/center.pyi +55 -65
- reflex/components/radix/themes/layout/container.py +2 -4
- reflex/components/radix/themes/layout/container.pyi +35 -45
- reflex/components/radix/themes/layout/flex.py +1 -1
- reflex/components/radix/themes/layout/flex.pyi +55 -65
- reflex/components/radix/themes/layout/grid.py +1 -1
- reflex/components/radix/themes/layout/grid.pyi +63 -73
- reflex/components/radix/themes/layout/list.py +1 -1
- reflex/components/radix/themes/layout/list.pyi +188 -238
- reflex/components/radix/themes/layout/section.py +2 -4
- reflex/components/radix/themes/layout/section.pyi +35 -45
- reflex/components/radix/themes/layout/spacer.pyi +55 -65
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/radix/themes/layout/stack.pyi +125 -155
- reflex/components/radix/themes/typography/blockquote.py +1 -1
- reflex/components/radix/themes/typography/blockquote.pyi +88 -98
- reflex/components/radix/themes/typography/code.py +1 -1
- reflex/components/radix/themes/typography/code.pyi +89 -99
- reflex/components/radix/themes/typography/heading.py +1 -1
- reflex/components/radix/themes/typography/heading.pyi +95 -105
- reflex/components/radix/themes/typography/link.py +1 -1
- reflex/components/radix/themes/typography/link.pyi +101 -111
- reflex/components/radix/themes/typography/text.py +1 -1
- reflex/components/radix/themes/typography/text.pyi +494 -564
- reflex/components/react_player/audio.pyi +32 -58
- reflex/components/react_player/react_player.py +1 -1
- reflex/components/react_player/react_player.pyi +32 -58
- reflex/components/react_player/video.pyi +32 -58
- reflex/components/recharts/cartesian.py +22 -19
- reflex/components/recharts/cartesian.pyi +658 -840
- reflex/components/recharts/charts.py +3 -3
- reflex/components/recharts/charts.pyi +238 -342
- reflex/components/recharts/general.py +8 -8
- reflex/components/recharts/general.pyi +175 -225
- reflex/components/recharts/polar.py +11 -11
- reflex/components/recharts/polar.pyi +135 -171
- reflex/components/recharts/recharts.pyi +31 -51
- reflex/components/sonner/toast.py +27 -31
- reflex/components/sonner/toast.pyi +36 -45
- reflex/components/suneditor/editor.py +1 -1
- reflex/components/suneditor/editor.pyi +54 -76
- reflex/components/tags/cond_tag.py +6 -4
- reflex/components/tags/iter_tag.py +37 -25
- reflex/components/tags/match_tag.py +6 -4
- reflex/components/tags/tag.py +43 -28
- reflex/constants/base.py +3 -1
- reflex/constants/event.py +1 -0
- reflex/custom_components/custom_components.py +3 -1
- reflex/event.py +166 -108
- reflex/experimental/__init__.py +25 -6
- reflex/experimental/client_state.py +34 -57
- reflex/experimental/hooks.py +12 -17
- reflex/experimental/layout.py +4 -4
- reflex/experimental/layout.pyi +130 -180
- reflex/middleware/hydrate_middleware.py +2 -0
- reflex/middleware/middleware.py +3 -3
- reflex/model.py +22 -0
- reflex/reflex.py +4 -0
- reflex/state.py +491 -110
- reflex/style.py +56 -39
- reflex/testing.py +8 -3
- reflex/utils/exceptions.py +32 -0
- reflex/utils/exec.py +0 -14
- reflex/utils/format.py +80 -209
- reflex/utils/imports.py +16 -73
- reflex/utils/net.py +43 -0
- reflex/utils/path_ops.py +13 -1
- reflex/utils/prerequisites.py +81 -41
- reflex/utils/pyi_generator.py +12 -6
- reflex/utils/serializers.py +13 -41
- reflex/utils/telemetry.py +3 -2
- reflex/utils/types.py +47 -7
- reflex/{experimental/vars → vars}/__init__.py +6 -3
- reflex/vars/base.py +2563 -0
- reflex/vars/function.py +196 -0
- reflex/vars/number.py +1158 -0
- reflex/vars/object.py +562 -0
- reflex/vars/sequence.py +1604 -0
- {reflex-0.5.10a2.dist-info → reflex-0.6.0.dist-info}/METADATA +6 -9
- reflex-0.6.0.dist-info/RECORD +382 -0
- reflex/.templates/apps/demo/.gitignore +0 -4
- reflex/.templates/apps/demo/assets/favicon.ico +0 -0
- reflex/.templates/apps/demo/assets/github.svg +0 -10
- reflex/.templates/apps/demo/assets/icon.svg +0 -37
- reflex/.templates/apps/demo/assets/logo.svg +0 -68
- reflex/.templates/apps/demo/assets/paneleft.svg +0 -13
- reflex/.templates/apps/demo/code/__init__.py +0 -1
- reflex/.templates/apps/demo/code/demo.py +0 -127
- reflex/.templates/apps/demo/code/pages/__init__.py +0 -7
- reflex/.templates/apps/demo/code/pages/chatapp.py +0 -31
- reflex/.templates/apps/demo/code/pages/datatable.py +0 -360
- reflex/.templates/apps/demo/code/pages/forms.py +0 -257
- reflex/.templates/apps/demo/code/pages/graphing.py +0 -253
- reflex/.templates/apps/demo/code/pages/home.py +0 -56
- reflex/.templates/apps/demo/code/sidebar.py +0 -178
- reflex/.templates/apps/demo/code/state.py +0 -22
- reflex/.templates/apps/demo/code/states/form_state.py +0 -40
- reflex/.templates/apps/demo/code/states/pie_state.py +0 -47
- reflex/.templates/apps/demo/code/styles.py +0 -68
- reflex/.templates/apps/demo/code/webui/__init__.py +0 -0
- reflex/.templates/apps/demo/code/webui/components/__init__.py +0 -4
- reflex/.templates/apps/demo/code/webui/components/chat.py +0 -118
- reflex/.templates/apps/demo/code/webui/components/loading_icon.py +0 -19
- reflex/.templates/apps/demo/code/webui/components/modal.py +0 -56
- reflex/.templates/apps/demo/code/webui/components/navbar.py +0 -70
- reflex/.templates/apps/demo/code/webui/components/sidebar.py +0 -66
- reflex/.templates/apps/demo/code/webui/state.py +0 -146
- reflex/.templates/apps/demo/code/webui/styles.py +0 -88
- reflex/.templates/web/components/reflex/chakra_color_mode_provider.js +0 -36
- reflex/experimental/vars/base.py +0 -583
- reflex/experimental/vars/function.py +0 -290
- reflex/experimental/vars/number.py +0 -1458
- reflex/experimental/vars/object.py +0 -804
- reflex/experimental/vars/sequence.py +0 -1764
- reflex/utils/watch.py +0 -96
- reflex/vars.py +0 -2604
- reflex/vars.pyi +0 -218
- reflex-0.5.10a2.dist-info/RECORD +0 -413
- {reflex-0.5.10a2.dist-info → reflex-0.6.0.dist-info}/LICENSE +0 -0
- {reflex-0.5.10a2.dist-info → reflex-0.6.0.dist-info}/WHEEL +0 -0
- {reflex-0.5.10a2.dist-info → reflex-0.6.0.dist-info}/entry_points.txt +0 -0
reflex/experimental/vars/base.py
DELETED
|
@@ -1,583 +0,0 @@
|
|
|
1
|
-
"""Collection of base classes."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import dataclasses
|
|
6
|
-
import functools
|
|
7
|
-
import inspect
|
|
8
|
-
import sys
|
|
9
|
-
from typing import (
|
|
10
|
-
TYPE_CHECKING,
|
|
11
|
-
Any,
|
|
12
|
-
Callable,
|
|
13
|
-
Dict,
|
|
14
|
-
Generic,
|
|
15
|
-
List,
|
|
16
|
-
Optional,
|
|
17
|
-
Set,
|
|
18
|
-
Tuple,
|
|
19
|
-
Type,
|
|
20
|
-
TypeVar,
|
|
21
|
-
Union,
|
|
22
|
-
overload,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
from typing_extensions import ParamSpec, get_origin
|
|
26
|
-
|
|
27
|
-
from reflex import constants
|
|
28
|
-
from reflex.base import Base
|
|
29
|
-
from reflex.utils import serializers, types
|
|
30
|
-
from reflex.utils.exceptions import VarTypeError
|
|
31
|
-
from reflex.vars import (
|
|
32
|
-
ImmutableVarData,
|
|
33
|
-
Var,
|
|
34
|
-
VarData,
|
|
35
|
-
_decode_var_immutable,
|
|
36
|
-
_extract_var_data,
|
|
37
|
-
_global_vars,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
if TYPE_CHECKING:
|
|
41
|
-
from .function import FunctionVar, ToFunctionOperation
|
|
42
|
-
from .number import (
|
|
43
|
-
BooleanVar,
|
|
44
|
-
NumberVar,
|
|
45
|
-
ToBooleanVarOperation,
|
|
46
|
-
ToNumberVarOperation,
|
|
47
|
-
)
|
|
48
|
-
from .object import ObjectVar, ToObjectOperation
|
|
49
|
-
from .sequence import ArrayVar, StringVar, ToArrayOperation, ToStringOperation
|
|
50
|
-
|
|
51
|
-
VAR_TYPE = TypeVar("VAR_TYPE")
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@dataclasses.dataclass(
|
|
55
|
-
eq=False,
|
|
56
|
-
frozen=True,
|
|
57
|
-
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
58
|
-
)
|
|
59
|
-
class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|
60
|
-
"""Base class for immutable vars."""
|
|
61
|
-
|
|
62
|
-
# The name of the var.
|
|
63
|
-
_var_name: str = dataclasses.field()
|
|
64
|
-
|
|
65
|
-
# The type of the var.
|
|
66
|
-
_var_type: types.GenericType = dataclasses.field(default=Any)
|
|
67
|
-
|
|
68
|
-
# Extra metadata associated with the Var
|
|
69
|
-
_var_data: Optional[ImmutableVarData] = dataclasses.field(default=None)
|
|
70
|
-
|
|
71
|
-
def __str__(self) -> str:
|
|
72
|
-
"""String representation of the var. Guaranteed to be a valid Javascript expression.
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
The name of the var.
|
|
76
|
-
"""
|
|
77
|
-
return self._var_name
|
|
78
|
-
|
|
79
|
-
@property
|
|
80
|
-
def _var_is_local(self) -> bool:
|
|
81
|
-
"""Whether this is a local javascript variable.
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
False
|
|
85
|
-
"""
|
|
86
|
-
return False
|
|
87
|
-
|
|
88
|
-
@property
|
|
89
|
-
def _var_is_string(self) -> bool:
|
|
90
|
-
"""Whether the var is a string literal.
|
|
91
|
-
|
|
92
|
-
Returns:
|
|
93
|
-
False
|
|
94
|
-
"""
|
|
95
|
-
return False
|
|
96
|
-
|
|
97
|
-
@property
|
|
98
|
-
def _var_full_name_needs_state_prefix(self) -> bool:
|
|
99
|
-
"""Whether the full name of the var needs a _var_state prefix.
|
|
100
|
-
|
|
101
|
-
Returns:
|
|
102
|
-
False
|
|
103
|
-
"""
|
|
104
|
-
return False
|
|
105
|
-
|
|
106
|
-
def __post_init__(self):
|
|
107
|
-
"""Post-initialize the var."""
|
|
108
|
-
# Decode any inline Var markup and apply it to the instance
|
|
109
|
-
_var_data, _var_name = _decode_var_immutable(self._var_name)
|
|
110
|
-
|
|
111
|
-
if _var_data or _var_name != self._var_name:
|
|
112
|
-
self.__init__(
|
|
113
|
-
_var_name=_var_name,
|
|
114
|
-
_var_type=self._var_type,
|
|
115
|
-
_var_data=ImmutableVarData.merge(self._var_data, _var_data),
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
def __hash__(self) -> int:
|
|
119
|
-
"""Define a hash function for the var.
|
|
120
|
-
|
|
121
|
-
Returns:
|
|
122
|
-
The hash of the var.
|
|
123
|
-
"""
|
|
124
|
-
return hash((self._var_name, self._var_type, self._var_data))
|
|
125
|
-
|
|
126
|
-
def _get_all_var_data(self) -> ImmutableVarData | None:
|
|
127
|
-
"""Get all VarData associated with the Var.
|
|
128
|
-
|
|
129
|
-
Returns:
|
|
130
|
-
The VarData of the components and all of its children.
|
|
131
|
-
"""
|
|
132
|
-
return self._var_data
|
|
133
|
-
|
|
134
|
-
def _replace(self, merge_var_data=None, **kwargs: Any):
|
|
135
|
-
"""Make a copy of this Var with updated fields.
|
|
136
|
-
|
|
137
|
-
Args:
|
|
138
|
-
merge_var_data: VarData to merge into the existing VarData.
|
|
139
|
-
**kwargs: Var fields to update.
|
|
140
|
-
|
|
141
|
-
Returns:
|
|
142
|
-
A new ImmutableVar with the updated fields overwriting the corresponding fields in this Var.
|
|
143
|
-
|
|
144
|
-
Raises:
|
|
145
|
-
TypeError: If _var_is_local, _var_is_string, or _var_full_name_needs_state_prefix is not None.
|
|
146
|
-
"""
|
|
147
|
-
if kwargs.get("_var_is_local", False) is not False:
|
|
148
|
-
raise TypeError(
|
|
149
|
-
"The _var_is_local argument is not supported for ImmutableVar."
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
if kwargs.get("_var_is_string", False) is not False:
|
|
153
|
-
raise TypeError(
|
|
154
|
-
"The _var_is_string argument is not supported for ImmutableVar."
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
if kwargs.get("_var_full_name_needs_state_prefix", False) is not False:
|
|
158
|
-
raise TypeError(
|
|
159
|
-
"The _var_full_name_needs_state_prefix argument is not supported for ImmutableVar."
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
field_values = dict(
|
|
163
|
-
_var_name=kwargs.pop("_var_name", self._var_name),
|
|
164
|
-
_var_type=kwargs.pop("_var_type", self._var_type),
|
|
165
|
-
_var_data=ImmutableVarData.merge(
|
|
166
|
-
kwargs.get("_var_data", self._var_data), merge_var_data
|
|
167
|
-
),
|
|
168
|
-
)
|
|
169
|
-
return type(self)(**field_values)
|
|
170
|
-
|
|
171
|
-
@classmethod
|
|
172
|
-
def create(
|
|
173
|
-
cls,
|
|
174
|
-
value: Any,
|
|
175
|
-
_var_is_local: bool | None = None,
|
|
176
|
-
_var_is_string: bool | None = None,
|
|
177
|
-
_var_data: VarData | None = None,
|
|
178
|
-
) -> ImmutableVar | Var | None:
|
|
179
|
-
"""Create a var from a value.
|
|
180
|
-
|
|
181
|
-
Args:
|
|
182
|
-
value: The value to create the var from.
|
|
183
|
-
_var_is_local: Whether the var is local. Deprecated.
|
|
184
|
-
_var_is_string: Whether the var is a string literal. Deprecated.
|
|
185
|
-
_var_data: Additional hooks and imports associated with the Var.
|
|
186
|
-
|
|
187
|
-
Returns:
|
|
188
|
-
The var.
|
|
189
|
-
|
|
190
|
-
Raises:
|
|
191
|
-
VarTypeError: If the value is JSON-unserializable.
|
|
192
|
-
TypeError: If _var_is_local or _var_is_string is not None.
|
|
193
|
-
"""
|
|
194
|
-
if _var_is_local is not None:
|
|
195
|
-
raise TypeError(
|
|
196
|
-
"The _var_is_local argument is not supported for ImmutableVar."
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
if _var_is_string is not None:
|
|
200
|
-
raise TypeError(
|
|
201
|
-
"The _var_is_string argument is not supported for ImmutableVar."
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
from reflex.utils import format
|
|
205
|
-
|
|
206
|
-
# Check for none values.
|
|
207
|
-
if value is None:
|
|
208
|
-
return None
|
|
209
|
-
|
|
210
|
-
# If the value is already a var, do nothing.
|
|
211
|
-
if isinstance(value, Var):
|
|
212
|
-
return value
|
|
213
|
-
|
|
214
|
-
# Try to pull the imports and hooks from contained values.
|
|
215
|
-
if not isinstance(value, str):
|
|
216
|
-
_var_data = VarData.merge(*_extract_var_data(value), _var_data)
|
|
217
|
-
|
|
218
|
-
# Try to serialize the value.
|
|
219
|
-
type_ = type(value)
|
|
220
|
-
if type_ in types.JSONType:
|
|
221
|
-
name = value
|
|
222
|
-
else:
|
|
223
|
-
name, _serialized_type = serializers.serialize(value, get_type=True)
|
|
224
|
-
if name is None:
|
|
225
|
-
raise VarTypeError(
|
|
226
|
-
f"No JSON serializer found for var {value} of type {type_}."
|
|
227
|
-
)
|
|
228
|
-
name = name if isinstance(name, str) else format.json_dumps(name)
|
|
229
|
-
|
|
230
|
-
return cls(
|
|
231
|
-
_var_name=name,
|
|
232
|
-
_var_type=type_,
|
|
233
|
-
_var_data=(
|
|
234
|
-
ImmutableVarData(
|
|
235
|
-
state=_var_data.state,
|
|
236
|
-
imports=_var_data.imports,
|
|
237
|
-
hooks=_var_data.hooks,
|
|
238
|
-
)
|
|
239
|
-
if _var_data
|
|
240
|
-
else None
|
|
241
|
-
),
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
@classmethod
|
|
245
|
-
def create_safe(
|
|
246
|
-
cls,
|
|
247
|
-
value: Any,
|
|
248
|
-
_var_is_local: bool | None = None,
|
|
249
|
-
_var_is_string: bool | None = None,
|
|
250
|
-
_var_data: VarData | None = None,
|
|
251
|
-
) -> Var | ImmutableVar:
|
|
252
|
-
"""Create a var from a value, asserting that it is not None.
|
|
253
|
-
|
|
254
|
-
Args:
|
|
255
|
-
value: The value to create the var from.
|
|
256
|
-
_var_is_local: Whether the var is local. Deprecated.
|
|
257
|
-
_var_is_string: Whether the var is a string literal. Deprecated.
|
|
258
|
-
_var_data: Additional hooks and imports associated with the Var.
|
|
259
|
-
|
|
260
|
-
Returns:
|
|
261
|
-
The var.
|
|
262
|
-
"""
|
|
263
|
-
var = cls.create(
|
|
264
|
-
value,
|
|
265
|
-
_var_is_local=_var_is_local,
|
|
266
|
-
_var_is_string=_var_is_string,
|
|
267
|
-
_var_data=_var_data,
|
|
268
|
-
)
|
|
269
|
-
assert var is not None
|
|
270
|
-
return var
|
|
271
|
-
|
|
272
|
-
def __format__(self, format_spec: str) -> str:
|
|
273
|
-
"""Format the var into a Javascript equivalent to an f-string.
|
|
274
|
-
|
|
275
|
-
Args:
|
|
276
|
-
format_spec: The format specifier (Ignored for now).
|
|
277
|
-
|
|
278
|
-
Returns:
|
|
279
|
-
The formatted var.
|
|
280
|
-
"""
|
|
281
|
-
hashed_var = hash(self)
|
|
282
|
-
|
|
283
|
-
_global_vars[hashed_var] = self
|
|
284
|
-
|
|
285
|
-
# Encode the _var_data into the formatted output for tracking purposes.
|
|
286
|
-
return f"{constants.REFLEX_VAR_OPENING_TAG}{hashed_var}{constants.REFLEX_VAR_CLOSING_TAG}{self._var_name}"
|
|
287
|
-
|
|
288
|
-
@overload
|
|
289
|
-
def to(
|
|
290
|
-
self, output: Type[NumberVar], var_type: type[int] | type[float] = float
|
|
291
|
-
) -> ToNumberVarOperation: ...
|
|
292
|
-
|
|
293
|
-
@overload
|
|
294
|
-
def to(self, output: Type[BooleanVar]) -> ToBooleanVarOperation: ...
|
|
295
|
-
|
|
296
|
-
@overload
|
|
297
|
-
def to(
|
|
298
|
-
self,
|
|
299
|
-
output: Type[ArrayVar],
|
|
300
|
-
var_type: type[list] | type[tuple] | type[set] = list,
|
|
301
|
-
) -> ToArrayOperation: ...
|
|
302
|
-
|
|
303
|
-
@overload
|
|
304
|
-
def to(self, output: Type[StringVar]) -> ToStringOperation: ...
|
|
305
|
-
|
|
306
|
-
@overload
|
|
307
|
-
def to(
|
|
308
|
-
self, output: Type[ObjectVar], var_type: types.GenericType = dict
|
|
309
|
-
) -> ToObjectOperation: ...
|
|
310
|
-
|
|
311
|
-
@overload
|
|
312
|
-
def to(
|
|
313
|
-
self, output: Type[FunctionVar], var_type: Type[Callable] = Callable
|
|
314
|
-
) -> ToFunctionOperation: ...
|
|
315
|
-
|
|
316
|
-
@overload
|
|
317
|
-
def to(
|
|
318
|
-
self, output: Type[OUTPUT], var_type: types.GenericType | None = None
|
|
319
|
-
) -> OUTPUT: ...
|
|
320
|
-
|
|
321
|
-
def to(
|
|
322
|
-
self, output: Type[OUTPUT], var_type: types.GenericType | None = None
|
|
323
|
-
) -> Var:
|
|
324
|
-
"""Convert the var to a different type.
|
|
325
|
-
|
|
326
|
-
Args:
|
|
327
|
-
output: The output type.
|
|
328
|
-
var_type: The type of the var.
|
|
329
|
-
|
|
330
|
-
Raises:
|
|
331
|
-
TypeError: If the var_type is not a supported type for the output.
|
|
332
|
-
|
|
333
|
-
Returns:
|
|
334
|
-
The converted var.
|
|
335
|
-
"""
|
|
336
|
-
from .number import (
|
|
337
|
-
BooleanVar,
|
|
338
|
-
NumberVar,
|
|
339
|
-
ToBooleanVarOperation,
|
|
340
|
-
ToNumberVarOperation,
|
|
341
|
-
)
|
|
342
|
-
|
|
343
|
-
fixed_type = (
|
|
344
|
-
var_type
|
|
345
|
-
if var_type is None or inspect.isclass(var_type)
|
|
346
|
-
else get_origin(var_type)
|
|
347
|
-
)
|
|
348
|
-
|
|
349
|
-
if issubclass(output, NumberVar):
|
|
350
|
-
if fixed_type is not None and not issubclass(fixed_type, (int, float)):
|
|
351
|
-
raise TypeError(
|
|
352
|
-
f"Unsupported type {var_type} for NumberVar. Must be int or float."
|
|
353
|
-
)
|
|
354
|
-
return ToNumberVarOperation(self, var_type or float)
|
|
355
|
-
if issubclass(output, BooleanVar):
|
|
356
|
-
return ToBooleanVarOperation(self)
|
|
357
|
-
|
|
358
|
-
from .sequence import ArrayVar, StringVar, ToArrayOperation, ToStringOperation
|
|
359
|
-
|
|
360
|
-
if issubclass(output, ArrayVar):
|
|
361
|
-
if fixed_type is not None and not issubclass(
|
|
362
|
-
fixed_type, (list, tuple, set)
|
|
363
|
-
):
|
|
364
|
-
raise TypeError(
|
|
365
|
-
f"Unsupported type {var_type} for ArrayVar. Must be list, tuple, or set."
|
|
366
|
-
)
|
|
367
|
-
return ToArrayOperation(self, var_type or list)
|
|
368
|
-
if issubclass(output, StringVar):
|
|
369
|
-
return ToStringOperation(self)
|
|
370
|
-
|
|
371
|
-
from .object import ObjectVar, ToObjectOperation
|
|
372
|
-
|
|
373
|
-
if issubclass(output, ObjectVar):
|
|
374
|
-
return ToObjectOperation(self, var_type or dict)
|
|
375
|
-
|
|
376
|
-
from .function import FunctionVar, ToFunctionOperation
|
|
377
|
-
|
|
378
|
-
if issubclass(output, FunctionVar):
|
|
379
|
-
if fixed_type is not None and not issubclass(fixed_type, Callable):
|
|
380
|
-
raise TypeError(
|
|
381
|
-
f"Unsupported type {var_type} for FunctionVar. Must be Callable."
|
|
382
|
-
)
|
|
383
|
-
return ToFunctionOperation(self, var_type or Callable)
|
|
384
|
-
|
|
385
|
-
return output(
|
|
386
|
-
_var_name=self._var_name,
|
|
387
|
-
_var_type=self._var_type if var_type is None else var_type,
|
|
388
|
-
_var_data=self._var_data,
|
|
389
|
-
)
|
|
390
|
-
|
|
391
|
-
def guess_type(self) -> ImmutableVar:
|
|
392
|
-
"""Guess the type of the var.
|
|
393
|
-
|
|
394
|
-
Returns:
|
|
395
|
-
The guessed type.
|
|
396
|
-
"""
|
|
397
|
-
from .number import NumberVar
|
|
398
|
-
from .object import ObjectVar
|
|
399
|
-
from .sequence import ArrayVar, StringVar
|
|
400
|
-
|
|
401
|
-
if self._var_type is Any:
|
|
402
|
-
return self
|
|
403
|
-
|
|
404
|
-
var_type = self._var_type
|
|
405
|
-
|
|
406
|
-
fixed_type = var_type if inspect.isclass(var_type) else get_origin(var_type)
|
|
407
|
-
|
|
408
|
-
if issubclass(fixed_type, (int, float)):
|
|
409
|
-
return self.to(NumberVar, var_type)
|
|
410
|
-
if issubclass(fixed_type, dict):
|
|
411
|
-
return self.to(ObjectVar, var_type)
|
|
412
|
-
if issubclass(fixed_type, (list, tuple, set)):
|
|
413
|
-
return self.to(ArrayVar, var_type)
|
|
414
|
-
if issubclass(fixed_type, str):
|
|
415
|
-
return self.to(StringVar)
|
|
416
|
-
if issubclass(fixed_type, Base):
|
|
417
|
-
return self.to(ObjectVar, var_type)
|
|
418
|
-
return self
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
OUTPUT = TypeVar("OUTPUT", bound=ImmutableVar)
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
class LiteralVar(ImmutableVar):
|
|
425
|
-
"""Base class for immutable literal vars."""
|
|
426
|
-
|
|
427
|
-
@classmethod
|
|
428
|
-
def create(
|
|
429
|
-
cls,
|
|
430
|
-
value: Any,
|
|
431
|
-
_var_data: VarData | None = None,
|
|
432
|
-
) -> Var:
|
|
433
|
-
"""Create a var from a value.
|
|
434
|
-
|
|
435
|
-
Args:
|
|
436
|
-
value: The value to create the var from.
|
|
437
|
-
_var_data: Additional hooks and imports associated with the Var.
|
|
438
|
-
|
|
439
|
-
Returns:
|
|
440
|
-
The var.
|
|
441
|
-
|
|
442
|
-
Raises:
|
|
443
|
-
TypeError: If the value is not a supported type for LiteralVar.
|
|
444
|
-
"""
|
|
445
|
-
if isinstance(value, Var):
|
|
446
|
-
if _var_data is None:
|
|
447
|
-
return value
|
|
448
|
-
return value._replace(merge_var_data=_var_data)
|
|
449
|
-
|
|
450
|
-
if value is None:
|
|
451
|
-
return ImmutableVar.create_safe("null", _var_data=_var_data)
|
|
452
|
-
|
|
453
|
-
from .object import LiteralObjectVar
|
|
454
|
-
|
|
455
|
-
if isinstance(value, Base):
|
|
456
|
-
return LiteralObjectVar(
|
|
457
|
-
value.dict(), _var_type=type(value), _var_data=_var_data
|
|
458
|
-
)
|
|
459
|
-
|
|
460
|
-
from .number import LiteralBooleanVar, LiteralNumberVar
|
|
461
|
-
from .sequence import LiteralArrayVar, LiteralStringVar
|
|
462
|
-
|
|
463
|
-
if isinstance(value, str):
|
|
464
|
-
return LiteralStringVar.create(value, _var_data=_var_data)
|
|
465
|
-
|
|
466
|
-
type_mapping = {
|
|
467
|
-
int: LiteralNumberVar,
|
|
468
|
-
float: LiteralNumberVar,
|
|
469
|
-
bool: LiteralBooleanVar,
|
|
470
|
-
dict: LiteralObjectVar,
|
|
471
|
-
list: LiteralArrayVar,
|
|
472
|
-
tuple: LiteralArrayVar,
|
|
473
|
-
set: LiteralArrayVar,
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
constructor = type_mapping.get(type(value))
|
|
477
|
-
|
|
478
|
-
if constructor is None:
|
|
479
|
-
raise TypeError(f"Unsupported type {type(value)} for LiteralVar.")
|
|
480
|
-
|
|
481
|
-
return constructor(value, _var_data=_var_data)
|
|
482
|
-
|
|
483
|
-
def __post_init__(self):
|
|
484
|
-
"""Post-initialize the var."""
|
|
485
|
-
|
|
486
|
-
def json(self) -> str:
|
|
487
|
-
"""Serialize the var to a JSON string.
|
|
488
|
-
|
|
489
|
-
Raises:
|
|
490
|
-
NotImplementedError: If the method is not implemented.
|
|
491
|
-
"""
|
|
492
|
-
raise NotImplementedError(
|
|
493
|
-
"LiteralVar subclasses must implement the json method."
|
|
494
|
-
)
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
P = ParamSpec("P")
|
|
498
|
-
T = TypeVar("T", bound=ImmutableVar)
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
def var_operation(*, output: Type[T]) -> Callable[[Callable[P, str]], Callable[P, T]]:
|
|
502
|
-
"""Decorator for creating a var operation.
|
|
503
|
-
|
|
504
|
-
Example:
|
|
505
|
-
```python
|
|
506
|
-
@var_operation(output=NumberVar)
|
|
507
|
-
def add(a: NumberVar, b: NumberVar):
|
|
508
|
-
return f"({a} + {b})"
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
Args:
|
|
512
|
-
output: The output type of the operation.
|
|
513
|
-
|
|
514
|
-
Returns:
|
|
515
|
-
The decorator.
|
|
516
|
-
"""
|
|
517
|
-
|
|
518
|
-
def decorator(func: Callable[P, str], output=output):
|
|
519
|
-
@functools.wraps(func)
|
|
520
|
-
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
521
|
-
args_vars = [
|
|
522
|
-
LiteralVar.create(arg) if not isinstance(arg, Var) else arg
|
|
523
|
-
for arg in args
|
|
524
|
-
]
|
|
525
|
-
kwargs_vars = {
|
|
526
|
-
key: LiteralVar.create(value) if not isinstance(value, Var) else value
|
|
527
|
-
for key, value in kwargs.items()
|
|
528
|
-
}
|
|
529
|
-
return output(
|
|
530
|
-
_var_name=func(*args_vars, **kwargs_vars), # type: ignore
|
|
531
|
-
_var_data=VarData.merge(
|
|
532
|
-
*[arg._get_all_var_data() for arg in args if isinstance(arg, Var)],
|
|
533
|
-
*[
|
|
534
|
-
arg._get_all_var_data()
|
|
535
|
-
for arg in kwargs.values()
|
|
536
|
-
if isinstance(arg, Var)
|
|
537
|
-
],
|
|
538
|
-
),
|
|
539
|
-
)
|
|
540
|
-
|
|
541
|
-
return wrapper
|
|
542
|
-
|
|
543
|
-
return decorator
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
def unionize(*args: Type) -> Type:
|
|
547
|
-
"""Unionize the types.
|
|
548
|
-
|
|
549
|
-
Args:
|
|
550
|
-
args: The types to unionize.
|
|
551
|
-
|
|
552
|
-
Returns:
|
|
553
|
-
The unionized types.
|
|
554
|
-
"""
|
|
555
|
-
if not args:
|
|
556
|
-
return Any
|
|
557
|
-
first, *rest = args
|
|
558
|
-
if not rest:
|
|
559
|
-
return first
|
|
560
|
-
return Union[first, unionize(*rest)]
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
def figure_out_type(value: Any) -> Type:
|
|
564
|
-
"""Figure out the type of the value.
|
|
565
|
-
|
|
566
|
-
Args:
|
|
567
|
-
value: The value to figure out the type of.
|
|
568
|
-
|
|
569
|
-
Returns:
|
|
570
|
-
The type of the value.
|
|
571
|
-
"""
|
|
572
|
-
if isinstance(value, list):
|
|
573
|
-
return List[unionize(*(figure_out_type(v) for v in value))]
|
|
574
|
-
if isinstance(value, set):
|
|
575
|
-
return Set[unionize(*(figure_out_type(v) for v in value))]
|
|
576
|
-
if isinstance(value, tuple):
|
|
577
|
-
return Tuple[unionize(*(figure_out_type(v) for v in value)), ...]
|
|
578
|
-
if isinstance(value, dict):
|
|
579
|
-
return Dict[
|
|
580
|
-
unionize(*(figure_out_type(k) for k in value)),
|
|
581
|
-
unionize(*(figure_out_type(v) for v in value.values())),
|
|
582
|
-
]
|
|
583
|
-
return type(value)
|