reflex 0.5.10a3__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.10a3.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.10a3.dist-info/RECORD +0 -413
- {reflex-0.5.10a3.dist-info → reflex-0.6.0.dist-info}/LICENSE +0 -0
- {reflex-0.5.10a3.dist-info → reflex-0.6.0.dist-info}/WHEEL +0 -0
- {reflex-0.5.10a3.dist-info → reflex-0.6.0.dist-info}/entry_points.txt +0 -0
reflex/vars/object.py
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
"""Classes for immutable object vars."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import dataclasses
|
|
6
|
+
import sys
|
|
7
|
+
import typing
|
|
8
|
+
from inspect import isclass
|
|
9
|
+
from typing import (
|
|
10
|
+
Any,
|
|
11
|
+
ClassVar,
|
|
12
|
+
Dict,
|
|
13
|
+
List,
|
|
14
|
+
NoReturn,
|
|
15
|
+
Tuple,
|
|
16
|
+
Type,
|
|
17
|
+
TypeVar,
|
|
18
|
+
Union,
|
|
19
|
+
get_args,
|
|
20
|
+
overload,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
from reflex.utils import types
|
|
24
|
+
from reflex.utils.exceptions import VarAttributeError
|
|
25
|
+
from reflex.utils.types import GenericType, get_attribute_access_type, get_origin
|
|
26
|
+
|
|
27
|
+
from .base import (
|
|
28
|
+
CachedVarOperation,
|
|
29
|
+
LiteralVar,
|
|
30
|
+
ToOperation,
|
|
31
|
+
Var,
|
|
32
|
+
VarData,
|
|
33
|
+
cached_property_no_lock,
|
|
34
|
+
figure_out_type,
|
|
35
|
+
var_operation,
|
|
36
|
+
var_operation_return,
|
|
37
|
+
)
|
|
38
|
+
from .number import BooleanVar, NumberVar, raise_unsupported_operand_types
|
|
39
|
+
from .sequence import ArrayVar, StringVar
|
|
40
|
+
|
|
41
|
+
OBJECT_TYPE = TypeVar("OBJECT_TYPE", bound=Dict)
|
|
42
|
+
|
|
43
|
+
KEY_TYPE = TypeVar("KEY_TYPE")
|
|
44
|
+
VALUE_TYPE = TypeVar("VALUE_TYPE")
|
|
45
|
+
|
|
46
|
+
ARRAY_INNER_TYPE = TypeVar("ARRAY_INNER_TYPE")
|
|
47
|
+
|
|
48
|
+
OTHER_KEY_TYPE = TypeVar("OTHER_KEY_TYPE")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ObjectVar(Var[OBJECT_TYPE]):
|
|
52
|
+
"""Base class for immutable object vars."""
|
|
53
|
+
|
|
54
|
+
def _key_type(self) -> Type:
|
|
55
|
+
"""Get the type of the keys of the object.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
The type of the keys of the object.
|
|
59
|
+
"""
|
|
60
|
+
return str
|
|
61
|
+
|
|
62
|
+
@overload
|
|
63
|
+
def _value_type(
|
|
64
|
+
self: ObjectVar[Dict[KEY_TYPE, VALUE_TYPE]],
|
|
65
|
+
) -> Type[VALUE_TYPE]: ...
|
|
66
|
+
|
|
67
|
+
@overload
|
|
68
|
+
def _value_type(self) -> Type: ...
|
|
69
|
+
|
|
70
|
+
def _value_type(self) -> Type:
|
|
71
|
+
"""Get the type of the values of the object.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
The type of the values of the object.
|
|
75
|
+
"""
|
|
76
|
+
fixed_type = get_origin(self._var_type) or self._var_type
|
|
77
|
+
if not isclass(fixed_type):
|
|
78
|
+
return Any
|
|
79
|
+
args = get_args(self._var_type) if issubclass(fixed_type, dict) else ()
|
|
80
|
+
return args[1] if args else Any
|
|
81
|
+
|
|
82
|
+
def keys(self) -> ArrayVar[List[str]]:
|
|
83
|
+
"""Get the keys of the object.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
The keys of the object.
|
|
87
|
+
"""
|
|
88
|
+
return object_keys_operation(self)
|
|
89
|
+
|
|
90
|
+
@overload
|
|
91
|
+
def values(
|
|
92
|
+
self: ObjectVar[Dict[KEY_TYPE, VALUE_TYPE]],
|
|
93
|
+
) -> ArrayVar[List[VALUE_TYPE]]: ...
|
|
94
|
+
|
|
95
|
+
@overload
|
|
96
|
+
def values(self) -> ArrayVar: ...
|
|
97
|
+
|
|
98
|
+
def values(self) -> ArrayVar:
|
|
99
|
+
"""Get the values of the object.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
The values of the object.
|
|
103
|
+
"""
|
|
104
|
+
return object_values_operation(self)
|
|
105
|
+
|
|
106
|
+
@overload
|
|
107
|
+
def entries(
|
|
108
|
+
self: ObjectVar[Dict[KEY_TYPE, VALUE_TYPE]],
|
|
109
|
+
) -> ArrayVar[List[Tuple[str, VALUE_TYPE]]]: ...
|
|
110
|
+
|
|
111
|
+
@overload
|
|
112
|
+
def entries(self) -> ArrayVar: ...
|
|
113
|
+
|
|
114
|
+
def entries(self) -> ArrayVar:
|
|
115
|
+
"""Get the entries of the object.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
The entries of the object.
|
|
119
|
+
"""
|
|
120
|
+
return object_entries_operation(self)
|
|
121
|
+
|
|
122
|
+
def merge(self, other: ObjectVar):
|
|
123
|
+
"""Merge two objects.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
other: The other object to merge.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
The merged object.
|
|
130
|
+
"""
|
|
131
|
+
return object_merge_operation(self, other)
|
|
132
|
+
|
|
133
|
+
# NoReturn is used here to catch when key value is Any
|
|
134
|
+
@overload
|
|
135
|
+
def __getitem__(
|
|
136
|
+
self: ObjectVar[Dict[KEY_TYPE, NoReturn]],
|
|
137
|
+
key: Var | Any,
|
|
138
|
+
) -> Var: ...
|
|
139
|
+
|
|
140
|
+
@overload
|
|
141
|
+
def __getitem__(
|
|
142
|
+
self: (
|
|
143
|
+
ObjectVar[Dict[KEY_TYPE, int]]
|
|
144
|
+
| ObjectVar[Dict[KEY_TYPE, float]]
|
|
145
|
+
| ObjectVar[Dict[KEY_TYPE, int | float]]
|
|
146
|
+
),
|
|
147
|
+
key: Var | Any,
|
|
148
|
+
) -> NumberVar: ...
|
|
149
|
+
|
|
150
|
+
@overload
|
|
151
|
+
def __getitem__(
|
|
152
|
+
self: ObjectVar[Dict[KEY_TYPE, str]],
|
|
153
|
+
key: Var | Any,
|
|
154
|
+
) -> StringVar: ...
|
|
155
|
+
|
|
156
|
+
@overload
|
|
157
|
+
def __getitem__(
|
|
158
|
+
self: ObjectVar[Dict[KEY_TYPE, list[ARRAY_INNER_TYPE]]],
|
|
159
|
+
key: Var | Any,
|
|
160
|
+
) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
|
|
161
|
+
|
|
162
|
+
@overload
|
|
163
|
+
def __getitem__(
|
|
164
|
+
self: ObjectVar[Dict[KEY_TYPE, set[ARRAY_INNER_TYPE]]],
|
|
165
|
+
key: Var | Any,
|
|
166
|
+
) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
|
|
167
|
+
|
|
168
|
+
@overload
|
|
169
|
+
def __getitem__(
|
|
170
|
+
self: ObjectVar[Dict[KEY_TYPE, tuple[ARRAY_INNER_TYPE, ...]]],
|
|
171
|
+
key: Var | Any,
|
|
172
|
+
) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
|
|
173
|
+
|
|
174
|
+
@overload
|
|
175
|
+
def __getitem__(
|
|
176
|
+
self: ObjectVar[Dict[KEY_TYPE, dict[OTHER_KEY_TYPE, VALUE_TYPE]]],
|
|
177
|
+
key: Var | Any,
|
|
178
|
+
) -> ObjectVar[dict[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
|
|
179
|
+
|
|
180
|
+
def __getitem__(self, key: Var | Any) -> Var:
|
|
181
|
+
"""Get an item from the object.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
key: The key to get from the object.
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
The item from the object.
|
|
188
|
+
"""
|
|
189
|
+
if not isinstance(key, (StringVar, str, int, NumberVar)) or (
|
|
190
|
+
isinstance(key, NumberVar) and key._is_strict_float()
|
|
191
|
+
):
|
|
192
|
+
raise_unsupported_operand_types("[]", (type(self), type(key)))
|
|
193
|
+
return ObjectItemOperation.create(self, key).guess_type()
|
|
194
|
+
|
|
195
|
+
# NoReturn is used here to catch when key value is Any
|
|
196
|
+
@overload
|
|
197
|
+
def __getattr__(
|
|
198
|
+
self: ObjectVar[Dict[KEY_TYPE, NoReturn]],
|
|
199
|
+
name: str,
|
|
200
|
+
) -> Var: ...
|
|
201
|
+
|
|
202
|
+
@overload
|
|
203
|
+
def __getattr__(
|
|
204
|
+
self: (
|
|
205
|
+
ObjectVar[Dict[KEY_TYPE, int]]
|
|
206
|
+
| ObjectVar[Dict[KEY_TYPE, float]]
|
|
207
|
+
| ObjectVar[Dict[KEY_TYPE, int | float]]
|
|
208
|
+
),
|
|
209
|
+
name: str,
|
|
210
|
+
) -> NumberVar: ...
|
|
211
|
+
|
|
212
|
+
@overload
|
|
213
|
+
def __getattr__(
|
|
214
|
+
self: ObjectVar[Dict[KEY_TYPE, str]],
|
|
215
|
+
name: str,
|
|
216
|
+
) -> StringVar: ...
|
|
217
|
+
|
|
218
|
+
@overload
|
|
219
|
+
def __getattr__(
|
|
220
|
+
self: ObjectVar[Dict[KEY_TYPE, list[ARRAY_INNER_TYPE]]],
|
|
221
|
+
name: str,
|
|
222
|
+
) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
|
|
223
|
+
|
|
224
|
+
@overload
|
|
225
|
+
def __getattr__(
|
|
226
|
+
self: ObjectVar[Dict[KEY_TYPE, set[ARRAY_INNER_TYPE]]],
|
|
227
|
+
name: str,
|
|
228
|
+
) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
|
|
229
|
+
|
|
230
|
+
@overload
|
|
231
|
+
def __getattr__(
|
|
232
|
+
self: ObjectVar[Dict[KEY_TYPE, tuple[ARRAY_INNER_TYPE, ...]]],
|
|
233
|
+
name: str,
|
|
234
|
+
) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
|
|
235
|
+
|
|
236
|
+
@overload
|
|
237
|
+
def __getattr__(
|
|
238
|
+
self: ObjectVar[Dict[KEY_TYPE, dict[OTHER_KEY_TYPE, VALUE_TYPE]]],
|
|
239
|
+
name: str,
|
|
240
|
+
) -> ObjectVar[dict[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
|
|
241
|
+
|
|
242
|
+
def __getattr__(self, name) -> Var:
|
|
243
|
+
"""Get an attribute of the var.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
name: The name of the attribute.
|
|
247
|
+
|
|
248
|
+
Raises:
|
|
249
|
+
VarAttributeError: The State var has no such attribute or may have been annotated wrongly.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
The attribute of the var.
|
|
253
|
+
"""
|
|
254
|
+
if name.startswith("__") and name.endswith("__"):
|
|
255
|
+
return getattr(super(type(self), self), name)
|
|
256
|
+
|
|
257
|
+
var_type = self._var_type
|
|
258
|
+
|
|
259
|
+
if types.is_optional(var_type):
|
|
260
|
+
var_type = get_args(var_type)[0]
|
|
261
|
+
|
|
262
|
+
fixed_type = var_type if isclass(var_type) else get_origin(var_type)
|
|
263
|
+
if isclass(fixed_type) and not issubclass(fixed_type, dict):
|
|
264
|
+
attribute_type = get_attribute_access_type(var_type, name)
|
|
265
|
+
if attribute_type is None:
|
|
266
|
+
raise VarAttributeError(
|
|
267
|
+
f"The State var `{str(self)}` has no attribute '{name}' or may have been annotated "
|
|
268
|
+
f"wrongly."
|
|
269
|
+
)
|
|
270
|
+
return ObjectItemOperation.create(self, name, attribute_type).guess_type()
|
|
271
|
+
else:
|
|
272
|
+
return ObjectItemOperation.create(self, name).guess_type()
|
|
273
|
+
|
|
274
|
+
def contains(self, key: Var | Any) -> BooleanVar:
|
|
275
|
+
"""Check if the object contains a key.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
key: The key to check.
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
The result of the check.
|
|
282
|
+
"""
|
|
283
|
+
return object_has_own_property_operation(self, key)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@dataclasses.dataclass(
|
|
287
|
+
eq=False,
|
|
288
|
+
frozen=True,
|
|
289
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
290
|
+
)
|
|
291
|
+
class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
|
292
|
+
"""Base class for immutable literal object vars."""
|
|
293
|
+
|
|
294
|
+
_var_value: Dict[Union[Var, Any], Union[Var, Any]] = dataclasses.field(
|
|
295
|
+
default_factory=dict
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
def _key_type(self) -> Type:
|
|
299
|
+
"""Get the type of the keys of the object.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
The type of the keys of the object.
|
|
303
|
+
"""
|
|
304
|
+
args_list = typing.get_args(self._var_type)
|
|
305
|
+
return args_list[0] if args_list else Any
|
|
306
|
+
|
|
307
|
+
def _value_type(self) -> Type:
|
|
308
|
+
"""Get the type of the values of the object.
|
|
309
|
+
|
|
310
|
+
Returns:
|
|
311
|
+
The type of the values of the object.
|
|
312
|
+
"""
|
|
313
|
+
args_list = typing.get_args(self._var_type)
|
|
314
|
+
return args_list[1] if args_list else Any
|
|
315
|
+
|
|
316
|
+
@cached_property_no_lock
|
|
317
|
+
def _cached_var_name(self) -> str:
|
|
318
|
+
"""The name of the var.
|
|
319
|
+
|
|
320
|
+
Returns:
|
|
321
|
+
The name of the var.
|
|
322
|
+
"""
|
|
323
|
+
return (
|
|
324
|
+
"({ "
|
|
325
|
+
+ ", ".join(
|
|
326
|
+
[
|
|
327
|
+
f"[{str(LiteralVar.create(key))}] : {str(LiteralVar.create(value))}"
|
|
328
|
+
for key, value in self._var_value.items()
|
|
329
|
+
]
|
|
330
|
+
)
|
|
331
|
+
+ " })"
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
def json(self) -> str:
|
|
335
|
+
"""Get the JSON representation of the object.
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
The JSON representation of the object.
|
|
339
|
+
"""
|
|
340
|
+
return (
|
|
341
|
+
"{"
|
|
342
|
+
+ ", ".join(
|
|
343
|
+
[
|
|
344
|
+
f"{LiteralVar.create(key).json()}:{LiteralVar.create(value).json()}"
|
|
345
|
+
for key, value in self._var_value.items()
|
|
346
|
+
]
|
|
347
|
+
)
|
|
348
|
+
+ "}"
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
def __hash__(self) -> int:
|
|
352
|
+
"""Get the hash of the var.
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
The hash of the var.
|
|
356
|
+
"""
|
|
357
|
+
return hash((self.__class__.__name__, self._js_expr))
|
|
358
|
+
|
|
359
|
+
@cached_property_no_lock
|
|
360
|
+
def _cached_get_all_var_data(self) -> VarData | None:
|
|
361
|
+
"""Get all the var data.
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
The var data.
|
|
365
|
+
"""
|
|
366
|
+
return VarData.merge(
|
|
367
|
+
*[LiteralVar.create(var)._get_all_var_data() for var in self._var_value],
|
|
368
|
+
*[
|
|
369
|
+
LiteralVar.create(var)._get_all_var_data()
|
|
370
|
+
for var in self._var_value.values()
|
|
371
|
+
],
|
|
372
|
+
self._var_data,
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
@classmethod
|
|
376
|
+
def create(
|
|
377
|
+
cls,
|
|
378
|
+
_var_value: OBJECT_TYPE,
|
|
379
|
+
_var_type: GenericType | None = None,
|
|
380
|
+
_var_data: VarData | None = None,
|
|
381
|
+
) -> LiteralObjectVar[OBJECT_TYPE]:
|
|
382
|
+
"""Create the literal object var.
|
|
383
|
+
|
|
384
|
+
Args:
|
|
385
|
+
_var_value: The value of the var.
|
|
386
|
+
_var_type: The type of the var.
|
|
387
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
The literal object var.
|
|
391
|
+
"""
|
|
392
|
+
return LiteralObjectVar(
|
|
393
|
+
_js_expr="",
|
|
394
|
+
_var_type=(figure_out_type(_var_value) if _var_type is None else _var_type),
|
|
395
|
+
_var_data=_var_data,
|
|
396
|
+
_var_value=_var_value,
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@var_operation
|
|
401
|
+
def object_keys_operation(value: ObjectVar):
|
|
402
|
+
"""Get the keys of an object.
|
|
403
|
+
|
|
404
|
+
Args:
|
|
405
|
+
value: The object to get the keys from.
|
|
406
|
+
|
|
407
|
+
Returns:
|
|
408
|
+
The keys of the object.
|
|
409
|
+
"""
|
|
410
|
+
return var_operation_return(
|
|
411
|
+
js_expression=f"Object.keys({value})",
|
|
412
|
+
var_type=List[str],
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
@var_operation
|
|
417
|
+
def object_values_operation(value: ObjectVar):
|
|
418
|
+
"""Get the values of an object.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
value: The object to get the values from.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
The values of the object.
|
|
425
|
+
"""
|
|
426
|
+
return var_operation_return(
|
|
427
|
+
js_expression=f"Object.values({value})",
|
|
428
|
+
var_type=List[value._value_type()],
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
@var_operation
|
|
433
|
+
def object_entries_operation(value: ObjectVar):
|
|
434
|
+
"""Get the entries of an object.
|
|
435
|
+
|
|
436
|
+
Args:
|
|
437
|
+
value: The object to get the entries from.
|
|
438
|
+
|
|
439
|
+
Returns:
|
|
440
|
+
The entries of the object.
|
|
441
|
+
"""
|
|
442
|
+
return var_operation_return(
|
|
443
|
+
js_expression=f"Object.entries({value})",
|
|
444
|
+
var_type=List[Tuple[str, value._value_type()]],
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
@var_operation
|
|
449
|
+
def object_merge_operation(lhs: ObjectVar, rhs: ObjectVar):
|
|
450
|
+
"""Merge two objects.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
lhs: The first object to merge.
|
|
454
|
+
rhs: The second object to merge.
|
|
455
|
+
|
|
456
|
+
Returns:
|
|
457
|
+
The merged object.
|
|
458
|
+
"""
|
|
459
|
+
return var_operation_return(
|
|
460
|
+
js_expression=f"({{...{lhs}, ...{rhs}}})",
|
|
461
|
+
var_type=Dict[
|
|
462
|
+
Union[lhs._key_type(), rhs._key_type()],
|
|
463
|
+
Union[lhs._value_type(), rhs._value_type()],
|
|
464
|
+
],
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
@dataclasses.dataclass(
|
|
469
|
+
eq=False,
|
|
470
|
+
frozen=True,
|
|
471
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
472
|
+
)
|
|
473
|
+
class ObjectItemOperation(CachedVarOperation, Var):
|
|
474
|
+
"""Operation to get an item from an object."""
|
|
475
|
+
|
|
476
|
+
_object: ObjectVar = dataclasses.field(
|
|
477
|
+
default_factory=lambda: LiteralObjectVar.create({})
|
|
478
|
+
)
|
|
479
|
+
_key: Var | Any = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
|
480
|
+
|
|
481
|
+
@cached_property_no_lock
|
|
482
|
+
def _cached_var_name(self) -> str:
|
|
483
|
+
"""The name of the operation.
|
|
484
|
+
|
|
485
|
+
Returns:
|
|
486
|
+
The name of the operation.
|
|
487
|
+
"""
|
|
488
|
+
if types.is_optional(self._object._var_type):
|
|
489
|
+
return f"{str(self._object)}?.[{str(self._key)}]"
|
|
490
|
+
return f"{str(self._object)}[{str(self._key)}]"
|
|
491
|
+
|
|
492
|
+
@classmethod
|
|
493
|
+
def create(
|
|
494
|
+
cls,
|
|
495
|
+
object: ObjectVar,
|
|
496
|
+
key: Var | Any,
|
|
497
|
+
_var_type: GenericType | None = None,
|
|
498
|
+
_var_data: VarData | None = None,
|
|
499
|
+
) -> ObjectItemOperation:
|
|
500
|
+
"""Create the object item operation.
|
|
501
|
+
|
|
502
|
+
Args:
|
|
503
|
+
object: The object to get the item from.
|
|
504
|
+
key: The key to get from the object.
|
|
505
|
+
_var_type: The type of the item.
|
|
506
|
+
_var_data: Additional hooks and imports associated with the operation.
|
|
507
|
+
|
|
508
|
+
Returns:
|
|
509
|
+
The object item operation.
|
|
510
|
+
"""
|
|
511
|
+
return cls(
|
|
512
|
+
_js_expr="",
|
|
513
|
+
_var_type=object._value_type() if _var_type is None else _var_type,
|
|
514
|
+
_var_data=_var_data,
|
|
515
|
+
_object=object,
|
|
516
|
+
_key=key if isinstance(key, Var) else LiteralVar.create(key),
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
@dataclasses.dataclass(
|
|
521
|
+
eq=False,
|
|
522
|
+
frozen=True,
|
|
523
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
524
|
+
)
|
|
525
|
+
class ToObjectOperation(ToOperation, ObjectVar):
|
|
526
|
+
"""Operation to convert a var to an object."""
|
|
527
|
+
|
|
528
|
+
_original: Var = dataclasses.field(
|
|
529
|
+
default_factory=lambda: LiteralObjectVar.create({})
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
_default_var_type: ClassVar[GenericType] = dict
|
|
533
|
+
|
|
534
|
+
def __getattr__(self, name: str) -> Any:
|
|
535
|
+
"""Get an attribute of the var.
|
|
536
|
+
|
|
537
|
+
Args:
|
|
538
|
+
name: The name of the attribute.
|
|
539
|
+
|
|
540
|
+
Returns:
|
|
541
|
+
The attribute of the var.
|
|
542
|
+
"""
|
|
543
|
+
if name == "_js_expr":
|
|
544
|
+
return self._original._js_expr
|
|
545
|
+
return ObjectVar.__getattr__(self, name)
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
@var_operation
|
|
549
|
+
def object_has_own_property_operation(object: ObjectVar, key: Var):
|
|
550
|
+
"""Check if an object has a key.
|
|
551
|
+
|
|
552
|
+
Args:
|
|
553
|
+
object: The object to check.
|
|
554
|
+
key: The key to check.
|
|
555
|
+
|
|
556
|
+
Returns:
|
|
557
|
+
The result of the check.
|
|
558
|
+
"""
|
|
559
|
+
return var_operation_return(
|
|
560
|
+
js_expression=f"{object}.hasOwnProperty({key})",
|
|
561
|
+
var_type=bool,
|
|
562
|
+
)
|