reflex 0.7.1a4__py3-none-any.whl → 0.7.2a1__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/utils/context.js.jinja2 +8 -8
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +3 -3
- reflex/admin.py +1 -2
- reflex/app.py +46 -49
- reflex/app_mixins/lifespan.py +2 -2
- reflex/app_mixins/middleware.py +1 -2
- reflex/assets.py +1 -2
- reflex/base.py +2 -2
- reflex/compiler/compiler.py +51 -16
- reflex/compiler/utils.py +4 -13
- reflex/components/base/app_wrap.pyi +7 -7
- reflex/components/base/bare.py +3 -3
- reflex/components/base/body.pyi +7 -7
- reflex/components/base/document.py +1 -3
- reflex/components/base/document.pyi +32 -32
- reflex/components/base/error_boundary.py +2 -4
- reflex/components/base/error_boundary.pyi +11 -13
- reflex/components/base/fragment.pyi +7 -7
- reflex/components/base/head.pyi +13 -13
- reflex/components/base/link.pyi +22 -22
- reflex/components/base/meta.py +5 -7
- reflex/components/base/meta.pyi +40 -40
- reflex/components/base/script.pyi +11 -14
- reflex/components/base/strict_mode.pyi +7 -7
- reflex/components/component.py +188 -113
- reflex/components/core/auto_scroll.py +8 -1
- reflex/components/core/auto_scroll.pyi +183 -210
- reflex/components/core/banner.py +2 -4
- reflex/components/core/banner.pyi +390 -444
- reflex/components/core/breakpoints.py +5 -5
- reflex/components/core/client_side_routing.pyi +14 -14
- reflex/components/core/clipboard.py +4 -4
- reflex/components/core/clipboard.pyi +12 -14
- reflex/components/core/cond.py +17 -25
- reflex/components/core/debounce.py +3 -3
- reflex/components/core/debounce.pyi +14 -14
- reflex/components/core/foreach.py +7 -2
- reflex/components/core/html.py +1 -3
- reflex/components/core/html.pyi +184 -213
- reflex/components/core/match.py +15 -19
- reflex/components/core/sticky.pyi +930 -1078
- reflex/components/core/upload.py +4 -4
- reflex/components/core/upload.pyi +62 -62
- reflex/components/datadisplay/code.py +6 -6
- reflex/components/datadisplay/code.pyi +1159 -1165
- reflex/components/datadisplay/dataeditor.py +49 -49
- reflex/components/datadisplay/dataeditor.pyi +95 -123
- reflex/components/datadisplay/logo.py +1 -3
- reflex/components/datadisplay/shiki_code_block.py +8 -10
- reflex/components/datadisplay/shiki_code_block.pyi +1678 -1720
- reflex/components/el/element.pyi +7 -7
- reflex/components/el/elements/base.pyi +183 -210
- reflex/components/el/elements/forms.py +23 -23
- reflex/components/el/elements/forms.pyi +2571 -2933
- reflex/components/el/elements/inline.py +4 -4
- reflex/components/el/elements/inline.pyi +5191 -5953
- reflex/components/el/elements/media.py +47 -47
- reflex/components/el/elements/media.pyi +4802 -5500
- reflex/components/el/elements/metadata.py +1 -3
- reflex/components/el/elements/metadata.pyi +782 -896
- reflex/components/el/elements/other.pyi +1278 -1467
- reflex/components/el/elements/scripts.pyi +580 -667
- reflex/components/el/elements/sectioning.pyi +2761 -3166
- reflex/components/el/elements/tables.pyi +1840 -2119
- reflex/components/el/elements/typography.pyi +2772 -3179
- reflex/components/gridjs/datatable.py +7 -7
- reflex/components/gridjs/datatable.pyi +19 -19
- reflex/components/lucide/icon.pyi +21 -21
- reflex/components/markdown/markdown.py +2 -2
- reflex/components/markdown/markdown.pyi +9 -9
- reflex/components/moment/moment.py +11 -12
- reflex/components/moment/moment.pyi +44 -47
- reflex/components/next/base.pyi +7 -7
- reflex/components/next/image.py +3 -3
- reflex/components/next/image.pyi +19 -21
- reflex/components/next/link.pyi +9 -9
- reflex/components/next/video.py +1 -3
- reflex/components/next/video.pyi +9 -9
- reflex/components/plotly/plotly.py +22 -45
- reflex/components/plotly/plotly.pyi +164 -164
- reflex/components/radix/primitives/accordion.py +14 -14
- reflex/components/radix/primitives/accordion.pyi +439 -487
- reflex/components/radix/primitives/base.py +1 -3
- reflex/components/radix/primitives/base.pyi +15 -15
- reflex/components/radix/primitives/drawer.py +3 -3
- reflex/components/radix/primitives/drawer.pyi +110 -116
- reflex/components/radix/primitives/form.py +1 -1
- reflex/components/radix/primitives/form.pyi +668 -752
- reflex/components/radix/primitives/progress.py +6 -6
- reflex/components/radix/primitives/progress.pyi +225 -243
- reflex/components/radix/primitives/slider.py +6 -6
- reflex/components/radix/primitives/slider.pyi +52 -55
- reflex/components/radix/themes/base.py +3 -6
- reflex/components/radix/themes/base.pyi +197 -303
- reflex/components/radix/themes/color_mode.py +5 -5
- reflex/components/radix/themes/color_mode.pyi +366 -436
- reflex/components/radix/themes/components/alert_dialog.pyi +229 -262
- reflex/components/radix/themes/components/aspect_ratio.py +1 -3
- reflex/components/radix/themes/components/aspect_ratio.pyi +8 -8
- reflex/components/radix/themes/components/avatar.pyi +79 -94
- reflex/components/radix/themes/components/badge.pyi +252 -295
- reflex/components/radix/themes/components/button.pyi +269 -314
- reflex/components/radix/themes/components/callout.py +2 -2
- reflex/components/radix/themes/components/callout.pyi +1116 -1290
- reflex/components/radix/themes/components/card.pyi +194 -229
- reflex/components/radix/themes/components/checkbox.pyi +243 -278
- reflex/components/radix/themes/components/checkbox_cards.py +3 -7
- reflex/components/radix/themes/components/checkbox_cards.pyi +101 -135
- reflex/components/radix/themes/components/checkbox_group.py +2 -2
- reflex/components/radix/themes/components/checkbox_group.pyi +83 -96
- reflex/components/radix/themes/components/context_menu.py +18 -15
- reflex/components/radix/themes/components/context_menu.pyi +408 -458
- reflex/components/radix/themes/components/data_list.pyi +122 -147
- reflex/components/radix/themes/components/dialog.pyi +231 -264
- reflex/components/radix/themes/components/dropdown_menu.py +16 -13
- reflex/components/radix/themes/components/dropdown_menu.pyi +223 -246
- reflex/components/radix/themes/components/hover_card.py +2 -2
- reflex/components/radix/themes/components/hover_card.pyi +237 -282
- reflex/components/radix/themes/components/icon_button.pyi +269 -314
- reflex/components/radix/themes/components/inset.py +8 -8
- reflex/components/radix/themes/components/inset.pyi +232 -292
- reflex/components/radix/themes/components/popover.py +2 -2
- reflex/components/radix/themes/components/popover.pyi +229 -271
- reflex/components/radix/themes/components/progress.pyi +80 -96
- reflex/components/radix/themes/components/radio.pyi +73 -86
- reflex/components/radix/themes/components/radio_cards.py +4 -8
- reflex/components/radix/themes/components/radio_cards.pyi +117 -154
- reflex/components/radix/themes/components/radio_group.py +3 -3
- reflex/components/radix/themes/components/radio_group.pyi +250 -291
- reflex/components/radix/themes/components/scroll_area.pyi +14 -20
- reflex/components/radix/themes/components/segmented_control.py +6 -6
- reflex/components/radix/themes/components/segmented_control.pyi +89 -108
- reflex/components/radix/themes/components/select.py +7 -7
- reflex/components/radix/themes/components/select.pyi +376 -444
- reflex/components/radix/themes/components/separator.pyi +79 -93
- reflex/components/radix/themes/components/skeleton.pyi +32 -26
- reflex/components/radix/themes/components/slider.py +8 -8
- reflex/components/radix/themes/components/slider.pyi +99 -122
- reflex/components/radix/themes/components/spinner.pyi +12 -19
- reflex/components/radix/themes/components/switch.pyi +84 -99
- reflex/components/radix/themes/components/table.py +9 -9
- reflex/components/radix/themes/components/table.pyi +1440 -1794
- reflex/components/radix/themes/components/tabs.py +4 -4
- reflex/components/radix/themes/components/tabs.pyi +120 -132
- reflex/components/radix/themes/components/text_area.pyi +281 -331
- reflex/components/radix/themes/components/text_field.py +2 -2
- reflex/components/radix/themes/components/text_field.pyi +639 -734
- reflex/components/radix/themes/components/tooltip.py +6 -6
- reflex/components/radix/themes/components/tooltip.pyi +34 -43
- reflex/components/radix/themes/layout/base.pyi +85 -182
- reflex/components/radix/themes/layout/box.pyi +183 -210
- reflex/components/radix/themes/layout/center.pyi +225 -286
- reflex/components/radix/themes/layout/container.pyi +191 -224
- reflex/components/radix/themes/layout/flex.py +2 -2
- reflex/components/radix/themes/layout/flex.pyi +225 -286
- reflex/components/radix/themes/layout/grid.py +2 -2
- reflex/components/radix/themes/layout/grid.pyi +245 -315
- reflex/components/radix/themes/layout/list.py +2 -2
- reflex/components/radix/themes/layout/list.pyi +712 -815
- reflex/components/radix/themes/layout/section.pyi +187 -221
- reflex/components/radix/themes/layout/spacer.pyi +225 -286
- reflex/components/radix/themes/layout/stack.pyi +625 -768
- reflex/components/radix/themes/typography/blockquote.pyi +257 -299
- reflex/components/radix/themes/typography/code.pyi +259 -304
- reflex/components/radix/themes/typography/heading.pyi +272 -324
- reflex/components/radix/themes/typography/link.pyi +302 -358
- reflex/components/radix/themes/typography/text.pyi +1669 -1945
- reflex/components/react_player/audio.pyi +20 -22
- reflex/components/react_player/react_player.pyi +19 -19
- reflex/components/react_player/video.pyi +20 -22
- reflex/components/recharts/cartesian.py +100 -97
- reflex/components/recharts/cartesian.pyi +891 -1007
- reflex/components/recharts/charts.py +42 -42
- reflex/components/recharts/charts.pyi +212 -249
- reflex/components/recharts/general.py +22 -21
- reflex/components/recharts/general.pyi +198 -223
- reflex/components/recharts/polar.py +42 -45
- reflex/components/recharts/polar.pyi +254 -288
- reflex/components/recharts/recharts.pyi +13 -13
- reflex/components/sonner/toast.py +20 -20
- reflex/components/sonner/toast.pyi +58 -61
- reflex/components/suneditor/editor.py +9 -9
- reflex/components/suneditor/editor.pyi +78 -83
- reflex/components/tags/cond_tag.py +2 -2
- reflex/components/tags/iter_tag.py +10 -14
- reflex/components/tags/match_tag.py +2 -2
- reflex/components/tags/tag.py +10 -10
- reflex/config.py +36 -35
- reflex/constants/__init__.py +56 -53
- reflex/custom_components/custom_components.py +6 -7
- reflex/event.py +38 -42
- reflex/experimental/client_state.py +2 -4
- reflex/experimental/layout.py +2 -2
- reflex/experimental/layout.pyi +579 -663
- reflex/istate/data.py +4 -5
- reflex/middleware/hydrate_middleware.py +2 -2
- reflex/middleware/middleware.py +2 -2
- reflex/model.py +3 -5
- reflex/page.py +2 -2
- reflex/reflex.py +9 -10
- reflex/state.py +77 -49
- reflex/style.py +9 -3
- reflex/testing.py +21 -24
- reflex/utils/console.py +1 -1
- reflex/utils/decorator.py +26 -1
- reflex/utils/exec.py +6 -11
- reflex/utils/export.py +2 -3
- reflex/utils/format.py +4 -4
- reflex/utils/imports.py +12 -12
- reflex/utils/prerequisites.py +35 -84
- reflex/utils/processes.py +5 -5
- reflex/utils/pyi_generator.py +33 -22
- reflex/utils/serializers.py +60 -15
- reflex/utils/types.py +237 -56
- reflex/vars/base.py +122 -72
- reflex/vars/datetime.py +2 -2
- reflex/vars/function.py +52 -55
- reflex/vars/number.py +59 -5
- reflex/vars/object.py +57 -26
- reflex/vars/sequence.py +983 -958
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/METADATA +3 -6
- reflex-0.7.2a1.dist-info/RECORD +405 -0
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/WHEEL +1 -1
- reflex-0.7.1a4.dist-info/RECORD +0 -405
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/LICENSE +0 -0
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/entry_points.txt +0 -0
reflex/vars/sequence.py
CHANGED
|
@@ -2,23 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import collections.abc
|
|
5
6
|
import dataclasses
|
|
6
7
|
import inspect
|
|
7
8
|
import json
|
|
8
9
|
import re
|
|
9
|
-
import typing
|
|
10
10
|
from typing import (
|
|
11
11
|
TYPE_CHECKING,
|
|
12
12
|
Any,
|
|
13
|
-
|
|
13
|
+
Iterable,
|
|
14
14
|
List,
|
|
15
15
|
Literal,
|
|
16
|
+
Mapping,
|
|
16
17
|
NoReturn,
|
|
17
18
|
Sequence,
|
|
18
|
-
Tuple,
|
|
19
19
|
Type,
|
|
20
20
|
TypeVar,
|
|
21
21
|
Union,
|
|
22
|
+
get_args,
|
|
22
23
|
overload,
|
|
23
24
|
)
|
|
24
25
|
|
|
@@ -27,6 +28,7 @@ from typing_extensions import TypeVar as TypingExtensionsTypeVar
|
|
|
27
28
|
from reflex import constants
|
|
28
29
|
from reflex.constants.base import REFLEX_VAR_OPENING_TAG
|
|
29
30
|
from reflex.constants.colors import Color
|
|
31
|
+
from reflex.utils import types
|
|
30
32
|
from reflex.utils.exceptions import VarTypeError
|
|
31
33
|
from reflex.utils.types import GenericType, get_origin
|
|
32
34
|
|
|
@@ -58,1279 +60,1275 @@ if TYPE_CHECKING:
|
|
|
58
60
|
from .function import FunctionVar
|
|
59
61
|
from .object import ObjectVar
|
|
60
62
|
|
|
63
|
+
ARRAY_VAR_TYPE = TypeVar("ARRAY_VAR_TYPE", bound=Sequence, covariant=True)
|
|
64
|
+
OTHER_ARRAY_VAR_TYPE = TypeVar("OTHER_ARRAY_VAR_TYPE", bound=Sequence, covariant=True)
|
|
65
|
+
MAPPING_VAR_TYPE = TypeVar("MAPPING_VAR_TYPE", bound=Mapping, covariant=True)
|
|
61
66
|
|
|
62
|
-
|
|
67
|
+
OTHER_TUPLE = TypeVar("OTHER_TUPLE")
|
|
68
|
+
|
|
69
|
+
INNER_ARRAY_VAR = TypeVar("INNER_ARRAY_VAR")
|
|
63
70
|
|
|
64
71
|
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
KEY_TYPE = TypeVar("KEY_TYPE")
|
|
73
|
+
VALUE_TYPE = TypeVar("VALUE_TYPE")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ArrayVar(Var[ARRAY_VAR_TYPE], python_types=(Sequence, set)):
|
|
77
|
+
"""Base class for immutable array vars."""
|
|
67
78
|
|
|
68
79
|
@overload
|
|
69
|
-
def
|
|
80
|
+
def join(self, sep: StringVar | str = "") -> StringVar: ...
|
|
70
81
|
|
|
71
82
|
@overload
|
|
72
|
-
def
|
|
83
|
+
def join(self, sep: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
73
84
|
|
|
74
|
-
def
|
|
75
|
-
"""
|
|
85
|
+
def join(self, sep: Any = "") -> StringVar:
|
|
86
|
+
"""Join the elements of the array.
|
|
76
87
|
|
|
77
88
|
Args:
|
|
78
|
-
|
|
89
|
+
sep: The separator between elements.
|
|
79
90
|
|
|
80
91
|
Returns:
|
|
81
|
-
The
|
|
92
|
+
The joined elements.
|
|
82
93
|
"""
|
|
83
|
-
if not isinstance(
|
|
84
|
-
raise_unsupported_operand_types("
|
|
94
|
+
if not isinstance(sep, (StringVar, str)):
|
|
95
|
+
raise_unsupported_operand_types("join", (type(self), type(sep)))
|
|
96
|
+
if (
|
|
97
|
+
isinstance(self, LiteralArrayVar)
|
|
98
|
+
and (
|
|
99
|
+
len(
|
|
100
|
+
args := [
|
|
101
|
+
x
|
|
102
|
+
for x in self._var_value
|
|
103
|
+
if isinstance(x, (LiteralStringVar, str))
|
|
104
|
+
]
|
|
105
|
+
)
|
|
106
|
+
== len(self._var_value)
|
|
107
|
+
)
|
|
108
|
+
and isinstance(sep, (LiteralStringVar, str))
|
|
109
|
+
):
|
|
110
|
+
sep_str = sep._var_value if isinstance(sep, LiteralStringVar) else sep
|
|
111
|
+
return LiteralStringVar.create(
|
|
112
|
+
sep_str.join(
|
|
113
|
+
i._var_value if isinstance(i, LiteralStringVar) else i for i in args
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
return array_join_operation(self, sep)
|
|
85
117
|
|
|
86
|
-
|
|
118
|
+
def reverse(self) -> ArrayVar[ARRAY_VAR_TYPE]:
|
|
119
|
+
"""Reverse the array.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
The reversed array.
|
|
123
|
+
"""
|
|
124
|
+
return array_reverse_operation(self)
|
|
87
125
|
|
|
88
126
|
@overload
|
|
89
|
-
def
|
|
127
|
+
def __add__(self, other: ArrayVar[ARRAY_VAR_TYPE]) -> ArrayVar[ARRAY_VAR_TYPE]: ...
|
|
90
128
|
|
|
91
129
|
@overload
|
|
92
|
-
def
|
|
130
|
+
def __add__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
93
131
|
|
|
94
|
-
def
|
|
95
|
-
"""Concatenate two
|
|
132
|
+
def __add__(self, other: Any) -> ArrayVar[ARRAY_VAR_TYPE]:
|
|
133
|
+
"""Concatenate two arrays.
|
|
96
134
|
|
|
97
|
-
|
|
98
|
-
other: The other
|
|
135
|
+
Parameters:
|
|
136
|
+
other: The other array to concatenate.
|
|
99
137
|
|
|
100
138
|
Returns:
|
|
101
|
-
The
|
|
139
|
+
ArrayConcatOperation: The concatenation of the two arrays.
|
|
102
140
|
"""
|
|
103
|
-
if not isinstance(other,
|
|
104
|
-
raise_unsupported_operand_types("+", (type(
|
|
141
|
+
if not isinstance(other, ArrayVar):
|
|
142
|
+
raise_unsupported_operand_types("+", (type(self), type(other)))
|
|
105
143
|
|
|
106
|
-
return
|
|
144
|
+
return array_concat_operation(self, other)
|
|
107
145
|
|
|
108
146
|
@overload
|
|
109
|
-
def
|
|
147
|
+
def __getitem__(self, i: slice) -> ArrayVar[ARRAY_VAR_TYPE]: ...
|
|
110
148
|
|
|
111
149
|
@overload
|
|
112
|
-
def
|
|
150
|
+
def __getitem__(
|
|
151
|
+
self: (
|
|
152
|
+
ArrayVar[tuple[int, OTHER_TUPLE]]
|
|
153
|
+
| ArrayVar[tuple[float, OTHER_TUPLE]]
|
|
154
|
+
| ArrayVar[tuple[int | float, OTHER_TUPLE]]
|
|
155
|
+
),
|
|
156
|
+
i: Literal[0, -2],
|
|
157
|
+
) -> NumberVar: ...
|
|
113
158
|
|
|
114
|
-
|
|
115
|
-
|
|
159
|
+
@overload
|
|
160
|
+
def __getitem__(
|
|
161
|
+
self: ArrayVar[tuple[Any, bool]], i: Literal[1, -1]
|
|
162
|
+
) -> BooleanVar: ...
|
|
116
163
|
|
|
117
|
-
|
|
118
|
-
|
|
164
|
+
@overload
|
|
165
|
+
def __getitem__(
|
|
166
|
+
self: (
|
|
167
|
+
ArrayVar[tuple[Any, int]]
|
|
168
|
+
| ArrayVar[tuple[Any, float]]
|
|
169
|
+
| ArrayVar[tuple[Any, int | float]]
|
|
170
|
+
),
|
|
171
|
+
i: Literal[1, -1],
|
|
172
|
+
) -> NumberVar: ...
|
|
119
173
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
raise_unsupported_operand_types("*", (type(self), type(other)))
|
|
174
|
+
@overload
|
|
175
|
+
def __getitem__( # pyright: ignore [reportOverlappingOverload]
|
|
176
|
+
self: ArrayVar[tuple[str, Any]], i: Literal[0, -2]
|
|
177
|
+
) -> StringVar: ...
|
|
125
178
|
|
|
126
|
-
|
|
179
|
+
@overload
|
|
180
|
+
def __getitem__(
|
|
181
|
+
self: ArrayVar[tuple[Any, str]], i: Literal[1, -1]
|
|
182
|
+
) -> StringVar: ...
|
|
127
183
|
|
|
128
184
|
@overload
|
|
129
|
-
def
|
|
185
|
+
def __getitem__(
|
|
186
|
+
self: ArrayVar[tuple[bool, Any]], i: Literal[0, -2]
|
|
187
|
+
) -> BooleanVar: ...
|
|
130
188
|
|
|
131
189
|
@overload
|
|
132
|
-
def
|
|
190
|
+
def __getitem__(
|
|
191
|
+
self: ArrayVar[Sequence[bool]], i: int | NumberVar
|
|
192
|
+
) -> BooleanVar: ...
|
|
133
193
|
|
|
134
|
-
|
|
135
|
-
|
|
194
|
+
@overload
|
|
195
|
+
def __getitem__(
|
|
196
|
+
self: (
|
|
197
|
+
ArrayVar[Sequence[int]]
|
|
198
|
+
| ArrayVar[Sequence[float]]
|
|
199
|
+
| ArrayVar[Sequence[int | float]]
|
|
200
|
+
),
|
|
201
|
+
i: int | NumberVar,
|
|
202
|
+
) -> NumberVar: ...
|
|
136
203
|
|
|
137
|
-
|
|
138
|
-
|
|
204
|
+
@overload
|
|
205
|
+
def __getitem__(self: ArrayVar[Sequence[str]], i: int | NumberVar) -> StringVar: ...
|
|
139
206
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
207
|
+
@overload
|
|
208
|
+
def __getitem__(
|
|
209
|
+
self: ArrayVar[Sequence[OTHER_ARRAY_VAR_TYPE]],
|
|
210
|
+
i: int | NumberVar,
|
|
211
|
+
) -> ArrayVar[OTHER_ARRAY_VAR_TYPE]: ...
|
|
145
212
|
|
|
146
|
-
|
|
213
|
+
@overload
|
|
214
|
+
def __getitem__(
|
|
215
|
+
self: ArrayVar[Sequence[MAPPING_VAR_TYPE]],
|
|
216
|
+
i: int | NumberVar,
|
|
217
|
+
) -> ObjectVar[MAPPING_VAR_TYPE]: ...
|
|
147
218
|
|
|
148
219
|
@overload
|
|
149
|
-
def __getitem__(
|
|
220
|
+
def __getitem__(
|
|
221
|
+
self: ArrayVar[Sequence[BASE_TYPE]],
|
|
222
|
+
i: int | NumberVar,
|
|
223
|
+
) -> ObjectVar[BASE_TYPE]: ...
|
|
150
224
|
|
|
151
225
|
@overload
|
|
152
|
-
def __getitem__(
|
|
226
|
+
def __getitem__(
|
|
227
|
+
self: ArrayVar[Sequence[SQLA_TYPE]],
|
|
228
|
+
i: int | NumberVar,
|
|
229
|
+
) -> ObjectVar[SQLA_TYPE]: ...
|
|
153
230
|
|
|
154
|
-
|
|
155
|
-
|
|
231
|
+
@overload
|
|
232
|
+
def __getitem__(
|
|
233
|
+
self: ArrayVar[Sequence[DATACLASS_TYPE]],
|
|
234
|
+
i: int | NumberVar,
|
|
235
|
+
) -> ObjectVar[DATACLASS_TYPE]: ...
|
|
236
|
+
|
|
237
|
+
@overload
|
|
238
|
+
def __getitem__(self, i: int | NumberVar) -> Var: ...
|
|
239
|
+
|
|
240
|
+
def __getitem__(self, i: Any) -> ArrayVar[ARRAY_VAR_TYPE] | Var:
|
|
241
|
+
"""Get a slice of the array.
|
|
156
242
|
|
|
157
243
|
Args:
|
|
158
244
|
i: The slice.
|
|
159
245
|
|
|
160
246
|
Returns:
|
|
161
|
-
The
|
|
247
|
+
The array slice operation.
|
|
162
248
|
"""
|
|
163
249
|
if isinstance(i, slice):
|
|
164
|
-
return
|
|
250
|
+
return ArraySliceOperation.create(self, i)
|
|
165
251
|
if not isinstance(i, (int, NumberVar)) or (
|
|
166
252
|
isinstance(i, NumberVar) and i._is_strict_float()
|
|
167
253
|
):
|
|
168
254
|
raise_unsupported_operand_types("[]", (type(self), type(i)))
|
|
169
|
-
return
|
|
255
|
+
return array_item_operation(self, i)
|
|
170
256
|
|
|
171
|
-
def length(self) -> NumberVar:
|
|
172
|
-
"""Get the length of the
|
|
257
|
+
def length(self) -> NumberVar[int]:
|
|
258
|
+
"""Get the length of the array.
|
|
173
259
|
|
|
174
260
|
Returns:
|
|
175
|
-
The
|
|
261
|
+
The length of the array.
|
|
176
262
|
"""
|
|
177
|
-
return self
|
|
263
|
+
return array_length_operation(self)
|
|
178
264
|
|
|
179
|
-
|
|
180
|
-
|
|
265
|
+
@overload
|
|
266
|
+
@classmethod
|
|
267
|
+
def range(cls, stop: int | NumberVar, /) -> ArrayVar[List[int]]: ...
|
|
181
268
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
269
|
+
@overload
|
|
270
|
+
@classmethod
|
|
271
|
+
def range(
|
|
272
|
+
cls,
|
|
273
|
+
start: int | NumberVar,
|
|
274
|
+
end: int | NumberVar,
|
|
275
|
+
step: int | NumberVar = 1,
|
|
276
|
+
/,
|
|
277
|
+
) -> ArrayVar[List[int]]: ...
|
|
186
278
|
|
|
187
|
-
|
|
188
|
-
|
|
279
|
+
@overload
|
|
280
|
+
@classmethod
|
|
281
|
+
def range(
|
|
282
|
+
cls,
|
|
283
|
+
first_endpoint: int | NumberVar,
|
|
284
|
+
second_endpoint: int | NumberVar | None = None,
|
|
285
|
+
step: int | NumberVar | None = None,
|
|
286
|
+
) -> ArrayVar[List[int]]: ...
|
|
189
287
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
288
|
+
@classmethod
|
|
289
|
+
def range(
|
|
290
|
+
cls,
|
|
291
|
+
first_endpoint: int | NumberVar,
|
|
292
|
+
second_endpoint: int | NumberVar | None = None,
|
|
293
|
+
step: int | NumberVar | None = None,
|
|
294
|
+
) -> ArrayVar[List[int]]:
|
|
295
|
+
"""Create a range of numbers.
|
|
194
296
|
|
|
195
|
-
|
|
196
|
-
|
|
297
|
+
Args:
|
|
298
|
+
first_endpoint: The end of the range if second_endpoint is not provided, otherwise the start of the range.
|
|
299
|
+
second_endpoint: The end of the range.
|
|
300
|
+
step: The step of the range.
|
|
197
301
|
|
|
198
302
|
Returns:
|
|
199
|
-
The
|
|
303
|
+
The range of numbers.
|
|
200
304
|
"""
|
|
201
|
-
|
|
305
|
+
if any(
|
|
306
|
+
not isinstance(i, (int, NumberVar))
|
|
307
|
+
for i in (first_endpoint, second_endpoint, step)
|
|
308
|
+
if i is not None
|
|
309
|
+
):
|
|
310
|
+
raise_unsupported_operand_types(
|
|
311
|
+
"range", (type(first_endpoint), type(second_endpoint), type(step))
|
|
312
|
+
)
|
|
313
|
+
if second_endpoint is None:
|
|
314
|
+
start = 0
|
|
315
|
+
end = first_endpoint
|
|
316
|
+
else:
|
|
317
|
+
start = first_endpoint
|
|
318
|
+
end = second_endpoint
|
|
202
319
|
|
|
203
|
-
|
|
204
|
-
"""Capitalize the string.
|
|
320
|
+
return array_range_operation(start, end, step or 1)
|
|
205
321
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
"""
|
|
209
|
-
return string_capitalize_operation(self)
|
|
322
|
+
@overload
|
|
323
|
+
def contains(self, other: Any) -> BooleanVar: ...
|
|
210
324
|
|
|
211
|
-
|
|
212
|
-
|
|
325
|
+
@overload
|
|
326
|
+
def contains(self, other: Any, field: StringVar | str) -> BooleanVar: ...
|
|
213
327
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
"""
|
|
217
|
-
return string_strip_operation(self)
|
|
218
|
-
|
|
219
|
-
def reversed(self) -> StringVar:
|
|
220
|
-
"""Reverse the string.
|
|
221
|
-
|
|
222
|
-
Returns:
|
|
223
|
-
The string reverse operation.
|
|
224
|
-
"""
|
|
225
|
-
return self.split().reverse().join()
|
|
226
|
-
|
|
227
|
-
@overload
|
|
228
|
-
def contains(
|
|
229
|
-
self, other: StringVar | str, field: StringVar | str | None = None
|
|
230
|
-
) -> BooleanVar: ...
|
|
231
|
-
|
|
232
|
-
@overload
|
|
233
|
-
def contains( # pyright: ignore [reportOverlappingOverload]
|
|
234
|
-
self, other: NoReturn, field: StringVar | str | None = None
|
|
235
|
-
) -> NoReturn: ...
|
|
236
|
-
|
|
237
|
-
def contains(self, other: Any, field: Any = None) -> BooleanVar:
|
|
238
|
-
"""Check if the string contains another string.
|
|
328
|
+
def contains(self, other: Any, field: Any = None) -> BooleanVar:
|
|
329
|
+
"""Check if the array contains an element.
|
|
239
330
|
|
|
240
331
|
Args:
|
|
241
|
-
other: The
|
|
332
|
+
other: The element to check for.
|
|
242
333
|
field: The field to check.
|
|
243
334
|
|
|
244
335
|
Returns:
|
|
245
|
-
The
|
|
336
|
+
The array contains operation.
|
|
246
337
|
"""
|
|
247
|
-
if not isinstance(other, (StringVar, str)):
|
|
248
|
-
raise_unsupported_operand_types("contains", (type(self), type(other)))
|
|
249
338
|
if field is not None:
|
|
250
339
|
if not isinstance(field, (StringVar, str)):
|
|
251
340
|
raise_unsupported_operand_types("contains", (type(self), type(field)))
|
|
252
|
-
return
|
|
253
|
-
return
|
|
254
|
-
|
|
255
|
-
@overload
|
|
256
|
-
def split(self, separator: StringVar | str = "") -> ArrayVar[List[str]]: ...
|
|
257
|
-
|
|
258
|
-
@overload
|
|
259
|
-
def split(self, separator: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
341
|
+
return array_contains_field_operation(self, other, field)
|
|
342
|
+
return array_contains_operation(self, other)
|
|
260
343
|
|
|
261
|
-
def
|
|
262
|
-
"""
|
|
344
|
+
def pluck(self, field: StringVar | str) -> ArrayVar:
|
|
345
|
+
"""Pluck a field from the array.
|
|
263
346
|
|
|
264
347
|
Args:
|
|
265
|
-
|
|
348
|
+
field: The field to pluck from the array.
|
|
266
349
|
|
|
267
350
|
Returns:
|
|
268
|
-
The
|
|
351
|
+
The array pluck operation.
|
|
269
352
|
"""
|
|
270
|
-
|
|
271
|
-
raise_unsupported_operand_types("split", (type(self), type(separator)))
|
|
272
|
-
return string_split_operation(self, separator)
|
|
353
|
+
return array_pluck_operation(self, field)
|
|
273
354
|
|
|
274
355
|
@overload
|
|
275
|
-
def
|
|
356
|
+
def __mul__(self, other: NumberVar | int) -> ArrayVar[ARRAY_VAR_TYPE]: ...
|
|
276
357
|
|
|
277
358
|
@overload
|
|
278
|
-
def
|
|
359
|
+
def __mul__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
279
360
|
|
|
280
|
-
def
|
|
281
|
-
"""
|
|
361
|
+
def __mul__(self, other: Any) -> ArrayVar[ARRAY_VAR_TYPE]:
|
|
362
|
+
"""Multiply the sequence by a number or integer.
|
|
282
363
|
|
|
283
|
-
|
|
284
|
-
|
|
364
|
+
Parameters:
|
|
365
|
+
other: The number or integer to multiply the sequence by.
|
|
285
366
|
|
|
286
367
|
Returns:
|
|
287
|
-
The
|
|
368
|
+
ArrayVar[ARRAY_VAR_TYPE]: The result of multiplying the sequence by the given number or integer.
|
|
288
369
|
"""
|
|
289
|
-
if not isinstance(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
@overload
|
|
294
|
-
def endswith(self, suffix: StringVar | str) -> BooleanVar: ...
|
|
295
|
-
|
|
296
|
-
@overload
|
|
297
|
-
def endswith(self, suffix: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
298
|
-
|
|
299
|
-
def endswith(self, suffix: Any) -> BooleanVar:
|
|
300
|
-
"""Check if the string ends with a suffix.
|
|
370
|
+
if not isinstance(other, (NumberVar, int)) or (
|
|
371
|
+
isinstance(other, NumberVar) and other._is_strict_float()
|
|
372
|
+
):
|
|
373
|
+
raise_unsupported_operand_types("*", (type(self), type(other)))
|
|
301
374
|
|
|
302
|
-
|
|
303
|
-
suffix: The suffix.
|
|
375
|
+
return repeat_array_operation(self, other)
|
|
304
376
|
|
|
305
|
-
|
|
306
|
-
The string ends with operation.
|
|
307
|
-
"""
|
|
308
|
-
if not isinstance(suffix, (StringVar, str)):
|
|
309
|
-
raise_unsupported_operand_types("endswith", (type(self), type(suffix)))
|
|
310
|
-
return string_ends_with_operation(self, suffix)
|
|
377
|
+
__rmul__ = __mul__
|
|
311
378
|
|
|
312
379
|
@overload
|
|
313
|
-
def __lt__(self, other:
|
|
380
|
+
def __lt__(self, other: ArrayVar[ARRAY_VAR_TYPE]) -> BooleanVar: ...
|
|
314
381
|
|
|
315
382
|
@overload
|
|
316
|
-
def __lt__(self, other:
|
|
383
|
+
def __lt__(self, other: list | tuple) -> BooleanVar: ...
|
|
317
384
|
|
|
318
385
|
def __lt__(self, other: Any):
|
|
319
|
-
"""Check if the
|
|
386
|
+
"""Check if the array is less than another array.
|
|
320
387
|
|
|
321
388
|
Args:
|
|
322
|
-
other: The other
|
|
389
|
+
other: The other array.
|
|
323
390
|
|
|
324
391
|
Returns:
|
|
325
|
-
The
|
|
392
|
+
The array less than operation.
|
|
326
393
|
"""
|
|
327
|
-
if not isinstance(other, (
|
|
394
|
+
if not isinstance(other, (ArrayVar, list, tuple)):
|
|
328
395
|
raise_unsupported_operand_types("<", (type(self), type(other)))
|
|
329
396
|
|
|
330
|
-
return
|
|
397
|
+
return array_lt_operation(self, other)
|
|
331
398
|
|
|
332
399
|
@overload
|
|
333
|
-
def __gt__(self, other:
|
|
400
|
+
def __gt__(self, other: ArrayVar[ARRAY_VAR_TYPE]) -> BooleanVar: ...
|
|
334
401
|
|
|
335
402
|
@overload
|
|
336
|
-
def __gt__(self, other:
|
|
403
|
+
def __gt__(self, other: list | tuple) -> BooleanVar: ...
|
|
337
404
|
|
|
338
405
|
def __gt__(self, other: Any):
|
|
339
|
-
"""Check if the
|
|
406
|
+
"""Check if the array is greater than another array.
|
|
340
407
|
|
|
341
408
|
Args:
|
|
342
|
-
other: The other
|
|
409
|
+
other: The other array.
|
|
343
410
|
|
|
344
411
|
Returns:
|
|
345
|
-
The
|
|
412
|
+
The array greater than operation.
|
|
346
413
|
"""
|
|
347
|
-
if not isinstance(other, (
|
|
414
|
+
if not isinstance(other, (ArrayVar, list, tuple)):
|
|
348
415
|
raise_unsupported_operand_types(">", (type(self), type(other)))
|
|
349
416
|
|
|
350
|
-
return
|
|
417
|
+
return array_gt_operation(self, other)
|
|
351
418
|
|
|
352
419
|
@overload
|
|
353
|
-
def __le__(self, other:
|
|
420
|
+
def __le__(self, other: ArrayVar[ARRAY_VAR_TYPE]) -> BooleanVar: ...
|
|
354
421
|
|
|
355
422
|
@overload
|
|
356
|
-
def __le__(self, other:
|
|
423
|
+
def __le__(self, other: list | tuple) -> BooleanVar: ...
|
|
357
424
|
|
|
358
425
|
def __le__(self, other: Any):
|
|
359
|
-
"""Check if the
|
|
426
|
+
"""Check if the array is less than or equal to another array.
|
|
360
427
|
|
|
361
428
|
Args:
|
|
362
|
-
other: The other
|
|
429
|
+
other: The other array.
|
|
363
430
|
|
|
364
431
|
Returns:
|
|
365
|
-
The
|
|
432
|
+
The array less than or equal operation.
|
|
366
433
|
"""
|
|
367
|
-
if not isinstance(other, (
|
|
434
|
+
if not isinstance(other, (ArrayVar, list, tuple)):
|
|
368
435
|
raise_unsupported_operand_types("<=", (type(self), type(other)))
|
|
369
436
|
|
|
370
|
-
return
|
|
437
|
+
return array_le_operation(self, other)
|
|
371
438
|
|
|
372
439
|
@overload
|
|
373
|
-
def __ge__(self, other:
|
|
440
|
+
def __ge__(self, other: ArrayVar[ARRAY_VAR_TYPE]) -> BooleanVar: ...
|
|
374
441
|
|
|
375
442
|
@overload
|
|
376
|
-
def __ge__(self, other:
|
|
443
|
+
def __ge__(self, other: list | tuple) -> BooleanVar: ...
|
|
377
444
|
|
|
378
445
|
def __ge__(self, other: Any):
|
|
379
|
-
"""Check if the
|
|
446
|
+
"""Check if the array is greater than or equal to another array.
|
|
380
447
|
|
|
381
448
|
Args:
|
|
382
|
-
other: The other
|
|
449
|
+
other: The other array.
|
|
383
450
|
|
|
384
451
|
Returns:
|
|
385
|
-
The
|
|
452
|
+
The array greater than or equal operation.
|
|
386
453
|
"""
|
|
387
|
-
if not isinstance(other, (
|
|
454
|
+
if not isinstance(other, (ArrayVar, list, tuple)):
|
|
388
455
|
raise_unsupported_operand_types(">=", (type(self), type(other)))
|
|
389
456
|
|
|
390
|
-
return
|
|
391
|
-
|
|
392
|
-
@overload
|
|
393
|
-
def replace( # pyright: ignore [reportOverlappingOverload]
|
|
394
|
-
self, search_value: StringVar | str, new_value: StringVar | str
|
|
395
|
-
) -> StringVar: ...
|
|
396
|
-
|
|
397
|
-
@overload
|
|
398
|
-
def replace(
|
|
399
|
-
self, search_value: Any, new_value: Any
|
|
400
|
-
) -> CustomVarOperationReturn[StringVar]: ...
|
|
457
|
+
return array_ge_operation(self, other)
|
|
401
458
|
|
|
402
|
-
def
|
|
403
|
-
"""
|
|
459
|
+
def foreach(self, fn: Any):
|
|
460
|
+
"""Apply a function to each element of the array.
|
|
404
461
|
|
|
405
462
|
Args:
|
|
406
|
-
|
|
407
|
-
new_value: The value to be replaced with.
|
|
463
|
+
fn: The function to apply.
|
|
408
464
|
|
|
409
465
|
Returns:
|
|
410
|
-
The
|
|
411
|
-
"""
|
|
412
|
-
if not isinstance(search_value, (StringVar, str)):
|
|
413
|
-
raise_unsupported_operand_types("replace", (type(self), type(search_value)))
|
|
414
|
-
if not isinstance(new_value, (StringVar, str)):
|
|
415
|
-
raise_unsupported_operand_types("replace", (type(self), type(new_value)))
|
|
416
|
-
|
|
417
|
-
return string_replace_operation(self, search_value, new_value)
|
|
466
|
+
The array after applying the function.
|
|
418
467
|
|
|
468
|
+
Raises:
|
|
469
|
+
VarTypeError: If the function takes more than one argument.
|
|
470
|
+
"""
|
|
471
|
+
from .function import ArgsFunctionOperation
|
|
419
472
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
473
|
+
if not callable(fn):
|
|
474
|
+
raise_unsupported_operand_types("foreach", (type(self), type(fn)))
|
|
475
|
+
# get the number of arguments of the function
|
|
476
|
+
num_args = len(inspect.signature(fn).parameters)
|
|
477
|
+
if num_args > 1:
|
|
478
|
+
raise VarTypeError(
|
|
479
|
+
"The function passed to foreach should take at most one argument."
|
|
480
|
+
)
|
|
423
481
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
482
|
+
if num_args == 0:
|
|
483
|
+
return_value = fn()
|
|
484
|
+
function_var = ArgsFunctionOperation.create((), return_value)
|
|
485
|
+
else:
|
|
486
|
+
# generic number var
|
|
487
|
+
number_var = Var("").to(NumberVar, int)
|
|
427
488
|
|
|
428
|
-
|
|
429
|
-
The string less than operation.
|
|
430
|
-
"""
|
|
431
|
-
return var_operation_return(js_expression=f"{lhs} < {rhs}", var_type=bool)
|
|
489
|
+
first_arg_type = self[number_var]._var_type
|
|
432
490
|
|
|
491
|
+
arg_name = get_unique_variable_name()
|
|
433
492
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
493
|
+
# get first argument type
|
|
494
|
+
first_arg = Var(
|
|
495
|
+
_js_expr=arg_name,
|
|
496
|
+
_var_type=first_arg_type,
|
|
497
|
+
).guess_type()
|
|
437
498
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
499
|
+
function_var = ArgsFunctionOperation.create(
|
|
500
|
+
(arg_name,),
|
|
501
|
+
Var.create(fn(first_arg)),
|
|
502
|
+
)
|
|
441
503
|
|
|
442
|
-
|
|
443
|
-
The string greater than operation.
|
|
444
|
-
"""
|
|
445
|
-
return var_operation_return(js_expression=f"{lhs} > {rhs}", var_type=bool)
|
|
504
|
+
return map_array_operation(self, function_var)
|
|
446
505
|
|
|
447
506
|
|
|
448
|
-
@
|
|
449
|
-
|
|
450
|
-
|
|
507
|
+
@dataclasses.dataclass(
|
|
508
|
+
eq=False,
|
|
509
|
+
frozen=True,
|
|
510
|
+
slots=True,
|
|
511
|
+
)
|
|
512
|
+
class LiteralArrayVar(CachedVarOperation, LiteralVar, ArrayVar[ARRAY_VAR_TYPE]):
|
|
513
|
+
"""Base class for immutable literal array vars."""
|
|
451
514
|
|
|
452
|
-
|
|
453
|
-
lhs: The left-hand side string.
|
|
454
|
-
rhs: The right-hand side string.
|
|
515
|
+
_var_value: Sequence[Union[Var, Any]] = dataclasses.field(default=())
|
|
455
516
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
return var_operation_return(js_expression=f"{lhs} <= {rhs}", var_type=bool)
|
|
517
|
+
@cached_property_no_lock
|
|
518
|
+
def _cached_var_name(self) -> str:
|
|
519
|
+
"""The name of the var.
|
|
460
520
|
|
|
521
|
+
Returns:
|
|
522
|
+
The name of the var.
|
|
523
|
+
"""
|
|
524
|
+
return (
|
|
525
|
+
"["
|
|
526
|
+
+ ", ".join(
|
|
527
|
+
[str(LiteralVar.create(element)) for element in self._var_value]
|
|
528
|
+
)
|
|
529
|
+
+ "]"
|
|
530
|
+
)
|
|
461
531
|
|
|
462
|
-
@
|
|
463
|
-
def
|
|
464
|
-
|
|
532
|
+
@cached_property_no_lock
|
|
533
|
+
def _cached_get_all_var_data(self) -> VarData | None:
|
|
534
|
+
"""Get all the VarData associated with the Var.
|
|
465
535
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
536
|
+
Returns:
|
|
537
|
+
The VarData associated with the Var.
|
|
538
|
+
"""
|
|
539
|
+
return VarData.merge(
|
|
540
|
+
*[
|
|
541
|
+
LiteralVar.create(element)._get_all_var_data()
|
|
542
|
+
for element in self._var_value
|
|
543
|
+
],
|
|
544
|
+
self._var_data,
|
|
545
|
+
)
|
|
474
546
|
|
|
547
|
+
def __hash__(self) -> int:
|
|
548
|
+
"""Get the hash of the var.
|
|
475
549
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
550
|
+
Returns:
|
|
551
|
+
The hash of the var.
|
|
552
|
+
"""
|
|
553
|
+
return hash((self.__class__.__name__, self._js_expr))
|
|
479
554
|
|
|
480
|
-
|
|
481
|
-
|
|
555
|
+
def json(self) -> str:
|
|
556
|
+
"""Get the JSON representation of the var.
|
|
482
557
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
"""
|
|
486
|
-
return var_operation_return(js_expression=f"{string}.toLowerCase()", var_type=str)
|
|
558
|
+
Returns:
|
|
559
|
+
The JSON representation of the var.
|
|
487
560
|
|
|
561
|
+
Raises:
|
|
562
|
+
TypeError: If the array elements are not of type LiteralVar.
|
|
563
|
+
"""
|
|
564
|
+
elements = []
|
|
565
|
+
for element in self._var_value:
|
|
566
|
+
element_var = LiteralVar.create(element)
|
|
567
|
+
if not isinstance(element_var, LiteralVar):
|
|
568
|
+
raise TypeError(
|
|
569
|
+
f"Array elements must be of type LiteralVar, not {type(element_var)}"
|
|
570
|
+
)
|
|
571
|
+
elements.append(element_var.json())
|
|
488
572
|
|
|
489
|
-
|
|
490
|
-
def string_upper_operation(string: StringVar[Any]):
|
|
491
|
-
"""Convert a string to uppercase.
|
|
573
|
+
return "[" + ", ".join(elements) + "]"
|
|
492
574
|
|
|
493
|
-
|
|
494
|
-
|
|
575
|
+
@classmethod
|
|
576
|
+
def create(
|
|
577
|
+
cls,
|
|
578
|
+
value: OTHER_ARRAY_VAR_TYPE,
|
|
579
|
+
_var_type: Type[OTHER_ARRAY_VAR_TYPE] | None = None,
|
|
580
|
+
_var_data: VarData | None = None,
|
|
581
|
+
) -> LiteralArrayVar[OTHER_ARRAY_VAR_TYPE]:
|
|
582
|
+
"""Create a var from a string value.
|
|
495
583
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
584
|
+
Args:
|
|
585
|
+
value: The value to create the var from.
|
|
586
|
+
_var_type: The type of the var.
|
|
587
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
500
588
|
|
|
589
|
+
Returns:
|
|
590
|
+
The var.
|
|
591
|
+
"""
|
|
592
|
+
return LiteralArrayVar(
|
|
593
|
+
_js_expr="",
|
|
594
|
+
_var_type=figure_out_type(value) if _var_type is None else _var_type,
|
|
595
|
+
_var_data=_var_data,
|
|
596
|
+
_var_value=value,
|
|
597
|
+
)
|
|
501
598
|
|
|
502
|
-
@var_operation
|
|
503
|
-
def string_title_operation(string: StringVar[Any]):
|
|
504
|
-
"""Convert a string to title case.
|
|
505
599
|
|
|
506
|
-
|
|
507
|
-
string: The string to convert.
|
|
600
|
+
STRING_TYPE = TypingExtensionsTypeVar("STRING_TYPE", default=str)
|
|
508
601
|
|
|
509
|
-
Returns:
|
|
510
|
-
The title case string.
|
|
511
|
-
"""
|
|
512
|
-
return var_operation_return(
|
|
513
|
-
js_expression=f"{string}.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ')",
|
|
514
|
-
var_type=str,
|
|
515
|
-
)
|
|
516
602
|
|
|
603
|
+
class StringVar(Var[STRING_TYPE], python_types=str):
|
|
604
|
+
"""Base class for immutable string vars."""
|
|
517
605
|
|
|
518
|
-
@
|
|
519
|
-
def
|
|
520
|
-
"""Capitalize a string.
|
|
606
|
+
@overload
|
|
607
|
+
def __add__(self, other: StringVar | str) -> ConcatVarOperation: ...
|
|
521
608
|
|
|
522
|
-
|
|
523
|
-
|
|
609
|
+
@overload
|
|
610
|
+
def __add__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
524
611
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
"""
|
|
528
|
-
return var_operation_return(
|
|
529
|
-
js_expression=f"(((s) => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase())({string}))",
|
|
530
|
-
var_type=str,
|
|
531
|
-
)
|
|
612
|
+
def __add__(self, other: Any) -> ConcatVarOperation:
|
|
613
|
+
"""Concatenate two strings.
|
|
532
614
|
|
|
615
|
+
Args:
|
|
616
|
+
other: The other string.
|
|
533
617
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
618
|
+
Returns:
|
|
619
|
+
The string concatenation operation.
|
|
620
|
+
"""
|
|
621
|
+
if not isinstance(other, (StringVar, str)):
|
|
622
|
+
raise_unsupported_operand_types("+", (type(self), type(other)))
|
|
537
623
|
|
|
538
|
-
|
|
539
|
-
string: The string to strip.
|
|
624
|
+
return ConcatVarOperation.create(self, other)
|
|
540
625
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
"""
|
|
544
|
-
return var_operation_return(js_expression=f"{string}.trim()", var_type=str)
|
|
626
|
+
@overload
|
|
627
|
+
def __radd__(self, other: StringVar | str) -> ConcatVarOperation: ...
|
|
545
628
|
|
|
629
|
+
@overload
|
|
630
|
+
def __radd__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
546
631
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
haystack: StringVar[Any], needle: StringVar[Any] | str, field: StringVar[Any] | str
|
|
550
|
-
):
|
|
551
|
-
"""Check if a string contains another string.
|
|
632
|
+
def __radd__(self, other: Any) -> ConcatVarOperation:
|
|
633
|
+
"""Concatenate two strings.
|
|
552
634
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
needle: The needle.
|
|
556
|
-
field: The field to check.
|
|
635
|
+
Args:
|
|
636
|
+
other: The other string.
|
|
557
637
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
var_type=bool,
|
|
564
|
-
)
|
|
638
|
+
Returns:
|
|
639
|
+
The string concatenation operation.
|
|
640
|
+
"""
|
|
641
|
+
if not isinstance(other, (StringVar, str)):
|
|
642
|
+
raise_unsupported_operand_types("+", (type(other), type(self)))
|
|
565
643
|
|
|
644
|
+
return ConcatVarOperation.create(other, self)
|
|
566
645
|
|
|
567
|
-
@
|
|
568
|
-
def
|
|
569
|
-
"""Check if a string contains another string.
|
|
646
|
+
@overload
|
|
647
|
+
def __mul__(self, other: NumberVar | int) -> StringVar: ...
|
|
570
648
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
needle: The needle.
|
|
649
|
+
@overload
|
|
650
|
+
def __mul__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
574
651
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
"""
|
|
578
|
-
return var_operation_return(
|
|
579
|
-
js_expression=f"{haystack}.includes({needle})", var_type=bool
|
|
580
|
-
)
|
|
652
|
+
def __mul__(self, other: Any) -> StringVar:
|
|
653
|
+
"""Multiply the sequence by a number or an integer.
|
|
581
654
|
|
|
655
|
+
Args:
|
|
656
|
+
other: The number or integer to multiply the sequence by.
|
|
582
657
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
):
|
|
587
|
-
|
|
658
|
+
Returns:
|
|
659
|
+
StringVar: The resulting sequence after multiplication.
|
|
660
|
+
"""
|
|
661
|
+
if not isinstance(other, (NumberVar, int)):
|
|
662
|
+
raise_unsupported_operand_types("*", (type(self), type(other)))
|
|
588
663
|
|
|
589
|
-
|
|
590
|
-
full_string: The full string.
|
|
591
|
-
prefix: The prefix.
|
|
664
|
+
return (self.split() * other).join()
|
|
592
665
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
"""
|
|
596
|
-
return var_operation_return(
|
|
597
|
-
js_expression=f"{full_string}.startsWith({prefix})", var_type=bool
|
|
598
|
-
)
|
|
666
|
+
@overload
|
|
667
|
+
def __rmul__(self, other: NumberVar | int) -> StringVar: ...
|
|
599
668
|
|
|
669
|
+
@overload
|
|
670
|
+
def __rmul__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
600
671
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
full_string: StringVar[Any], suffix: StringVar[Any] | str
|
|
604
|
-
):
|
|
605
|
-
"""Check if a string ends with a suffix.
|
|
672
|
+
def __rmul__(self, other: Any) -> StringVar:
|
|
673
|
+
"""Multiply the sequence by a number or an integer.
|
|
606
674
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
suffix: The suffix.
|
|
675
|
+
Args:
|
|
676
|
+
other: The number or integer to multiply the sequence by.
|
|
610
677
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
)
|
|
678
|
+
Returns:
|
|
679
|
+
StringVar: The resulting sequence after multiplication.
|
|
680
|
+
"""
|
|
681
|
+
if not isinstance(other, (NumberVar, int)):
|
|
682
|
+
raise_unsupported_operand_types("*", (type(other), type(self)))
|
|
617
683
|
|
|
684
|
+
return (self.split() * other).join()
|
|
618
685
|
|
|
619
|
-
@
|
|
620
|
-
def
|
|
621
|
-
"""Get an item from a string.
|
|
686
|
+
@overload
|
|
687
|
+
def __getitem__(self, i: slice) -> StringVar: ...
|
|
622
688
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
index: The index of the item.
|
|
689
|
+
@overload
|
|
690
|
+
def __getitem__(self, i: int | NumberVar) -> StringVar: ...
|
|
626
691
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
"""
|
|
630
|
-
return var_operation_return(js_expression=f"{string}.at({index})", var_type=str)
|
|
692
|
+
def __getitem__(self, i: Any) -> StringVar:
|
|
693
|
+
"""Get a slice of the string.
|
|
631
694
|
|
|
695
|
+
Args:
|
|
696
|
+
i: The slice.
|
|
632
697
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
698
|
+
Returns:
|
|
699
|
+
The string slice operation.
|
|
700
|
+
"""
|
|
701
|
+
if isinstance(i, slice):
|
|
702
|
+
return self.split()[i].join()
|
|
703
|
+
if not isinstance(i, (int, NumberVar)) or (
|
|
704
|
+
isinstance(i, NumberVar) and i._is_strict_float()
|
|
705
|
+
):
|
|
706
|
+
raise_unsupported_operand_types("[]", (type(self), type(i)))
|
|
707
|
+
return string_item_operation(self, i)
|
|
636
708
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
sep: The separator.
|
|
709
|
+
def length(self) -> NumberVar:
|
|
710
|
+
"""Get the length of the string.
|
|
640
711
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
712
|
+
Returns:
|
|
713
|
+
The string length operation.
|
|
714
|
+
"""
|
|
715
|
+
return self.split().length()
|
|
645
716
|
|
|
717
|
+
def lower(self) -> StringVar:
|
|
718
|
+
"""Convert the string to lowercase.
|
|
646
719
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
)
|
|
651
|
-
"""Replace a string with a value.
|
|
720
|
+
Returns:
|
|
721
|
+
The string lower operation.
|
|
722
|
+
"""
|
|
723
|
+
return string_lower_operation(self)
|
|
652
724
|
|
|
653
|
-
|
|
654
|
-
string
|
|
655
|
-
search_value: The string to search.
|
|
656
|
-
new_value: The value to be replaced with.
|
|
725
|
+
def upper(self) -> StringVar:
|
|
726
|
+
"""Convert the string to uppercase.
|
|
657
727
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
js_expression=f"{string}.replaceAll({search_value}, {new_value})",
|
|
663
|
-
var_type=str,
|
|
664
|
-
)
|
|
728
|
+
Returns:
|
|
729
|
+
The string upper operation.
|
|
730
|
+
"""
|
|
731
|
+
return string_upper_operation(self)
|
|
665
732
|
|
|
733
|
+
def title(self) -> StringVar:
|
|
734
|
+
"""Convert the string to title case.
|
|
666
735
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
)
|
|
671
|
-
_decode_var_pattern = re.compile(_decode_var_pattern_re, flags=re.DOTALL)
|
|
736
|
+
Returns:
|
|
737
|
+
The string title operation.
|
|
738
|
+
"""
|
|
739
|
+
return string_title_operation(self)
|
|
672
740
|
|
|
741
|
+
def capitalize(self) -> StringVar:
|
|
742
|
+
"""Capitalize the string.
|
|
673
743
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
)
|
|
679
|
-
class LiteralStringVar(LiteralVar, StringVar[str]):
|
|
680
|
-
"""Base class for immutable literal string vars."""
|
|
744
|
+
Returns:
|
|
745
|
+
The string capitalize operation.
|
|
746
|
+
"""
|
|
747
|
+
return string_capitalize_operation(self)
|
|
681
748
|
|
|
682
|
-
|
|
749
|
+
def strip(self) -> StringVar:
|
|
750
|
+
"""Strip the string.
|
|
683
751
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
_var_type: GenericType | None = None,
|
|
689
|
-
_var_data: VarData | None = None,
|
|
690
|
-
) -> StringVar:
|
|
691
|
-
"""Create a var from a string value.
|
|
752
|
+
Returns:
|
|
753
|
+
The string strip operation.
|
|
754
|
+
"""
|
|
755
|
+
return string_strip_operation(self)
|
|
692
756
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
_var_type: The type of the var.
|
|
696
|
-
_var_data: Additional hooks and imports associated with the Var.
|
|
757
|
+
def reversed(self) -> StringVar:
|
|
758
|
+
"""Reverse the string.
|
|
697
759
|
|
|
698
760
|
Returns:
|
|
699
|
-
The
|
|
761
|
+
The string reverse operation.
|
|
700
762
|
"""
|
|
701
|
-
|
|
702
|
-
_var_type = _var_type or type(value) or str
|
|
763
|
+
return self.split().reverse().join()
|
|
703
764
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
765
|
+
@overload
|
|
766
|
+
def contains(
|
|
767
|
+
self, other: StringVar | str, field: StringVar | str | None = None
|
|
768
|
+
) -> BooleanVar: ...
|
|
707
769
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
770
|
+
@overload
|
|
771
|
+
def contains( # pyright: ignore [reportOverlappingOverload]
|
|
772
|
+
self, other: NoReturn, field: StringVar | str | None = None
|
|
773
|
+
) -> NoReturn: ...
|
|
711
774
|
|
|
712
|
-
|
|
775
|
+
def contains(self, other: Any, field: Any = None) -> BooleanVar:
|
|
776
|
+
"""Check if the string contains another string.
|
|
713
777
|
|
|
714
|
-
|
|
778
|
+
Args:
|
|
779
|
+
other: The other string.
|
|
780
|
+
field: The field to check.
|
|
715
781
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
782
|
+
Returns:
|
|
783
|
+
The string contains operation.
|
|
784
|
+
"""
|
|
785
|
+
if not isinstance(other, (StringVar, str)):
|
|
786
|
+
raise_unsupported_operand_types("contains", (type(self), type(other)))
|
|
787
|
+
if field is not None:
|
|
788
|
+
if not isinstance(field, (StringVar, str)):
|
|
789
|
+
raise_unsupported_operand_types("contains", (type(self), type(field)))
|
|
790
|
+
return string_contains_field_operation(self, other, field)
|
|
791
|
+
return string_contains_operation(self, other)
|
|
723
792
|
|
|
724
|
-
|
|
793
|
+
@overload
|
|
794
|
+
def split(self, separator: StringVar | str = "") -> ArrayVar[list[str]]: ...
|
|
725
795
|
|
|
726
|
-
|
|
796
|
+
@overload
|
|
797
|
+
def split(self, separator: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
727
798
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
]
|
|
731
|
-
if len(filtered_strings_and_vals) == 1:
|
|
732
|
-
only_string = filtered_strings_and_vals[0]
|
|
733
|
-
if isinstance(only_string, str):
|
|
734
|
-
return LiteralVar.create(only_string).to(StringVar, _var_type)
|
|
735
|
-
else:
|
|
736
|
-
return only_string.to(StringVar, only_string._var_type)
|
|
799
|
+
def split(self, separator: Any = "") -> ArrayVar[list[str]]:
|
|
800
|
+
"""Split the string.
|
|
737
801
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
s
|
|
741
|
-
for s in filtered_strings_and_vals
|
|
742
|
-
if isinstance(s, (str, LiteralStringVar))
|
|
743
|
-
]
|
|
744
|
-
) == len(filtered_strings_and_vals):
|
|
745
|
-
return LiteralStringVar.create(
|
|
746
|
-
"".join(
|
|
747
|
-
s._var_value if isinstance(s, LiteralStringVar) else s
|
|
748
|
-
for s in literal_strings
|
|
749
|
-
),
|
|
750
|
-
_var_type=_var_type,
|
|
751
|
-
_var_data=VarData.merge(
|
|
752
|
-
_var_data,
|
|
753
|
-
*(
|
|
754
|
-
s._get_all_var_data()
|
|
755
|
-
for s in filtered_strings_and_vals
|
|
756
|
-
if isinstance(s, Var)
|
|
757
|
-
),
|
|
758
|
-
),
|
|
759
|
-
)
|
|
802
|
+
Args:
|
|
803
|
+
separator: The separator.
|
|
760
804
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
805
|
+
Returns:
|
|
806
|
+
The string split operation.
|
|
807
|
+
"""
|
|
808
|
+
if not isinstance(separator, (StringVar, str)):
|
|
809
|
+
raise_unsupported_operand_types("split", (type(self), type(separator)))
|
|
810
|
+
return string_split_operation(self, separator)
|
|
765
811
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
if _var_type is str
|
|
769
|
-
else concat_result.to(StringVar, _var_type)
|
|
770
|
-
)
|
|
812
|
+
@overload
|
|
813
|
+
def startswith(self, prefix: StringVar | str) -> BooleanVar: ...
|
|
771
814
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
_var_type=_var_type,
|
|
775
|
-
_var_data=_var_data,
|
|
776
|
-
_var_value=value,
|
|
777
|
-
)
|
|
815
|
+
@overload
|
|
816
|
+
def startswith(self, prefix: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
778
817
|
|
|
779
|
-
def
|
|
780
|
-
"""
|
|
818
|
+
def startswith(self, prefix: Any) -> BooleanVar:
|
|
819
|
+
"""Check if the string starts with a prefix.
|
|
820
|
+
|
|
821
|
+
Args:
|
|
822
|
+
prefix: The prefix.
|
|
781
823
|
|
|
782
824
|
Returns:
|
|
783
|
-
The
|
|
825
|
+
The string starts with operation.
|
|
784
826
|
"""
|
|
785
|
-
|
|
827
|
+
if not isinstance(prefix, (StringVar, str)):
|
|
828
|
+
raise_unsupported_operand_types("startswith", (type(self), type(prefix)))
|
|
829
|
+
return string_starts_with_operation(self, prefix)
|
|
786
830
|
|
|
787
|
-
|
|
788
|
-
|
|
831
|
+
@overload
|
|
832
|
+
def endswith(self, suffix: StringVar | str) -> BooleanVar: ...
|
|
833
|
+
|
|
834
|
+
@overload
|
|
835
|
+
def endswith(self, suffix: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
836
|
+
|
|
837
|
+
def endswith(self, suffix: Any) -> BooleanVar:
|
|
838
|
+
"""Check if the string ends with a suffix.
|
|
839
|
+
|
|
840
|
+
Args:
|
|
841
|
+
suffix: The suffix.
|
|
789
842
|
|
|
790
843
|
Returns:
|
|
791
|
-
The
|
|
844
|
+
The string ends with operation.
|
|
792
845
|
"""
|
|
793
|
-
|
|
846
|
+
if not isinstance(suffix, (StringVar, str)):
|
|
847
|
+
raise_unsupported_operand_types("endswith", (type(self), type(suffix)))
|
|
848
|
+
return string_ends_with_operation(self, suffix)
|
|
794
849
|
|
|
850
|
+
@overload
|
|
851
|
+
def __lt__(self, other: StringVar | str) -> BooleanVar: ...
|
|
795
852
|
|
|
796
|
-
@
|
|
797
|
-
|
|
798
|
-
frozen=True,
|
|
799
|
-
slots=True,
|
|
800
|
-
)
|
|
801
|
-
class ConcatVarOperation(CachedVarOperation, StringVar[str]):
|
|
802
|
-
"""Representing a concatenation of literal string vars."""
|
|
853
|
+
@overload
|
|
854
|
+
def __lt__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
803
855
|
|
|
804
|
-
|
|
856
|
+
def __lt__(self, other: Any):
|
|
857
|
+
"""Check if the string is less than another string.
|
|
805
858
|
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
"""The name of the var.
|
|
859
|
+
Args:
|
|
860
|
+
other: The other string.
|
|
809
861
|
|
|
810
862
|
Returns:
|
|
811
|
-
The
|
|
863
|
+
The string less than operation.
|
|
812
864
|
"""
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
for var in self._var_value:
|
|
816
|
-
if isinstance(var, LiteralStringVar):
|
|
817
|
-
last_string += var._var_value
|
|
818
|
-
else:
|
|
819
|
-
if last_string:
|
|
820
|
-
list_of_strs.append(last_string)
|
|
821
|
-
last_string = ""
|
|
822
|
-
list_of_strs.append(var)
|
|
865
|
+
if not isinstance(other, (StringVar, str)):
|
|
866
|
+
raise_unsupported_operand_types("<", (type(self), type(other)))
|
|
823
867
|
|
|
824
|
-
|
|
825
|
-
list_of_strs.append(last_string)
|
|
826
|
-
|
|
827
|
-
list_of_strs_filtered = [
|
|
828
|
-
str(LiteralVar.create(s)) for s in list_of_strs if isinstance(s, Var) or s
|
|
829
|
-
]
|
|
830
|
-
|
|
831
|
-
if len(list_of_strs_filtered) == 1:
|
|
832
|
-
return list_of_strs_filtered[0]
|
|
833
|
-
|
|
834
|
-
return "(" + "+".join(list_of_strs_filtered) + ")"
|
|
868
|
+
return string_lt_operation(self, other)
|
|
835
869
|
|
|
836
|
-
@
|
|
837
|
-
def
|
|
838
|
-
"""Get all the VarData asVarDatae Var.
|
|
870
|
+
@overload
|
|
871
|
+
def __gt__(self, other: StringVar | str) -> BooleanVar: ...
|
|
839
872
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
"""
|
|
843
|
-
return VarData.merge(
|
|
844
|
-
*[
|
|
845
|
-
var._get_all_var_data()
|
|
846
|
-
for var in self._var_value
|
|
847
|
-
if isinstance(var, Var)
|
|
848
|
-
],
|
|
849
|
-
self._var_data,
|
|
850
|
-
)
|
|
873
|
+
@overload
|
|
874
|
+
def __gt__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
851
875
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
cls,
|
|
855
|
-
*value: Var | str,
|
|
856
|
-
_var_data: VarData | None = None,
|
|
857
|
-
) -> ConcatVarOperation:
|
|
858
|
-
"""Create a var from a string value.
|
|
876
|
+
def __gt__(self, other: Any):
|
|
877
|
+
"""Check if the string is greater than another string.
|
|
859
878
|
|
|
860
879
|
Args:
|
|
861
|
-
|
|
862
|
-
_var_data: Additional hooks and imports associated with the Var.
|
|
880
|
+
other: The other string.
|
|
863
881
|
|
|
864
882
|
Returns:
|
|
865
|
-
The
|
|
883
|
+
The string greater than operation.
|
|
866
884
|
"""
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
_var_type=str,
|
|
870
|
-
_var_data=_var_data,
|
|
871
|
-
_var_value=tuple(map(LiteralVar.create, value)),
|
|
872
|
-
)
|
|
885
|
+
if not isinstance(other, (StringVar, str)):
|
|
886
|
+
raise_unsupported_operand_types(">", (type(self), type(other)))
|
|
873
887
|
|
|
888
|
+
return string_gt_operation(self, other)
|
|
874
889
|
|
|
875
|
-
|
|
876
|
-
|
|
890
|
+
@overload
|
|
891
|
+
def __le__(self, other: StringVar | str) -> BooleanVar: ...
|
|
877
892
|
|
|
878
|
-
|
|
893
|
+
@overload
|
|
894
|
+
def __le__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
879
895
|
|
|
880
|
-
|
|
896
|
+
def __le__(self, other: Any):
|
|
897
|
+
"""Check if the string is less than or equal to another string.
|
|
881
898
|
|
|
882
|
-
|
|
883
|
-
|
|
899
|
+
Args:
|
|
900
|
+
other: The other string.
|
|
884
901
|
|
|
902
|
+
Returns:
|
|
903
|
+
The string less than or equal operation.
|
|
904
|
+
"""
|
|
905
|
+
if not isinstance(other, (StringVar, str)):
|
|
906
|
+
raise_unsupported_operand_types("<=", (type(self), type(other)))
|
|
885
907
|
|
|
886
|
-
|
|
887
|
-
"""Base class for immutable array vars."""
|
|
908
|
+
return string_le_operation(self, other)
|
|
888
909
|
|
|
889
910
|
@overload
|
|
890
|
-
def
|
|
911
|
+
def __ge__(self, other: StringVar | str) -> BooleanVar: ...
|
|
891
912
|
|
|
892
913
|
@overload
|
|
893
|
-
def
|
|
914
|
+
def __ge__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
|
894
915
|
|
|
895
|
-
def
|
|
896
|
-
"""
|
|
916
|
+
def __ge__(self, other: Any):
|
|
917
|
+
"""Check if the string is greater than or equal to another string.
|
|
897
918
|
|
|
898
919
|
Args:
|
|
899
|
-
|
|
920
|
+
other: The other string.
|
|
900
921
|
|
|
901
922
|
Returns:
|
|
902
|
-
The
|
|
923
|
+
The string greater than or equal operation.
|
|
903
924
|
"""
|
|
904
|
-
if not isinstance(
|
|
905
|
-
raise_unsupported_operand_types("
|
|
906
|
-
if (
|
|
907
|
-
isinstance(self, LiteralArrayVar)
|
|
908
|
-
and (
|
|
909
|
-
len(
|
|
910
|
-
args := [
|
|
911
|
-
x
|
|
912
|
-
for x in self._var_value
|
|
913
|
-
if isinstance(x, (LiteralStringVar, str))
|
|
914
|
-
]
|
|
915
|
-
)
|
|
916
|
-
== len(self._var_value)
|
|
917
|
-
)
|
|
918
|
-
and isinstance(sep, (LiteralStringVar, str))
|
|
919
|
-
):
|
|
920
|
-
sep_str = sep._var_value if isinstance(sep, LiteralStringVar) else sep
|
|
921
|
-
return LiteralStringVar.create(
|
|
922
|
-
sep_str.join(
|
|
923
|
-
i._var_value if isinstance(i, LiteralStringVar) else i for i in args
|
|
924
|
-
)
|
|
925
|
-
)
|
|
926
|
-
return array_join_operation(self, sep)
|
|
927
|
-
|
|
928
|
-
def reverse(self) -> ArrayVar[ARRAY_VAR_TYPE]:
|
|
929
|
-
"""Reverse the array.
|
|
925
|
+
if not isinstance(other, (StringVar, str)):
|
|
926
|
+
raise_unsupported_operand_types(">=", (type(self), type(other)))
|
|
930
927
|
|
|
931
|
-
|
|
932
|
-
The reversed array.
|
|
933
|
-
"""
|
|
934
|
-
return array_reverse_operation(self)
|
|
928
|
+
return string_ge_operation(self, other)
|
|
935
929
|
|
|
936
930
|
@overload
|
|
937
|
-
def
|
|
931
|
+
def replace( # pyright: ignore [reportOverlappingOverload]
|
|
932
|
+
self, search_value: StringVar | str, new_value: StringVar | str
|
|
933
|
+
) -> StringVar: ...
|
|
938
934
|
|
|
939
935
|
@overload
|
|
940
|
-
def
|
|
936
|
+
def replace(
|
|
937
|
+
self, search_value: Any, new_value: Any
|
|
938
|
+
) -> CustomVarOperationReturn[StringVar]: ...
|
|
941
939
|
|
|
942
|
-
def
|
|
943
|
-
"""
|
|
940
|
+
def replace(self, search_value: Any, new_value: Any) -> StringVar: # pyright: ignore [reportInconsistentOverload]
|
|
941
|
+
"""Replace a string with a value.
|
|
944
942
|
|
|
945
|
-
|
|
946
|
-
|
|
943
|
+
Args:
|
|
944
|
+
search_value: The string to search.
|
|
945
|
+
new_value: The value to be replaced with.
|
|
947
946
|
|
|
948
947
|
Returns:
|
|
949
|
-
|
|
948
|
+
The string replace operation.
|
|
950
949
|
"""
|
|
951
|
-
if not isinstance(
|
|
952
|
-
raise_unsupported_operand_types("
|
|
950
|
+
if not isinstance(search_value, (StringVar, str)):
|
|
951
|
+
raise_unsupported_operand_types("replace", (type(self), type(search_value)))
|
|
952
|
+
if not isinstance(new_value, (StringVar, str)):
|
|
953
|
+
raise_unsupported_operand_types("replace", (type(self), type(new_value)))
|
|
953
954
|
|
|
954
|
-
return
|
|
955
|
+
return string_replace_operation(self, search_value, new_value)
|
|
955
956
|
|
|
956
|
-
@overload
|
|
957
|
-
def __getitem__(self, i: slice) -> ArrayVar[ARRAY_VAR_TYPE]: ...
|
|
958
957
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
ArrayVar[Tuple[int, OTHER_TUPLE]]
|
|
963
|
-
| ArrayVar[Tuple[float, OTHER_TUPLE]]
|
|
964
|
-
| ArrayVar[Tuple[int | float, OTHER_TUPLE]]
|
|
965
|
-
),
|
|
966
|
-
i: Literal[0, -2],
|
|
967
|
-
) -> NumberVar: ...
|
|
958
|
+
@var_operation
|
|
959
|
+
def string_lt_operation(lhs: StringVar[Any] | str, rhs: StringVar[Any] | str):
|
|
960
|
+
"""Check if a string is less than another string.
|
|
968
961
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
) -> BooleanVar: ...
|
|
962
|
+
Args:
|
|
963
|
+
lhs: The left-hand side string.
|
|
964
|
+
rhs: The right-hand side string.
|
|
973
965
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
| ArrayVar[Tuple[Any, float]]
|
|
979
|
-
| ArrayVar[Tuple[Any, int | float]]
|
|
980
|
-
),
|
|
981
|
-
i: Literal[1, -1],
|
|
982
|
-
) -> NumberVar: ...
|
|
966
|
+
Returns:
|
|
967
|
+
The string less than operation.
|
|
968
|
+
"""
|
|
969
|
+
return var_operation_return(js_expression=f"{lhs} < {rhs}", var_type=bool)
|
|
983
970
|
|
|
984
|
-
@overload
|
|
985
|
-
def __getitem__(
|
|
986
|
-
self: ArrayVar[Tuple[str, Any]], i: Literal[0, -2]
|
|
987
|
-
) -> StringVar: ...
|
|
988
971
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
) -> StringVar: ...
|
|
972
|
+
@var_operation
|
|
973
|
+
def string_gt_operation(lhs: StringVar[Any] | str, rhs: StringVar[Any] | str):
|
|
974
|
+
"""Check if a string is greater than another string.
|
|
993
975
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
) -> BooleanVar: ...
|
|
976
|
+
Args:
|
|
977
|
+
lhs: The left-hand side string.
|
|
978
|
+
rhs: The right-hand side string.
|
|
998
979
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
980
|
+
Returns:
|
|
981
|
+
The string greater than operation.
|
|
982
|
+
"""
|
|
983
|
+
return var_operation_return(js_expression=f"{lhs} > {rhs}", var_type=bool)
|
|
1003
984
|
|
|
1004
|
-
@overload
|
|
1005
|
-
def __getitem__(
|
|
1006
|
-
self: (
|
|
1007
|
-
ARRAY_VAR_OF_LIST_ELEMENT[int]
|
|
1008
|
-
| ARRAY_VAR_OF_LIST_ELEMENT[float]
|
|
1009
|
-
| ARRAY_VAR_OF_LIST_ELEMENT[int | float]
|
|
1010
|
-
),
|
|
1011
|
-
i: int | NumberVar,
|
|
1012
|
-
) -> NumberVar: ...
|
|
1013
985
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
) -> StringVar: ...
|
|
986
|
+
@var_operation
|
|
987
|
+
def string_le_operation(lhs: StringVar[Any] | str, rhs: StringVar[Any] | str):
|
|
988
|
+
"""Check if a string is less than or equal to another string.
|
|
1018
989
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
i: int | NumberVar,
|
|
1023
|
-
) -> ArrayVar[List[INNER_ARRAY_VAR]]: ...
|
|
990
|
+
Args:
|
|
991
|
+
lhs: The left-hand side string.
|
|
992
|
+
rhs: The right-hand side string.
|
|
1024
993
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
) -> ArrayVar[Tuple[KEY_TYPE, VALUE_TYPE]]: ...
|
|
994
|
+
Returns:
|
|
995
|
+
The string less than or equal operation.
|
|
996
|
+
"""
|
|
997
|
+
return var_operation_return(js_expression=f"{lhs} <= {rhs}", var_type=bool)
|
|
1030
998
|
|
|
1031
|
-
@overload
|
|
1032
|
-
def __getitem__(
|
|
1033
|
-
self: ARRAY_VAR_OF_LIST_ELEMENT[Tuple[INNER_ARRAY_VAR, ...]],
|
|
1034
|
-
i: int | NumberVar,
|
|
1035
|
-
) -> ArrayVar[Tuple[INNER_ARRAY_VAR, ...]]: ...
|
|
1036
999
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
i: int | NumberVar,
|
|
1041
|
-
) -> ObjectVar[Dict[KEY_TYPE, VALUE_TYPE]]: ...
|
|
1000
|
+
@var_operation
|
|
1001
|
+
def string_ge_operation(lhs: StringVar[Any] | str, rhs: StringVar[Any] | str):
|
|
1002
|
+
"""Check if a string is greater than or equal to another string.
|
|
1042
1003
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
i: int | NumberVar,
|
|
1047
|
-
) -> ObjectVar[BASE_TYPE]: ...
|
|
1004
|
+
Args:
|
|
1005
|
+
lhs: The left-hand side string.
|
|
1006
|
+
rhs: The right-hand side string.
|
|
1048
1007
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
) -> ObjectVar[SQLA_TYPE]: ...
|
|
1008
|
+
Returns:
|
|
1009
|
+
The string greater than or equal operation.
|
|
1010
|
+
"""
|
|
1011
|
+
return var_operation_return(js_expression=f"{lhs} >= {rhs}", var_type=bool)
|
|
1054
1012
|
|
|
1055
|
-
@overload
|
|
1056
|
-
def __getitem__(
|
|
1057
|
-
self: ARRAY_VAR_OF_LIST_ELEMENT[DATACLASS_TYPE],
|
|
1058
|
-
i: int | NumberVar,
|
|
1059
|
-
) -> ObjectVar[DATACLASS_TYPE]: ...
|
|
1060
1013
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1014
|
+
@var_operation
|
|
1015
|
+
def string_lower_operation(string: StringVar[Any]):
|
|
1016
|
+
"""Convert a string to lowercase.
|
|
1063
1017
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1018
|
+
Args:
|
|
1019
|
+
string: The string to convert.
|
|
1066
1020
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1021
|
+
Returns:
|
|
1022
|
+
The lowercase string.
|
|
1023
|
+
"""
|
|
1024
|
+
return var_operation_return(js_expression=f"{string}.toLowerCase()", var_type=str)
|
|
1069
1025
|
|
|
1070
|
-
Returns:
|
|
1071
|
-
The array slice operation.
|
|
1072
|
-
"""
|
|
1073
|
-
if isinstance(i, slice):
|
|
1074
|
-
return ArraySliceOperation.create(self, i)
|
|
1075
|
-
if not isinstance(i, (int, NumberVar)) or (
|
|
1076
|
-
isinstance(i, NumberVar) and i._is_strict_float()
|
|
1077
|
-
):
|
|
1078
|
-
raise_unsupported_operand_types("[]", (type(self), type(i)))
|
|
1079
|
-
return array_item_operation(self, i)
|
|
1080
1026
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1027
|
+
@var_operation
|
|
1028
|
+
def string_upper_operation(string: StringVar[Any]):
|
|
1029
|
+
"""Convert a string to uppercase.
|
|
1083
1030
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
"""
|
|
1087
|
-
return array_length_operation(self)
|
|
1031
|
+
Args:
|
|
1032
|
+
string: The string to convert.
|
|
1088
1033
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1034
|
+
Returns:
|
|
1035
|
+
The uppercase string.
|
|
1036
|
+
"""
|
|
1037
|
+
return var_operation_return(js_expression=f"{string}.toUpperCase()", var_type=str)
|
|
1092
1038
|
|
|
1093
|
-
@overload
|
|
1094
|
-
@classmethod
|
|
1095
|
-
def range(
|
|
1096
|
-
cls,
|
|
1097
|
-
start: int | NumberVar,
|
|
1098
|
-
end: int | NumberVar,
|
|
1099
|
-
step: int | NumberVar = 1,
|
|
1100
|
-
/,
|
|
1101
|
-
) -> ArrayVar[List[int]]: ...
|
|
1102
1039
|
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
cls,
|
|
1107
|
-
first_endpoint: int | NumberVar,
|
|
1108
|
-
second_endpoint: int | NumberVar | None = None,
|
|
1109
|
-
step: int | NumberVar | None = None,
|
|
1110
|
-
) -> ArrayVar[List[int]]: ...
|
|
1040
|
+
@var_operation
|
|
1041
|
+
def string_title_operation(string: StringVar[Any]):
|
|
1042
|
+
"""Convert a string to title case.
|
|
1111
1043
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
cls,
|
|
1115
|
-
first_endpoint: int | NumberVar,
|
|
1116
|
-
second_endpoint: int | NumberVar | None = None,
|
|
1117
|
-
step: int | NumberVar | None = None,
|
|
1118
|
-
) -> ArrayVar[List[int]]:
|
|
1119
|
-
"""Create a range of numbers.
|
|
1044
|
+
Args:
|
|
1045
|
+
string: The string to convert.
|
|
1120
1046
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1047
|
+
Returns:
|
|
1048
|
+
The title case string.
|
|
1049
|
+
"""
|
|
1050
|
+
return var_operation_return(
|
|
1051
|
+
js_expression=f"{string}.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ')",
|
|
1052
|
+
var_type=str,
|
|
1053
|
+
)
|
|
1125
1054
|
|
|
1126
|
-
Returns:
|
|
1127
|
-
The range of numbers.
|
|
1128
|
-
"""
|
|
1129
|
-
if any(
|
|
1130
|
-
not isinstance(i, (int, NumberVar))
|
|
1131
|
-
for i in (first_endpoint, second_endpoint, step)
|
|
1132
|
-
if i is not None
|
|
1133
|
-
):
|
|
1134
|
-
raise_unsupported_operand_types(
|
|
1135
|
-
"range", (type(first_endpoint), type(second_endpoint), type(step))
|
|
1136
|
-
)
|
|
1137
|
-
if second_endpoint is None:
|
|
1138
|
-
start = 0
|
|
1139
|
-
end = first_endpoint
|
|
1140
|
-
else:
|
|
1141
|
-
start = first_endpoint
|
|
1142
|
-
end = second_endpoint
|
|
1143
1055
|
|
|
1144
|
-
|
|
1056
|
+
@var_operation
|
|
1057
|
+
def string_capitalize_operation(string: StringVar[Any]):
|
|
1058
|
+
"""Capitalize a string.
|
|
1145
1059
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1060
|
+
Args:
|
|
1061
|
+
string: The string to capitalize.
|
|
1148
1062
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1063
|
+
Returns:
|
|
1064
|
+
The capitalized string.
|
|
1065
|
+
"""
|
|
1066
|
+
return var_operation_return(
|
|
1067
|
+
js_expression=f"(((s) => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase())({string}))",
|
|
1068
|
+
var_type=str,
|
|
1069
|
+
)
|
|
1151
1070
|
|
|
1152
|
-
def contains(self, other: Any, field: Any = None) -> BooleanVar:
|
|
1153
|
-
"""Check if the array contains an element.
|
|
1154
1071
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1072
|
+
@var_operation
|
|
1073
|
+
def string_strip_operation(string: StringVar[Any]):
|
|
1074
|
+
"""Strip a string.
|
|
1158
1075
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
"""
|
|
1162
|
-
if field is not None:
|
|
1163
|
-
if not isinstance(field, (StringVar, str)):
|
|
1164
|
-
raise_unsupported_operand_types("contains", (type(self), type(field)))
|
|
1165
|
-
return array_contains_field_operation(self, other, field)
|
|
1166
|
-
return array_contains_operation(self, other)
|
|
1076
|
+
Args:
|
|
1077
|
+
string: The string to strip.
|
|
1167
1078
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1079
|
+
Returns:
|
|
1080
|
+
The stripped string.
|
|
1081
|
+
"""
|
|
1082
|
+
return var_operation_return(js_expression=f"{string}.trim()", var_type=str)
|
|
1170
1083
|
|
|
1171
|
-
Args:
|
|
1172
|
-
field: The field to pluck from the array.
|
|
1173
1084
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1085
|
+
@var_operation
|
|
1086
|
+
def string_contains_field_operation(
|
|
1087
|
+
haystack: StringVar[Any], needle: StringVar[Any] | str, field: StringVar[Any] | str
|
|
1088
|
+
):
|
|
1089
|
+
"""Check if a string contains another string.
|
|
1178
1090
|
|
|
1179
|
-
|
|
1180
|
-
|
|
1091
|
+
Args:
|
|
1092
|
+
haystack: The haystack.
|
|
1093
|
+
needle: The needle.
|
|
1094
|
+
field: The field to check.
|
|
1181
1095
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1096
|
+
Returns:
|
|
1097
|
+
The string contains operation.
|
|
1098
|
+
"""
|
|
1099
|
+
return var_operation_return(
|
|
1100
|
+
js_expression=f"{haystack}.some(obj => obj[{field}] === {needle})",
|
|
1101
|
+
var_type=bool,
|
|
1102
|
+
)
|
|
1184
1103
|
|
|
1185
|
-
def __mul__(self, other: Any) -> ArrayVar[ARRAY_VAR_TYPE]:
|
|
1186
|
-
"""Multiply the sequence by a number or integer.
|
|
1187
1104
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1105
|
+
@var_operation
|
|
1106
|
+
def string_contains_operation(haystack: StringVar[Any], needle: StringVar[Any] | str):
|
|
1107
|
+
"""Check if a string contains another string.
|
|
1190
1108
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
if not isinstance(other, (NumberVar, int)) or (
|
|
1195
|
-
isinstance(other, NumberVar) and other._is_strict_float()
|
|
1196
|
-
):
|
|
1197
|
-
raise_unsupported_operand_types("*", (type(self), type(other)))
|
|
1109
|
+
Args:
|
|
1110
|
+
haystack: The haystack.
|
|
1111
|
+
needle: The needle.
|
|
1198
1112
|
|
|
1199
|
-
|
|
1113
|
+
Returns:
|
|
1114
|
+
The string contains operation.
|
|
1115
|
+
"""
|
|
1116
|
+
return var_operation_return(
|
|
1117
|
+
js_expression=f"{haystack}.includes({needle})", var_type=bool
|
|
1118
|
+
)
|
|
1200
1119
|
|
|
1201
|
-
__rmul__ = __mul__
|
|
1202
1120
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1121
|
+
@var_operation
|
|
1122
|
+
def string_starts_with_operation(
|
|
1123
|
+
full_string: StringVar[Any], prefix: StringVar[Any] | str
|
|
1124
|
+
):
|
|
1125
|
+
"""Check if a string starts with a prefix.
|
|
1205
1126
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1127
|
+
Args:
|
|
1128
|
+
full_string: The full string.
|
|
1129
|
+
prefix: The prefix.
|
|
1208
1130
|
|
|
1209
|
-
|
|
1210
|
-
|
|
1131
|
+
Returns:
|
|
1132
|
+
Whether the string starts with the prefix.
|
|
1133
|
+
"""
|
|
1134
|
+
return var_operation_return(
|
|
1135
|
+
js_expression=f"{full_string}.startsWith({prefix})", var_type=bool
|
|
1136
|
+
)
|
|
1211
1137
|
|
|
1212
|
-
Args:
|
|
1213
|
-
other: The other array.
|
|
1214
1138
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1139
|
+
@var_operation
|
|
1140
|
+
def string_ends_with_operation(
|
|
1141
|
+
full_string: StringVar[Any], suffix: StringVar[Any] | str
|
|
1142
|
+
):
|
|
1143
|
+
"""Check if a string ends with a suffix.
|
|
1220
1144
|
|
|
1221
|
-
|
|
1145
|
+
Args:
|
|
1146
|
+
full_string: The full string.
|
|
1147
|
+
suffix: The suffix.
|
|
1222
1148
|
|
|
1223
|
-
|
|
1224
|
-
|
|
1149
|
+
Returns:
|
|
1150
|
+
Whether the string ends with the suffix.
|
|
1151
|
+
"""
|
|
1152
|
+
return var_operation_return(
|
|
1153
|
+
js_expression=f"{full_string}.endsWith({suffix})", var_type=bool
|
|
1154
|
+
)
|
|
1225
1155
|
|
|
1226
|
-
@overload
|
|
1227
|
-
def __gt__(self, other: list | tuple) -> BooleanVar: ...
|
|
1228
1156
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1157
|
+
@var_operation
|
|
1158
|
+
def string_item_operation(string: StringVar[Any], index: NumberVar | int):
|
|
1159
|
+
"""Get an item from a string.
|
|
1231
1160
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1161
|
+
Args:
|
|
1162
|
+
string: The string.
|
|
1163
|
+
index: The index of the item.
|
|
1234
1164
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
raise_unsupported_operand_types(">", (type(self), type(other)))
|
|
1165
|
+
Returns:
|
|
1166
|
+
The item from the string.
|
|
1167
|
+
"""
|
|
1168
|
+
return var_operation_return(js_expression=f"{string}.at({index})", var_type=str)
|
|
1240
1169
|
|
|
1241
|
-
return array_gt_operation(self, other)
|
|
1242
1170
|
|
|
1243
|
-
|
|
1244
|
-
|
|
1171
|
+
@var_operation
|
|
1172
|
+
def array_join_operation(array: ArrayVar, sep: StringVar[Any] | str = ""):
|
|
1173
|
+
"""Join the elements of an array.
|
|
1245
1174
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1175
|
+
Args:
|
|
1176
|
+
array: The array.
|
|
1177
|
+
sep: The separator.
|
|
1248
1178
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1179
|
+
Returns:
|
|
1180
|
+
The joined elements.
|
|
1181
|
+
"""
|
|
1182
|
+
return var_operation_return(js_expression=f"{array}.join({sep})", var_type=str)
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
@var_operation
|
|
1186
|
+
def string_replace_operation(
|
|
1187
|
+
string: StringVar[Any], search_value: StringVar | str, new_value: StringVar | str
|
|
1188
|
+
):
|
|
1189
|
+
"""Replace a string with a value.
|
|
1190
|
+
|
|
1191
|
+
Args:
|
|
1192
|
+
string: The string.
|
|
1193
|
+
search_value: The string to search.
|
|
1194
|
+
new_value: The value to be replaced with.
|
|
1195
|
+
|
|
1196
|
+
Returns:
|
|
1197
|
+
The string replace operation.
|
|
1198
|
+
"""
|
|
1199
|
+
return var_operation_return(
|
|
1200
|
+
js_expression=f"{string}.replaceAll({search_value}, {new_value})",
|
|
1201
|
+
var_type=str,
|
|
1202
|
+
)
|
|
1251
1203
|
|
|
1252
|
-
Args:
|
|
1253
|
-
other: The other array.
|
|
1254
1204
|
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1205
|
+
# Compile regex for finding reflex var tags.
|
|
1206
|
+
_decode_var_pattern_re = (
|
|
1207
|
+
rf"{constants.REFLEX_VAR_OPENING_TAG}(.*?){constants.REFLEX_VAR_CLOSING_TAG}"
|
|
1208
|
+
)
|
|
1209
|
+
_decode_var_pattern = re.compile(_decode_var_pattern_re, flags=re.DOTALL)
|
|
1260
1210
|
|
|
1261
|
-
return array_le_operation(self, other)
|
|
1262
1211
|
|
|
1263
|
-
|
|
1264
|
-
|
|
1212
|
+
@dataclasses.dataclass(
|
|
1213
|
+
eq=False,
|
|
1214
|
+
frozen=True,
|
|
1215
|
+
slots=True,
|
|
1216
|
+
)
|
|
1217
|
+
class LiteralStringVar(LiteralVar, StringVar[str]):
|
|
1218
|
+
"""Base class for immutable literal string vars."""
|
|
1265
1219
|
|
|
1266
|
-
|
|
1267
|
-
def __ge__(self, other: list | tuple) -> BooleanVar: ...
|
|
1220
|
+
_var_value: str = dataclasses.field(default="")
|
|
1268
1221
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1222
|
+
@classmethod
|
|
1223
|
+
def create(
|
|
1224
|
+
cls,
|
|
1225
|
+
value: str,
|
|
1226
|
+
_var_type: GenericType | None = None,
|
|
1227
|
+
_var_data: VarData | None = None,
|
|
1228
|
+
) -> StringVar:
|
|
1229
|
+
"""Create a var from a string value.
|
|
1271
1230
|
|
|
1272
1231
|
Args:
|
|
1273
|
-
|
|
1232
|
+
value: The value to create the var from.
|
|
1233
|
+
_var_type: The type of the var.
|
|
1234
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
1274
1235
|
|
|
1275
1236
|
Returns:
|
|
1276
|
-
The
|
|
1237
|
+
The var.
|
|
1277
1238
|
"""
|
|
1278
|
-
|
|
1279
|
-
|
|
1239
|
+
# Determine var type in case the value is inherited from str.
|
|
1240
|
+
_var_type = _var_type or type(value) or str
|
|
1280
1241
|
|
|
1281
|
-
|
|
1242
|
+
if REFLEX_VAR_OPENING_TAG in value:
|
|
1243
|
+
strings_and_vals: list[Var | str] = []
|
|
1244
|
+
offset = 0
|
|
1282
1245
|
|
|
1283
|
-
|
|
1284
|
-
|
|
1246
|
+
# Find all tags
|
|
1247
|
+
while m := _decode_var_pattern.search(value):
|
|
1248
|
+
start, end = m.span()
|
|
1285
1249
|
|
|
1286
|
-
|
|
1287
|
-
fn: The function to apply.
|
|
1250
|
+
strings_and_vals.append(value[:start])
|
|
1288
1251
|
|
|
1289
|
-
|
|
1290
|
-
The array after applying the function.
|
|
1252
|
+
serialized_data = m.group(1)
|
|
1291
1253
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1254
|
+
if serialized_data.isnumeric() or (
|
|
1255
|
+
serialized_data[0] == "-" and serialized_data[1:].isnumeric()
|
|
1256
|
+
):
|
|
1257
|
+
# This is a global immutable var.
|
|
1258
|
+
var = _global_vars[int(serialized_data)]
|
|
1259
|
+
strings_and_vals.append(var)
|
|
1260
|
+
value = value[(end + len(var._js_expr)) :]
|
|
1296
1261
|
|
|
1297
|
-
|
|
1298
|
-
raise_unsupported_operand_types("foreach", (type(self), type(fn)))
|
|
1299
|
-
# get the number of arguments of the function
|
|
1300
|
-
num_args = len(inspect.signature(fn).parameters)
|
|
1301
|
-
if num_args > 1:
|
|
1302
|
-
raise VarTypeError(
|
|
1303
|
-
"The function passed to foreach should take at most one argument."
|
|
1304
|
-
)
|
|
1262
|
+
offset += end - start
|
|
1305
1263
|
|
|
1306
|
-
|
|
1307
|
-
return_value = fn()
|
|
1308
|
-
function_var = ArgsFunctionOperation.create((), return_value)
|
|
1309
|
-
else:
|
|
1310
|
-
# generic number var
|
|
1311
|
-
number_var = Var("").to(NumberVar, int)
|
|
1264
|
+
strings_and_vals.append(value)
|
|
1312
1265
|
|
|
1313
|
-
|
|
1266
|
+
filtered_strings_and_vals = [
|
|
1267
|
+
s for s in strings_and_vals if isinstance(s, Var) or s
|
|
1268
|
+
]
|
|
1269
|
+
if len(filtered_strings_and_vals) == 1:
|
|
1270
|
+
only_string = filtered_strings_and_vals[0]
|
|
1271
|
+
if isinstance(only_string, str):
|
|
1272
|
+
return LiteralVar.create(only_string).to(StringVar, _var_type)
|
|
1273
|
+
else:
|
|
1274
|
+
return only_string.to(StringVar, only_string._var_type)
|
|
1314
1275
|
|
|
1315
|
-
|
|
1276
|
+
if len(
|
|
1277
|
+
literal_strings := [
|
|
1278
|
+
s
|
|
1279
|
+
for s in filtered_strings_and_vals
|
|
1280
|
+
if isinstance(s, (str, LiteralStringVar))
|
|
1281
|
+
]
|
|
1282
|
+
) == len(filtered_strings_and_vals):
|
|
1283
|
+
return LiteralStringVar.create(
|
|
1284
|
+
"".join(
|
|
1285
|
+
s._var_value if isinstance(s, LiteralStringVar) else s
|
|
1286
|
+
for s in literal_strings
|
|
1287
|
+
),
|
|
1288
|
+
_var_type=_var_type,
|
|
1289
|
+
_var_data=VarData.merge(
|
|
1290
|
+
_var_data,
|
|
1291
|
+
*(
|
|
1292
|
+
s._get_all_var_data()
|
|
1293
|
+
for s in filtered_strings_and_vals
|
|
1294
|
+
if isinstance(s, Var)
|
|
1295
|
+
),
|
|
1296
|
+
),
|
|
1297
|
+
)
|
|
1316
1298
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
).guess_type()
|
|
1299
|
+
concat_result = ConcatVarOperation.create(
|
|
1300
|
+
*filtered_strings_and_vals,
|
|
1301
|
+
_var_data=_var_data,
|
|
1302
|
+
)
|
|
1322
1303
|
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1304
|
+
return (
|
|
1305
|
+
concat_result
|
|
1306
|
+
if _var_type is str
|
|
1307
|
+
else concat_result.to(StringVar, _var_type)
|
|
1326
1308
|
)
|
|
1327
1309
|
|
|
1328
|
-
return
|
|
1310
|
+
return LiteralStringVar(
|
|
1311
|
+
_js_expr=json.dumps(value),
|
|
1312
|
+
_var_type=_var_type,
|
|
1313
|
+
_var_data=_var_data,
|
|
1314
|
+
_var_value=value,
|
|
1315
|
+
)
|
|
1316
|
+
|
|
1317
|
+
def __hash__(self) -> int:
|
|
1318
|
+
"""Get the hash of the var.
|
|
1329
1319
|
|
|
1320
|
+
Returns:
|
|
1321
|
+
The hash of the var.
|
|
1322
|
+
"""
|
|
1323
|
+
return hash((type(self).__name__, self._var_value))
|
|
1330
1324
|
|
|
1331
|
-
|
|
1325
|
+
def json(self) -> str:
|
|
1326
|
+
"""Get the JSON representation of the var.
|
|
1332
1327
|
|
|
1333
|
-
|
|
1328
|
+
Returns:
|
|
1329
|
+
The JSON representation of the var.
|
|
1330
|
+
"""
|
|
1331
|
+
return json.dumps(self._var_value)
|
|
1334
1332
|
|
|
1335
1333
|
|
|
1336
1334
|
@dataclasses.dataclass(
|
|
@@ -1338,10 +1336,10 @@ ARRAY_VAR_OF_LIST_ELEMENT = ArrayVar[Sequence[LIST_ELEMENT]]
|
|
|
1338
1336
|
frozen=True,
|
|
1339
1337
|
slots=True,
|
|
1340
1338
|
)
|
|
1341
|
-
class
|
|
1342
|
-
"""
|
|
1339
|
+
class ConcatVarOperation(CachedVarOperation, StringVar[str]):
|
|
1340
|
+
"""Representing a concatenation of literal string vars."""
|
|
1343
1341
|
|
|
1344
|
-
_var_value:
|
|
1342
|
+
_var_value: tuple[Var, ...] = dataclasses.field(default_factory=tuple)
|
|
1345
1343
|
|
|
1346
1344
|
@cached_property_no_lock
|
|
1347
1345
|
def _cached_var_name(self) -> str:
|
|
@@ -1350,79 +1348,65 @@ class LiteralArrayVar(CachedVarOperation, LiteralVar, ArrayVar[ARRAY_VAR_TYPE]):
|
|
|
1350
1348
|
Returns:
|
|
1351
1349
|
The name of the var.
|
|
1352
1350
|
"""
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1351
|
+
list_of_strs: list[str | Var] = []
|
|
1352
|
+
last_string = ""
|
|
1353
|
+
for var in self._var_value:
|
|
1354
|
+
if isinstance(var, LiteralStringVar):
|
|
1355
|
+
last_string += var._var_value
|
|
1356
|
+
else:
|
|
1357
|
+
if last_string:
|
|
1358
|
+
list_of_strs.append(last_string)
|
|
1359
|
+
last_string = ""
|
|
1360
|
+
list_of_strs.append(var)
|
|
1361
|
+
|
|
1362
|
+
if last_string:
|
|
1363
|
+
list_of_strs.append(last_string)
|
|
1364
|
+
|
|
1365
|
+
list_of_strs_filtered = [
|
|
1366
|
+
str(LiteralVar.create(s)) for s in list_of_strs if isinstance(s, Var) or s
|
|
1367
|
+
]
|
|
1368
|
+
|
|
1369
|
+
if len(list_of_strs_filtered) == 1:
|
|
1370
|
+
return list_of_strs_filtered[0]
|
|
1371
|
+
|
|
1372
|
+
return "(" + "+".join(list_of_strs_filtered) + ")"
|
|
1360
1373
|
|
|
1361
1374
|
@cached_property_no_lock
|
|
1362
1375
|
def _cached_get_all_var_data(self) -> VarData | None:
|
|
1363
|
-
"""Get all the VarData
|
|
1376
|
+
"""Get all the VarData asVarDatae Var.
|
|
1364
1377
|
|
|
1365
1378
|
Returns:
|
|
1366
1379
|
The VarData associated with the Var.
|
|
1367
1380
|
"""
|
|
1368
1381
|
return VarData.merge(
|
|
1369
1382
|
*[
|
|
1370
|
-
|
|
1371
|
-
for
|
|
1383
|
+
var._get_all_var_data()
|
|
1384
|
+
for var in self._var_value
|
|
1385
|
+
if isinstance(var, Var)
|
|
1372
1386
|
],
|
|
1373
1387
|
self._var_data,
|
|
1374
1388
|
)
|
|
1375
1389
|
|
|
1376
|
-
def __hash__(self) -> int:
|
|
1377
|
-
"""Get the hash of the var.
|
|
1378
|
-
|
|
1379
|
-
Returns:
|
|
1380
|
-
The hash of the var.
|
|
1381
|
-
"""
|
|
1382
|
-
return hash((self.__class__.__name__, self._js_expr))
|
|
1383
|
-
|
|
1384
|
-
def json(self) -> str:
|
|
1385
|
-
"""Get the JSON representation of the var.
|
|
1386
|
-
|
|
1387
|
-
Returns:
|
|
1388
|
-
The JSON representation of the var.
|
|
1389
|
-
|
|
1390
|
-
Raises:
|
|
1391
|
-
TypeError: If the array elements are not of type LiteralVar.
|
|
1392
|
-
"""
|
|
1393
|
-
elements = []
|
|
1394
|
-
for element in self._var_value:
|
|
1395
|
-
element_var = LiteralVar.create(element)
|
|
1396
|
-
if not isinstance(element_var, LiteralVar):
|
|
1397
|
-
raise TypeError(
|
|
1398
|
-
f"Array elements must be of type LiteralVar, not {type(element_var)}"
|
|
1399
|
-
)
|
|
1400
|
-
elements.append(element_var.json())
|
|
1401
|
-
|
|
1402
|
-
return "[" + ", ".join(elements) + "]"
|
|
1403
|
-
|
|
1404
1390
|
@classmethod
|
|
1405
1391
|
def create(
|
|
1406
1392
|
cls,
|
|
1407
|
-
value:
|
|
1408
|
-
_var_type: Type[OTHER_ARRAY_VAR_TYPE] | None = None,
|
|
1393
|
+
*value: Var | str,
|
|
1409
1394
|
_var_data: VarData | None = None,
|
|
1410
|
-
) ->
|
|
1395
|
+
) -> ConcatVarOperation:
|
|
1411
1396
|
"""Create a var from a string value.
|
|
1412
1397
|
|
|
1413
1398
|
Args:
|
|
1414
|
-
value: The
|
|
1415
|
-
_var_type: The type of the var.
|
|
1399
|
+
*value: The values to concatenate.
|
|
1416
1400
|
_var_data: Additional hooks and imports associated with the Var.
|
|
1417
1401
|
|
|
1418
1402
|
Returns:
|
|
1419
1403
|
The var.
|
|
1420
1404
|
"""
|
|
1421
|
-
return
|
|
1405
|
+
return cls(
|
|
1422
1406
|
_js_expr="",
|
|
1423
|
-
_var_type=
|
|
1407
|
+
_var_type=str,
|
|
1424
1408
|
_var_data=_var_data,
|
|
1425
|
-
_var_value=value,
|
|
1409
|
+
_var_value=tuple(map(LiteralVar.create, value)),
|
|
1426
1410
|
)
|
|
1427
1411
|
|
|
1428
1412
|
|
|
@@ -1438,7 +1422,7 @@ def string_split_operation(string: StringVar[Any], sep: StringVar | str = ""):
|
|
|
1438
1422
|
The split string.
|
|
1439
1423
|
"""
|
|
1440
1424
|
return var_operation_return(
|
|
1441
|
-
js_expression=f"{string}.split({sep})", var_type=
|
|
1425
|
+
js_expression=f"{string}.split({sep})", var_type=list[str]
|
|
1442
1426
|
)
|
|
1443
1427
|
|
|
1444
1428
|
|
|
@@ -1638,11 +1622,50 @@ def is_tuple_type(t: GenericType) -> bool:
|
|
|
1638
1622
|
Returns:
|
|
1639
1623
|
Whether the type is a tuple type.
|
|
1640
1624
|
"""
|
|
1641
|
-
if inspect.isclass(t):
|
|
1642
|
-
return issubclass(t, tuple)
|
|
1643
1625
|
return get_origin(t) is tuple
|
|
1644
1626
|
|
|
1645
1627
|
|
|
1628
|
+
def _determine_value_of_array_index(
|
|
1629
|
+
var_type: GenericType, index: int | float | None = None
|
|
1630
|
+
):
|
|
1631
|
+
"""Determine the value of an array index.
|
|
1632
|
+
|
|
1633
|
+
Args:
|
|
1634
|
+
var_type: The type of the array.
|
|
1635
|
+
index: The index of the array.
|
|
1636
|
+
|
|
1637
|
+
Returns:
|
|
1638
|
+
The value of the array index.
|
|
1639
|
+
"""
|
|
1640
|
+
origin_var_type = get_origin(var_type) or var_type
|
|
1641
|
+
if origin_var_type in types.UnionTypes:
|
|
1642
|
+
return unionize(
|
|
1643
|
+
*[
|
|
1644
|
+
_determine_value_of_array_index(t, index)
|
|
1645
|
+
for t in get_args(var_type)
|
|
1646
|
+
if t is not type(None)
|
|
1647
|
+
]
|
|
1648
|
+
)
|
|
1649
|
+
if origin_var_type in [
|
|
1650
|
+
Sequence,
|
|
1651
|
+
Iterable,
|
|
1652
|
+
list,
|
|
1653
|
+
set,
|
|
1654
|
+
collections.abc.Sequence,
|
|
1655
|
+
collections.abc.Iterable,
|
|
1656
|
+
]:
|
|
1657
|
+
args = get_args(var_type)
|
|
1658
|
+
return args[0] if args else Any
|
|
1659
|
+
if origin_var_type is tuple:
|
|
1660
|
+
args = get_args(var_type)
|
|
1661
|
+
return (
|
|
1662
|
+
args[int(index) % len(args)]
|
|
1663
|
+
if args and index is not None
|
|
1664
|
+
else (unionize(*args) if args else Any)
|
|
1665
|
+
)
|
|
1666
|
+
return Any
|
|
1667
|
+
|
|
1668
|
+
|
|
1646
1669
|
@var_operation
|
|
1647
1670
|
def array_item_operation(array: ArrayVar, index: NumberVar | int):
|
|
1648
1671
|
"""Get an item from an array.
|
|
@@ -1654,12 +1677,14 @@ def array_item_operation(array: ArrayVar, index: NumberVar | int):
|
|
|
1654
1677
|
Returns:
|
|
1655
1678
|
The item from the array.
|
|
1656
1679
|
"""
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1680
|
+
element_type = _determine_value_of_array_index(
|
|
1681
|
+
array._var_type,
|
|
1682
|
+
(
|
|
1683
|
+
index
|
|
1684
|
+
if isinstance(index, int)
|
|
1685
|
+
else (index._var_value if isinstance(index, LiteralNumberVar) else None)
|
|
1686
|
+
),
|
|
1687
|
+
)
|
|
1663
1688
|
|
|
1664
1689
|
return var_operation_return(
|
|
1665
1690
|
js_expression=f"{array!s}.at({index!s})",
|
|
@@ -1683,7 +1708,7 @@ def array_range_operation(
|
|
|
1683
1708
|
"""
|
|
1684
1709
|
return var_operation_return(
|
|
1685
1710
|
js_expression=f"Array.from({{ length: Math.ceil(({stop!s} - {start!s}) / {step!s}) }}, (_, i) => {start!s} + i * {step!s})",
|
|
1686
|
-
var_type=
|
|
1711
|
+
var_type=list[int],
|
|
1687
1712
|
)
|
|
1688
1713
|
|
|
1689
1714
|
|
|
@@ -1749,7 +1774,7 @@ def repeat_array_operation(
|
|
|
1749
1774
|
def map_array_operation(
|
|
1750
1775
|
array: ArrayVar[ARRAY_VAR_TYPE],
|
|
1751
1776
|
function: FunctionVar,
|
|
1752
|
-
) -> CustomVarOperationReturn[
|
|
1777
|
+
) -> CustomVarOperationReturn[list[Any]]:
|
|
1753
1778
|
"""Map a function over an array.
|
|
1754
1779
|
|
|
1755
1780
|
Args:
|
|
@@ -1760,7 +1785,7 @@ def map_array_operation(
|
|
|
1760
1785
|
The mapped array.
|
|
1761
1786
|
"""
|
|
1762
1787
|
return var_operation_return(
|
|
1763
|
-
js_expression=f"{array}.map({function})", var_type=
|
|
1788
|
+
js_expression=f"{array}.map({function})", var_type=list[Any]
|
|
1764
1789
|
)
|
|
1765
1790
|
|
|
1766
1791
|
|