reflex 0.5.10a3__py3-none-any.whl → 0.6.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- reflex/.templates/jinja/web/pages/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/__init__.py +3 -2
- reflex/__init__.pyi +2 -2
- reflex/app.py +43 -9
- reflex/base.py +3 -2
- reflex/compiler/compiler.py +6 -6
- reflex/compiler/utils.py +5 -3
- reflex/components/base/app_wrap.py +2 -4
- reflex/components/base/app_wrap.pyi +17 -17
- reflex/components/base/bare.py +7 -4
- reflex/components/base/body.pyi +17 -17
- reflex/components/base/document.pyi +81 -81
- reflex/components/base/error_boundary.py +10 -8
- reflex/components/base/error_boundary.pyi +20 -19
- reflex/components/base/fragment.pyi +17 -17
- reflex/components/base/head.pyi +33 -33
- reflex/components/base/link.pyi +34 -33
- reflex/components/base/meta.pyi +65 -65
- reflex/components/base/script.py +2 -1
- reflex/components/base/script.pyi +21 -20
- reflex/components/component.py +116 -145
- reflex/components/core/banner.py +59 -60
- reflex/components/core/banner.pyi +86 -150
- reflex/components/core/client_side_routing.py +2 -1
- reflex/components/core/client_side_routing.pyi +34 -33
- reflex/components/core/clipboard.py +2 -2
- reflex/components/core/clipboard.pyi +19 -18
- reflex/components/core/cond.py +21 -44
- reflex/components/core/debounce.py +6 -8
- reflex/components/core/debounce.pyi +19 -18
- reflex/components/core/foreach.py +5 -14
- reflex/components/core/html.pyi +18 -17
- reflex/components/core/match.py +36 -43
- reflex/components/core/upload.py +32 -25
- reflex/components/core/upload.pyi +84 -73
- reflex/components/datadisplay/code.py +55 -28
- reflex/components/datadisplay/code.pyi +20 -17
- reflex/components/datadisplay/dataeditor.py +17 -11
- reflex/components/datadisplay/dataeditor.pyi +34 -33
- reflex/components/el/__init__.py +0 -1
- reflex/components/el/__init__.pyi +0 -11
- reflex/components/el/element.pyi +17 -17
- reflex/components/el/elements/__init__.py +1 -7
- reflex/components/el/elements/__init__.pyi +1 -15
- reflex/components/el/elements/base.pyi +18 -17
- reflex/components/el/elements/forms.py +24 -31
- reflex/components/el/elements/forms.pyi +237 -236
- reflex/components/el/elements/inline.pyi +450 -449
- reflex/components/el/elements/media.py +0 -21
- reflex/components/el/elements/media.pyi +338 -337
- reflex/components/el/elements/metadata.py +3 -2
- reflex/components/el/elements/metadata.pyi +98 -97
- reflex/components/el/elements/other.pyi +114 -113
- reflex/components/el/elements/scripts.pyi +50 -49
- reflex/components/el/elements/sectioning.pyi +242 -241
- reflex/components/el/elements/tables.pyi +162 -161
- reflex/components/el/elements/typography.pyi +242 -241
- reflex/components/gridjs/datatable.py +13 -14
- reflex/components/gridjs/datatable.pyi +34 -33
- reflex/components/lucide/icon.py +2 -126
- reflex/components/lucide/icon.pyi +34 -142
- reflex/components/markdown/markdown.py +30 -35
- reflex/components/markdown/markdown.pyi +29 -32
- reflex/components/moment/moment.pyi +19 -18
- reflex/components/next/base.pyi +17 -17
- reflex/components/next/image.py +0 -4
- reflex/components/next/image.pyi +20 -19
- reflex/components/next/link.pyi +18 -17
- reflex/components/next/video.pyi +18 -17
- reflex/components/plotly/plotly.py +16 -28
- reflex/components/plotly/plotly.pyi +36 -35
- reflex/components/props.py +21 -10
- reflex/components/radix/__init__.pyi +1 -1
- reflex/components/radix/primitives/__init__.pyi +0 -1
- reflex/components/radix/primitives/accordion.py +7 -8
- reflex/components/radix/primitives/accordion.pyi +117 -116
- reflex/components/radix/primitives/base.pyi +34 -33
- reflex/components/radix/primitives/drawer.pyi +169 -168
- reflex/components/radix/primitives/form.pyi +168 -167
- reflex/components/radix/primitives/progress.pyi +82 -81
- reflex/components/radix/primitives/slider.pyi +84 -83
- reflex/components/radix/themes/base.py +8 -4
- reflex/components/radix/themes/base.pyi +114 -113
- reflex/components/radix/themes/color_mode.py +12 -21
- reflex/components/radix/themes/color_mode.pyi +67 -67
- reflex/components/radix/themes/components/__init__.pyi +1 -0
- reflex/components/radix/themes/components/alert_dialog.pyi +118 -117
- reflex/components/radix/themes/components/aspect_ratio.pyi +18 -17
- reflex/components/radix/themes/components/avatar.pyi +18 -17
- reflex/components/radix/themes/components/badge.pyi +18 -17
- reflex/components/radix/themes/components/button.pyi +18 -17
- reflex/components/radix/themes/components/callout.pyi +82 -81
- reflex/components/radix/themes/components/card.pyi +18 -17
- reflex/components/radix/themes/components/checkbox.py +2 -3
- reflex/components/radix/themes/components/checkbox.pyi +53 -52
- reflex/components/radix/themes/components/checkbox_cards.pyi +34 -33
- reflex/components/radix/themes/components/checkbox_group.pyi +34 -33
- reflex/components/radix/themes/components/context_menu.pyi +140 -139
- reflex/components/radix/themes/components/data_list.py +5 -0
- reflex/components/radix/themes/components/data_list.pyi +71 -65
- reflex/components/radix/themes/components/dialog.pyi +121 -120
- reflex/components/radix/themes/components/dropdown_menu.pyi +142 -141
- reflex/components/radix/themes/components/hover_card.pyi +68 -67
- reflex/components/radix/themes/components/icon_button.py +2 -1
- reflex/components/radix/themes/components/icon_button.pyi +18 -17
- reflex/components/radix/themes/components/inset.pyi +18 -17
- reflex/components/radix/themes/components/popover.pyi +73 -72
- reflex/components/radix/themes/components/progress.pyi +18 -17
- reflex/components/radix/themes/components/radio.pyi +18 -17
- reflex/components/radix/themes/components/radio_cards.pyi +35 -34
- reflex/components/radix/themes/components/radio_group.py +35 -31
- reflex/components/radix/themes/components/radio_group.pyi +73 -66
- reflex/components/radix/themes/components/scroll_area.pyi +18 -17
- reflex/components/radix/themes/components/segmented_control.pyi +35 -34
- reflex/components/radix/themes/components/select.py +2 -1
- reflex/components/radix/themes/components/select.pyi +155 -154
- reflex/components/radix/themes/components/separator.py +2 -3
- reflex/components/radix/themes/components/separator.pyi +18 -17
- reflex/components/radix/themes/components/skeleton.pyi +18 -17
- reflex/components/radix/themes/components/slider.py +2 -1
- reflex/components/radix/themes/components/slider.pyi +20 -19
- reflex/components/radix/themes/components/spinner.pyi +18 -17
- reflex/components/radix/themes/components/switch.pyi +19 -18
- reflex/components/radix/themes/components/table.pyi +114 -113
- reflex/components/radix/themes/components/tabs.pyi +84 -83
- reflex/components/radix/themes/components/text_area.pyi +21 -20
- reflex/components/radix/themes/components/text_field.py +0 -79
- reflex/components/radix/themes/components/text_field.pyi +57 -63
- reflex/components/radix/themes/components/tooltip.pyi +21 -20
- reflex/components/radix/themes/layout/base.pyi +18 -17
- reflex/components/radix/themes/layout/box.pyi +18 -17
- reflex/components/radix/themes/layout/center.pyi +18 -17
- reflex/components/radix/themes/layout/container.py +2 -3
- reflex/components/radix/themes/layout/container.pyi +18 -17
- reflex/components/radix/themes/layout/flex.pyi +18 -17
- reflex/components/radix/themes/layout/grid.pyi +18 -17
- reflex/components/radix/themes/layout/list.py +5 -4
- reflex/components/radix/themes/layout/list.pyi +86 -85
- reflex/components/radix/themes/layout/section.py +2 -3
- reflex/components/radix/themes/layout/section.pyi +18 -17
- reflex/components/radix/themes/layout/spacer.pyi +18 -17
- reflex/components/radix/themes/layout/stack.pyi +50 -49
- reflex/components/radix/themes/typography/blockquote.pyi +18 -17
- reflex/components/radix/themes/typography/code.pyi +18 -17
- reflex/components/radix/themes/typography/heading.pyi +18 -17
- reflex/components/radix/themes/typography/link.pyi +18 -17
- reflex/components/radix/themes/typography/text.pyi +114 -113
- reflex/components/react_player/audio.pyi +34 -33
- reflex/components/react_player/react_player.pyi +34 -33
- reflex/components/react_player/video.pyi +34 -33
- reflex/components/recharts/cartesian.py +23 -19
- reflex/components/recharts/cartesian.pyi +297 -296
- reflex/components/recharts/charts.py +6 -5
- reflex/components/recharts/charts.pyi +179 -178
- reflex/components/recharts/general.py +8 -7
- reflex/components/recharts/general.pyi +82 -81
- reflex/components/recharts/polar.py +14 -13
- reflex/components/recharts/polar.pyi +76 -75
- reflex/components/recharts/recharts.pyi +33 -33
- reflex/components/sonner/toast.py +30 -33
- reflex/components/sonner/toast.pyi +27 -25
- reflex/components/suneditor/editor.py +2 -1
- reflex/components/suneditor/editor.pyi +27 -26
- reflex/components/tags/iter_tag.py +16 -16
- reflex/components/tags/tag.py +8 -10
- reflex/constants/base.py +3 -1
- reflex/constants/event.py +1 -0
- reflex/event.py +89 -79
- reflex/experimental/__init__.py +25 -6
- reflex/experimental/client_state.py +34 -58
- reflex/experimental/hooks.py +13 -18
- reflex/experimental/layout.py +5 -5
- reflex/experimental/layout.pyi +84 -83
- reflex/{experimental/vars → ivars}/__init__.py +0 -1
- reflex/ivars/base.py +2180 -0
- reflex/ivars/function.py +200 -0
- reflex/ivars/number.py +1137 -0
- reflex/ivars/object.py +564 -0
- reflex/ivars/sequence.py +1601 -0
- reflex/model.py +22 -0
- reflex/reflex.py +4 -0
- reflex/state.py +388 -73
- reflex/style.py +52 -34
- reflex/testing.py +8 -3
- reflex/utils/exceptions.py +12 -0
- reflex/utils/exec.py +0 -14
- reflex/utils/format.py +74 -223
- reflex/utils/net.py +43 -0
- reflex/utils/path_ops.py +13 -1
- reflex/utils/prerequisites.py +46 -26
- reflex/utils/pyi_generator.py +5 -4
- reflex/utils/serializers.py +13 -31
- reflex/utils/types.py +44 -9
- reflex/vars.py +127 -2230
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/METADATA +4 -6
- reflex-0.6.0a1.dist-info/RECORD +384 -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/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.pyi +0 -218
- reflex-0.5.10a3.dist-info/RECORD +0 -413
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/LICENSE +0 -0
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/WHEEL +0 -0
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/entry_points.txt +0 -0
reflex/ivars/number.py
ADDED
|
@@ -0,0 +1,1137 @@
|
|
|
1
|
+
"""Immutable number vars."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import dataclasses
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from typing import (
|
|
9
|
+
TYPE_CHECKING,
|
|
10
|
+
Any,
|
|
11
|
+
Callable,
|
|
12
|
+
ClassVar,
|
|
13
|
+
NoReturn,
|
|
14
|
+
Type,
|
|
15
|
+
TypeVar,
|
|
16
|
+
Union,
|
|
17
|
+
overload,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from reflex.utils.exceptions import VarTypeError
|
|
21
|
+
from reflex.vars import Var, VarData
|
|
22
|
+
|
|
23
|
+
from .base import (
|
|
24
|
+
CustomVarOperationReturn,
|
|
25
|
+
ImmutableVar,
|
|
26
|
+
LiteralNoneVar,
|
|
27
|
+
LiteralVar,
|
|
28
|
+
ToOperation,
|
|
29
|
+
unionize,
|
|
30
|
+
var_operation,
|
|
31
|
+
var_operation_return,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
NUMBER_T = TypeVar("NUMBER_T", int, float, Union[int, float], bool)
|
|
35
|
+
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from .sequence import ArrayVar
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def raise_unsupported_operand_types(
|
|
41
|
+
operator: str, operands_types: tuple[type, ...]
|
|
42
|
+
) -> NoReturn:
|
|
43
|
+
"""Raise an unsupported operand types error.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
operator: The operator.
|
|
47
|
+
operands_types: The types of the operands.
|
|
48
|
+
|
|
49
|
+
Raises:
|
|
50
|
+
VarTypeError: The operand types are unsupported.
|
|
51
|
+
"""
|
|
52
|
+
raise VarTypeError(
|
|
53
|
+
f"Unsupported Operand type(s) for {operator}: {', '.join(map(lambda t: t.__name__, operands_types))}"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class NumberVar(ImmutableVar[NUMBER_T]):
|
|
58
|
+
"""Base class for immutable number vars."""
|
|
59
|
+
|
|
60
|
+
@overload
|
|
61
|
+
def __add__(self, other: number_types) -> NumberVar: ...
|
|
62
|
+
|
|
63
|
+
@overload
|
|
64
|
+
def __add__(self, other: NoReturn) -> NoReturn: ...
|
|
65
|
+
|
|
66
|
+
def __add__(self, other: Any):
|
|
67
|
+
"""Add two numbers.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
other: The other number.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
The number addition operation.
|
|
74
|
+
"""
|
|
75
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
76
|
+
raise_unsupported_operand_types("+", (type(self), type(other)))
|
|
77
|
+
return number_add_operation(self, +other)
|
|
78
|
+
|
|
79
|
+
@overload
|
|
80
|
+
def __radd__(self, other: number_types) -> NumberVar: ...
|
|
81
|
+
|
|
82
|
+
@overload
|
|
83
|
+
def __radd__(self, other: NoReturn) -> NoReturn: ...
|
|
84
|
+
|
|
85
|
+
def __radd__(self, other: Any):
|
|
86
|
+
"""Add two numbers.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
other: The other number.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
The number addition operation.
|
|
93
|
+
"""
|
|
94
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
95
|
+
raise_unsupported_operand_types("+", (type(other), type(self)))
|
|
96
|
+
return number_add_operation(+other, self)
|
|
97
|
+
|
|
98
|
+
@overload
|
|
99
|
+
def __sub__(self, other: number_types) -> NumberVar: ...
|
|
100
|
+
|
|
101
|
+
@overload
|
|
102
|
+
def __sub__(self, other: NoReturn) -> NoReturn: ...
|
|
103
|
+
|
|
104
|
+
def __sub__(self, other: Any):
|
|
105
|
+
"""Subtract two numbers.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
other: The other number.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
The number subtraction operation.
|
|
112
|
+
"""
|
|
113
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
114
|
+
raise_unsupported_operand_types("-", (type(self), type(other)))
|
|
115
|
+
|
|
116
|
+
return number_subtract_operation(self, +other)
|
|
117
|
+
|
|
118
|
+
@overload
|
|
119
|
+
def __rsub__(self, other: number_types) -> NumberVar: ...
|
|
120
|
+
|
|
121
|
+
@overload
|
|
122
|
+
def __rsub__(self, other: NoReturn) -> NoReturn: ...
|
|
123
|
+
|
|
124
|
+
def __rsub__(self, other: Any):
|
|
125
|
+
"""Subtract two numbers.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
other: The other number.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
The number subtraction operation.
|
|
132
|
+
"""
|
|
133
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
134
|
+
raise_unsupported_operand_types("-", (type(other), type(self)))
|
|
135
|
+
|
|
136
|
+
return number_subtract_operation(+other, self)
|
|
137
|
+
|
|
138
|
+
def __abs__(self):
|
|
139
|
+
"""Get the absolute value of the number.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
The number absolute operation.
|
|
143
|
+
"""
|
|
144
|
+
return number_abs_operation(self)
|
|
145
|
+
|
|
146
|
+
@overload
|
|
147
|
+
def __mul__(self, other: number_types | boolean_types) -> NumberVar: ...
|
|
148
|
+
|
|
149
|
+
@overload
|
|
150
|
+
def __mul__(self, other: list | tuple | set | ArrayVar) -> ArrayVar: ...
|
|
151
|
+
|
|
152
|
+
def __mul__(self, other: Any):
|
|
153
|
+
"""Multiply two numbers.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
other: The other number.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
The number multiplication operation.
|
|
160
|
+
"""
|
|
161
|
+
from .sequence import ArrayVar, LiteralArrayVar
|
|
162
|
+
|
|
163
|
+
if isinstance(other, (list, tuple, set, ArrayVar)):
|
|
164
|
+
if isinstance(other, ArrayVar):
|
|
165
|
+
return other * self
|
|
166
|
+
return LiteralArrayVar.create(other) * self
|
|
167
|
+
|
|
168
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
169
|
+
raise_unsupported_operand_types("*", (type(self), type(other)))
|
|
170
|
+
|
|
171
|
+
return number_multiply_operation(self, +other)
|
|
172
|
+
|
|
173
|
+
@overload
|
|
174
|
+
def __rmul__(self, other: number_types | boolean_types) -> NumberVar: ...
|
|
175
|
+
|
|
176
|
+
@overload
|
|
177
|
+
def __rmul__(self, other: list | tuple | set | ArrayVar) -> ArrayVar: ...
|
|
178
|
+
|
|
179
|
+
def __rmul__(self, other: Any):
|
|
180
|
+
"""Multiply two numbers.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
other: The other number.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
The number multiplication operation.
|
|
187
|
+
"""
|
|
188
|
+
from .sequence import ArrayVar, LiteralArrayVar
|
|
189
|
+
|
|
190
|
+
if isinstance(other, (list, tuple, set, ArrayVar)):
|
|
191
|
+
if isinstance(other, ArrayVar):
|
|
192
|
+
return other * self
|
|
193
|
+
return LiteralArrayVar.create(other) * self
|
|
194
|
+
|
|
195
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
196
|
+
raise_unsupported_operand_types("*", (type(other), type(self)))
|
|
197
|
+
|
|
198
|
+
return number_multiply_operation(+other, self)
|
|
199
|
+
|
|
200
|
+
@overload
|
|
201
|
+
def __truediv__(self, other: number_types) -> NumberVar: ...
|
|
202
|
+
|
|
203
|
+
@overload
|
|
204
|
+
def __truediv__(self, other: NoReturn) -> NoReturn: ...
|
|
205
|
+
|
|
206
|
+
def __truediv__(self, other: Any):
|
|
207
|
+
"""Divide two numbers.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
other: The other number.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
The number true division operation.
|
|
214
|
+
"""
|
|
215
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
216
|
+
raise_unsupported_operand_types("/", (type(self), type(other)))
|
|
217
|
+
|
|
218
|
+
return number_true_division_operation(self, +other)
|
|
219
|
+
|
|
220
|
+
@overload
|
|
221
|
+
def __rtruediv__(self, other: number_types) -> NumberVar: ...
|
|
222
|
+
|
|
223
|
+
@overload
|
|
224
|
+
def __rtruediv__(self, other: NoReturn) -> NoReturn: ...
|
|
225
|
+
|
|
226
|
+
def __rtruediv__(self, other: Any):
|
|
227
|
+
"""Divide two numbers.
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
other: The other number.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
The number true division operation.
|
|
234
|
+
"""
|
|
235
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
236
|
+
raise_unsupported_operand_types("/", (type(other), type(self)))
|
|
237
|
+
|
|
238
|
+
return number_true_division_operation(+other, self)
|
|
239
|
+
|
|
240
|
+
@overload
|
|
241
|
+
def __floordiv__(self, other: number_types) -> NumberVar: ...
|
|
242
|
+
|
|
243
|
+
@overload
|
|
244
|
+
def __floordiv__(self, other: NoReturn) -> NoReturn: ...
|
|
245
|
+
|
|
246
|
+
def __floordiv__(self, other: Any):
|
|
247
|
+
"""Floor divide two numbers.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
other: The other number.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
The number floor division operation.
|
|
254
|
+
"""
|
|
255
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
256
|
+
raise_unsupported_operand_types("//", (type(self), type(other)))
|
|
257
|
+
|
|
258
|
+
return number_floor_division_operation(self, +other)
|
|
259
|
+
|
|
260
|
+
@overload
|
|
261
|
+
def __rfloordiv__(self, other: number_types) -> NumberVar: ...
|
|
262
|
+
|
|
263
|
+
@overload
|
|
264
|
+
def __rfloordiv__(self, other: NoReturn) -> NoReturn: ...
|
|
265
|
+
|
|
266
|
+
def __rfloordiv__(self, other: Any):
|
|
267
|
+
"""Floor divide two numbers.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
other: The other number.
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
The number floor division operation.
|
|
274
|
+
"""
|
|
275
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
276
|
+
raise_unsupported_operand_types("//", (type(other), type(self)))
|
|
277
|
+
|
|
278
|
+
return number_floor_division_operation(+other, self)
|
|
279
|
+
|
|
280
|
+
@overload
|
|
281
|
+
def __mod__(self, other: number_types) -> NumberVar: ...
|
|
282
|
+
|
|
283
|
+
@overload
|
|
284
|
+
def __mod__(self, other: NoReturn) -> NoReturn: ...
|
|
285
|
+
|
|
286
|
+
def __mod__(self, other: Any):
|
|
287
|
+
"""Modulo two numbers.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
other: The other number.
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
The number modulo operation.
|
|
294
|
+
"""
|
|
295
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
296
|
+
raise_unsupported_operand_types("%", (type(self), type(other)))
|
|
297
|
+
|
|
298
|
+
return number_modulo_operation(self, +other)
|
|
299
|
+
|
|
300
|
+
@overload
|
|
301
|
+
def __rmod__(self, other: number_types) -> NumberVar: ...
|
|
302
|
+
|
|
303
|
+
@overload
|
|
304
|
+
def __rmod__(self, other: NoReturn) -> NoReturn: ...
|
|
305
|
+
|
|
306
|
+
def __rmod__(self, other: Any):
|
|
307
|
+
"""Modulo two numbers.
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
other: The other number.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
The number modulo operation.
|
|
314
|
+
"""
|
|
315
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
316
|
+
raise_unsupported_operand_types("%", (type(other), type(self)))
|
|
317
|
+
|
|
318
|
+
return number_modulo_operation(+other, self)
|
|
319
|
+
|
|
320
|
+
@overload
|
|
321
|
+
def __pow__(self, other: number_types) -> NumberVar: ...
|
|
322
|
+
|
|
323
|
+
@overload
|
|
324
|
+
def __pow__(self, other: NoReturn) -> NoReturn: ...
|
|
325
|
+
|
|
326
|
+
def __pow__(self, other: Any):
|
|
327
|
+
"""Exponentiate two numbers.
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
other: The other number.
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
The number exponent operation.
|
|
334
|
+
"""
|
|
335
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
336
|
+
raise_unsupported_operand_types("**", (type(self), type(other)))
|
|
337
|
+
|
|
338
|
+
return number_exponent_operation(self, +other)
|
|
339
|
+
|
|
340
|
+
@overload
|
|
341
|
+
def __rpow__(self, other: number_types) -> NumberVar: ...
|
|
342
|
+
|
|
343
|
+
@overload
|
|
344
|
+
def __rpow__(self, other: NoReturn) -> NoReturn: ...
|
|
345
|
+
|
|
346
|
+
def __rpow__(self, other: Any):
|
|
347
|
+
"""Exponentiate two numbers.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
other: The other number.
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
The number exponent operation.
|
|
354
|
+
"""
|
|
355
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
356
|
+
raise_unsupported_operand_types("**", (type(other), type(self)))
|
|
357
|
+
|
|
358
|
+
return number_exponent_operation(+other, self)
|
|
359
|
+
|
|
360
|
+
def __neg__(self):
|
|
361
|
+
"""Negate the number.
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
The number negation operation.
|
|
365
|
+
"""
|
|
366
|
+
return number_negate_operation(self)
|
|
367
|
+
|
|
368
|
+
def __invert__(self):
|
|
369
|
+
"""Boolean NOT the number.
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
The boolean NOT operation.
|
|
373
|
+
"""
|
|
374
|
+
return boolean_not_operation(self.bool())
|
|
375
|
+
|
|
376
|
+
def __pos__(self) -> NumberVar:
|
|
377
|
+
"""Positive the number.
|
|
378
|
+
|
|
379
|
+
Returns:
|
|
380
|
+
The number.
|
|
381
|
+
"""
|
|
382
|
+
return self
|
|
383
|
+
|
|
384
|
+
def __round__(self):
|
|
385
|
+
"""Round the number.
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
The number round operation.
|
|
389
|
+
"""
|
|
390
|
+
return number_round_operation(self)
|
|
391
|
+
|
|
392
|
+
def __ceil__(self):
|
|
393
|
+
"""Ceil the number.
|
|
394
|
+
|
|
395
|
+
Returns:
|
|
396
|
+
The number ceil operation.
|
|
397
|
+
"""
|
|
398
|
+
return number_ceil_operation(self)
|
|
399
|
+
|
|
400
|
+
def __floor__(self):
|
|
401
|
+
"""Floor the number.
|
|
402
|
+
|
|
403
|
+
Returns:
|
|
404
|
+
The number floor operation.
|
|
405
|
+
"""
|
|
406
|
+
return number_floor_operation(self)
|
|
407
|
+
|
|
408
|
+
def __trunc__(self):
|
|
409
|
+
"""Trunc the number.
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
The number trunc operation.
|
|
413
|
+
"""
|
|
414
|
+
return number_trunc_operation(self)
|
|
415
|
+
|
|
416
|
+
@overload
|
|
417
|
+
def __lt__(self, other: number_types) -> BooleanVar: ...
|
|
418
|
+
|
|
419
|
+
@overload
|
|
420
|
+
def __lt__(self, other: NoReturn) -> NoReturn: ...
|
|
421
|
+
|
|
422
|
+
def __lt__(self, other: Any):
|
|
423
|
+
"""Less than comparison.
|
|
424
|
+
|
|
425
|
+
Args:
|
|
426
|
+
other: The other number.
|
|
427
|
+
|
|
428
|
+
Returns:
|
|
429
|
+
The result of the comparison.
|
|
430
|
+
"""
|
|
431
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
432
|
+
raise_unsupported_operand_types("<", (type(self), type(other)))
|
|
433
|
+
return less_than_operation(self, +other)
|
|
434
|
+
|
|
435
|
+
@overload
|
|
436
|
+
def __le__(self, other: number_types) -> BooleanVar: ...
|
|
437
|
+
|
|
438
|
+
@overload
|
|
439
|
+
def __le__(self, other: NoReturn) -> NoReturn: ...
|
|
440
|
+
|
|
441
|
+
def __le__(self, other: Any):
|
|
442
|
+
"""Less than or equal comparison.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
other: The other number.
|
|
446
|
+
|
|
447
|
+
Returns:
|
|
448
|
+
The result of the comparison.
|
|
449
|
+
"""
|
|
450
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
451
|
+
raise_unsupported_operand_types("<=", (type(self), type(other)))
|
|
452
|
+
return less_than_or_equal_operation(self, +other)
|
|
453
|
+
|
|
454
|
+
def __eq__(self, other: Any):
|
|
455
|
+
"""Equal comparison.
|
|
456
|
+
|
|
457
|
+
Args:
|
|
458
|
+
other: The other number.
|
|
459
|
+
|
|
460
|
+
Returns:
|
|
461
|
+
The result of the comparison.
|
|
462
|
+
"""
|
|
463
|
+
if isinstance(other, NUMBER_TYPES):
|
|
464
|
+
return equal_operation(self, +other)
|
|
465
|
+
return equal_operation(self, other)
|
|
466
|
+
|
|
467
|
+
def __ne__(self, other: Any):
|
|
468
|
+
"""Not equal comparison.
|
|
469
|
+
|
|
470
|
+
Args:
|
|
471
|
+
other: The other number.
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
The result of the comparison.
|
|
475
|
+
"""
|
|
476
|
+
if isinstance(other, NUMBER_TYPES):
|
|
477
|
+
return not_equal_operation(self, +other)
|
|
478
|
+
return not_equal_operation(self, other)
|
|
479
|
+
|
|
480
|
+
@overload
|
|
481
|
+
def __gt__(self, other: number_types) -> BooleanVar: ...
|
|
482
|
+
|
|
483
|
+
@overload
|
|
484
|
+
def __gt__(self, other: NoReturn) -> NoReturn: ...
|
|
485
|
+
|
|
486
|
+
def __gt__(self, other: Any):
|
|
487
|
+
"""Greater than comparison.
|
|
488
|
+
|
|
489
|
+
Args:
|
|
490
|
+
other: The other number.
|
|
491
|
+
|
|
492
|
+
Returns:
|
|
493
|
+
The result of the comparison.
|
|
494
|
+
"""
|
|
495
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
496
|
+
raise_unsupported_operand_types(">", (type(self), type(other)))
|
|
497
|
+
return greater_than_operation(self, +other)
|
|
498
|
+
|
|
499
|
+
@overload
|
|
500
|
+
def __ge__(self, other: number_types) -> BooleanVar: ...
|
|
501
|
+
|
|
502
|
+
@overload
|
|
503
|
+
def __ge__(self, other: NoReturn) -> NoReturn: ...
|
|
504
|
+
|
|
505
|
+
def __ge__(self, other: Any):
|
|
506
|
+
"""Greater than or equal comparison.
|
|
507
|
+
|
|
508
|
+
Args:
|
|
509
|
+
other: The other number.
|
|
510
|
+
|
|
511
|
+
Returns:
|
|
512
|
+
The result of the comparison.
|
|
513
|
+
"""
|
|
514
|
+
if not isinstance(other, NUMBER_TYPES):
|
|
515
|
+
raise_unsupported_operand_types(">=", (type(self), type(other)))
|
|
516
|
+
return greater_than_or_equal_operation(self, +other)
|
|
517
|
+
|
|
518
|
+
def bool(self):
|
|
519
|
+
"""Boolean conversion.
|
|
520
|
+
|
|
521
|
+
Returns:
|
|
522
|
+
The boolean value of the number.
|
|
523
|
+
"""
|
|
524
|
+
return self != 0
|
|
525
|
+
|
|
526
|
+
def _is_strict_float(self) -> bool:
|
|
527
|
+
"""Check if the number is a float.
|
|
528
|
+
|
|
529
|
+
Returns:
|
|
530
|
+
bool: True if the number is a float.
|
|
531
|
+
"""
|
|
532
|
+
return issubclass(self._var_type, float)
|
|
533
|
+
|
|
534
|
+
def _is_strict_int(self) -> bool:
|
|
535
|
+
"""Check if the number is an int.
|
|
536
|
+
|
|
537
|
+
Returns:
|
|
538
|
+
bool: True if the number is an int.
|
|
539
|
+
"""
|
|
540
|
+
return issubclass(self._var_type, int)
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
def binary_number_operation(
|
|
544
|
+
func: Callable[[NumberVar, NumberVar], str],
|
|
545
|
+
) -> Callable[[number_types, number_types], NumberVar]:
|
|
546
|
+
"""Decorator to create a binary number operation.
|
|
547
|
+
|
|
548
|
+
Args:
|
|
549
|
+
func: The binary number operation function.
|
|
550
|
+
|
|
551
|
+
Returns:
|
|
552
|
+
The binary number operation.
|
|
553
|
+
"""
|
|
554
|
+
|
|
555
|
+
@var_operation
|
|
556
|
+
def operation(lhs: NumberVar, rhs: NumberVar):
|
|
557
|
+
return var_operation_return(
|
|
558
|
+
js_expression=func(lhs, rhs),
|
|
559
|
+
var_type=unionize(lhs._var_type, rhs._var_type),
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
def wrapper(lhs: number_types, rhs: number_types) -> NumberVar:
|
|
563
|
+
"""Create the binary number operation.
|
|
564
|
+
|
|
565
|
+
Args:
|
|
566
|
+
lhs: The first number.
|
|
567
|
+
rhs: The second number.
|
|
568
|
+
|
|
569
|
+
Returns:
|
|
570
|
+
The binary number operation.
|
|
571
|
+
"""
|
|
572
|
+
return operation(lhs, rhs) # type: ignore
|
|
573
|
+
|
|
574
|
+
return wrapper
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
@binary_number_operation
|
|
578
|
+
def number_add_operation(lhs: NumberVar, rhs: NumberVar):
|
|
579
|
+
"""Add two numbers.
|
|
580
|
+
|
|
581
|
+
Args:
|
|
582
|
+
lhs: The first number.
|
|
583
|
+
rhs: The second number.
|
|
584
|
+
|
|
585
|
+
Returns:
|
|
586
|
+
The number addition operation.
|
|
587
|
+
"""
|
|
588
|
+
return f"({lhs} + {rhs})"
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
@binary_number_operation
|
|
592
|
+
def number_subtract_operation(lhs: NumberVar, rhs: NumberVar):
|
|
593
|
+
"""Subtract two numbers.
|
|
594
|
+
|
|
595
|
+
Args:
|
|
596
|
+
lhs: The first number.
|
|
597
|
+
rhs: The second number.
|
|
598
|
+
|
|
599
|
+
Returns:
|
|
600
|
+
The number subtraction operation.
|
|
601
|
+
"""
|
|
602
|
+
return f"({lhs} - {rhs})"
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
@var_operation
|
|
606
|
+
def number_abs_operation(value: NumberVar):
|
|
607
|
+
"""Get the absolute value of the number.
|
|
608
|
+
|
|
609
|
+
Args:
|
|
610
|
+
value: The number.
|
|
611
|
+
|
|
612
|
+
Returns:
|
|
613
|
+
The number absolute operation.
|
|
614
|
+
"""
|
|
615
|
+
return var_operation_return(
|
|
616
|
+
js_expression=f"Math.abs({value})", var_type=value._var_type
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
@binary_number_operation
|
|
621
|
+
def number_multiply_operation(lhs: NumberVar, rhs: NumberVar):
|
|
622
|
+
"""Multiply two numbers.
|
|
623
|
+
|
|
624
|
+
Args:
|
|
625
|
+
lhs: The first number.
|
|
626
|
+
rhs: The second number.
|
|
627
|
+
|
|
628
|
+
Returns:
|
|
629
|
+
The number multiplication operation.
|
|
630
|
+
"""
|
|
631
|
+
return f"({lhs} * {rhs})"
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
@var_operation
|
|
635
|
+
def number_negate_operation(
|
|
636
|
+
value: NumberVar[NUMBER_T],
|
|
637
|
+
) -> CustomVarOperationReturn[NUMBER_T]:
|
|
638
|
+
"""Negate the number.
|
|
639
|
+
|
|
640
|
+
Args:
|
|
641
|
+
value: The number.
|
|
642
|
+
|
|
643
|
+
Returns:
|
|
644
|
+
The number negation operation.
|
|
645
|
+
"""
|
|
646
|
+
return var_operation_return(js_expression=f"-({value})", var_type=value._var_type)
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
@binary_number_operation
|
|
650
|
+
def number_true_division_operation(lhs: NumberVar, rhs: NumberVar):
|
|
651
|
+
"""Divide two numbers.
|
|
652
|
+
|
|
653
|
+
Args:
|
|
654
|
+
lhs: The first number.
|
|
655
|
+
rhs: The second number.
|
|
656
|
+
|
|
657
|
+
Returns:
|
|
658
|
+
The number true division operation.
|
|
659
|
+
"""
|
|
660
|
+
return f"({lhs} / {rhs})"
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
@binary_number_operation
|
|
664
|
+
def number_floor_division_operation(lhs: NumberVar, rhs: NumberVar):
|
|
665
|
+
"""Floor divide two numbers.
|
|
666
|
+
|
|
667
|
+
Args:
|
|
668
|
+
lhs: The first number.
|
|
669
|
+
rhs: The second number.
|
|
670
|
+
|
|
671
|
+
Returns:
|
|
672
|
+
The number floor division operation.
|
|
673
|
+
"""
|
|
674
|
+
return f"Math.floor({lhs} / {rhs})"
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
@binary_number_operation
|
|
678
|
+
def number_modulo_operation(lhs: NumberVar, rhs: NumberVar):
|
|
679
|
+
"""Modulo two numbers.
|
|
680
|
+
|
|
681
|
+
Args:
|
|
682
|
+
lhs: The first number.
|
|
683
|
+
rhs: The second number.
|
|
684
|
+
|
|
685
|
+
Returns:
|
|
686
|
+
The number modulo operation.
|
|
687
|
+
"""
|
|
688
|
+
return f"({lhs} % {rhs})"
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
@binary_number_operation
|
|
692
|
+
def number_exponent_operation(lhs: NumberVar, rhs: NumberVar):
|
|
693
|
+
"""Exponentiate two numbers.
|
|
694
|
+
|
|
695
|
+
Args:
|
|
696
|
+
lhs: The first number.
|
|
697
|
+
rhs: The second number.
|
|
698
|
+
|
|
699
|
+
Returns:
|
|
700
|
+
The number exponent operation.
|
|
701
|
+
"""
|
|
702
|
+
return f"({lhs} ** {rhs})"
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
@var_operation
|
|
706
|
+
def number_round_operation(value: NumberVar):
|
|
707
|
+
"""Round the number.
|
|
708
|
+
|
|
709
|
+
Args:
|
|
710
|
+
value: The number.
|
|
711
|
+
|
|
712
|
+
Returns:
|
|
713
|
+
The number round operation.
|
|
714
|
+
"""
|
|
715
|
+
return var_operation_return(js_expression=f"Math.round({value})", var_type=int)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
@var_operation
|
|
719
|
+
def number_ceil_operation(value: NumberVar):
|
|
720
|
+
"""Ceil the number.
|
|
721
|
+
|
|
722
|
+
Args:
|
|
723
|
+
value: The number.
|
|
724
|
+
|
|
725
|
+
Returns:
|
|
726
|
+
The number ceil operation.
|
|
727
|
+
"""
|
|
728
|
+
return var_operation_return(js_expression=f"Math.ceil({value})", var_type=int)
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
@var_operation
|
|
732
|
+
def number_floor_operation(value: NumberVar):
|
|
733
|
+
"""Floor the number.
|
|
734
|
+
|
|
735
|
+
Args:
|
|
736
|
+
value: The number.
|
|
737
|
+
|
|
738
|
+
Returns:
|
|
739
|
+
The number floor operation.
|
|
740
|
+
"""
|
|
741
|
+
return var_operation_return(js_expression=f"Math.floor({value})", var_type=int)
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
@var_operation
|
|
745
|
+
def number_trunc_operation(value: NumberVar):
|
|
746
|
+
"""Trunc the number.
|
|
747
|
+
|
|
748
|
+
Args:
|
|
749
|
+
value: The number.
|
|
750
|
+
|
|
751
|
+
Returns:
|
|
752
|
+
The number trunc operation.
|
|
753
|
+
"""
|
|
754
|
+
return var_operation_return(js_expression=f"Math.trunc({value})", var_type=int)
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
class BooleanVar(NumberVar[bool]):
|
|
758
|
+
"""Base class for immutable boolean vars."""
|
|
759
|
+
|
|
760
|
+
def __invert__(self):
|
|
761
|
+
"""NOT the boolean.
|
|
762
|
+
|
|
763
|
+
Returns:
|
|
764
|
+
The boolean NOT operation.
|
|
765
|
+
"""
|
|
766
|
+
return boolean_not_operation(self)
|
|
767
|
+
|
|
768
|
+
def __int__(self):
|
|
769
|
+
"""Convert the boolean to an int.
|
|
770
|
+
|
|
771
|
+
Returns:
|
|
772
|
+
The boolean to int operation.
|
|
773
|
+
"""
|
|
774
|
+
return boolean_to_number_operation(self)
|
|
775
|
+
|
|
776
|
+
def __pos__(self):
|
|
777
|
+
"""Convert the boolean to an int.
|
|
778
|
+
|
|
779
|
+
Returns:
|
|
780
|
+
The boolean to int operation.
|
|
781
|
+
"""
|
|
782
|
+
return boolean_to_number_operation(self)
|
|
783
|
+
|
|
784
|
+
def bool(self) -> BooleanVar:
|
|
785
|
+
"""Boolean conversion.
|
|
786
|
+
|
|
787
|
+
Returns:
|
|
788
|
+
The boolean value of the boolean.
|
|
789
|
+
"""
|
|
790
|
+
return self
|
|
791
|
+
|
|
792
|
+
def __lt__(self, other: Any):
|
|
793
|
+
"""Less than comparison.
|
|
794
|
+
|
|
795
|
+
Args:
|
|
796
|
+
other: The other boolean.
|
|
797
|
+
|
|
798
|
+
Returns:
|
|
799
|
+
The result of the comparison.
|
|
800
|
+
"""
|
|
801
|
+
return +self < other
|
|
802
|
+
|
|
803
|
+
def __le__(self, other: Any):
|
|
804
|
+
"""Less than or equal comparison.
|
|
805
|
+
|
|
806
|
+
Args:
|
|
807
|
+
other: The other boolean.
|
|
808
|
+
|
|
809
|
+
Returns:
|
|
810
|
+
The result of the comparison.
|
|
811
|
+
"""
|
|
812
|
+
return +self <= other
|
|
813
|
+
|
|
814
|
+
def __gt__(self, other: Any):
|
|
815
|
+
"""Greater than comparison.
|
|
816
|
+
|
|
817
|
+
Args:
|
|
818
|
+
other: The other boolean.
|
|
819
|
+
|
|
820
|
+
Returns:
|
|
821
|
+
The result of the comparison.
|
|
822
|
+
"""
|
|
823
|
+
return +self > other
|
|
824
|
+
|
|
825
|
+
def __ge__(self, other: Any):
|
|
826
|
+
"""Greater than or equal comparison.
|
|
827
|
+
|
|
828
|
+
Args:
|
|
829
|
+
other: The other boolean.
|
|
830
|
+
|
|
831
|
+
Returns:
|
|
832
|
+
The result of the comparison.
|
|
833
|
+
"""
|
|
834
|
+
return +self >= other
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
@var_operation
|
|
838
|
+
def boolean_to_number_operation(value: BooleanVar):
|
|
839
|
+
"""Convert the boolean to a number.
|
|
840
|
+
|
|
841
|
+
Args:
|
|
842
|
+
value: The boolean.
|
|
843
|
+
|
|
844
|
+
Returns:
|
|
845
|
+
The boolean to number operation.
|
|
846
|
+
"""
|
|
847
|
+
return var_operation_return(js_expression=f"Number({value})", var_type=int)
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
def comparison_operator(
|
|
851
|
+
func: Callable[[ImmutableVar, ImmutableVar], str],
|
|
852
|
+
) -> Callable[[ImmutableVar | Any, ImmutableVar | Any], BooleanVar]:
|
|
853
|
+
"""Decorator to create a comparison operation.
|
|
854
|
+
|
|
855
|
+
Args:
|
|
856
|
+
func: The comparison operation function.
|
|
857
|
+
|
|
858
|
+
Returns:
|
|
859
|
+
The comparison operation.
|
|
860
|
+
"""
|
|
861
|
+
|
|
862
|
+
@var_operation
|
|
863
|
+
def operation(lhs: ImmutableVar, rhs: ImmutableVar):
|
|
864
|
+
return var_operation_return(
|
|
865
|
+
js_expression=func(lhs, rhs),
|
|
866
|
+
var_type=bool,
|
|
867
|
+
)
|
|
868
|
+
|
|
869
|
+
def wrapper(lhs: ImmutableVar | Any, rhs: ImmutableVar | Any) -> BooleanVar:
|
|
870
|
+
"""Create the comparison operation.
|
|
871
|
+
|
|
872
|
+
Args:
|
|
873
|
+
lhs: The first value.
|
|
874
|
+
rhs: The second value.
|
|
875
|
+
|
|
876
|
+
Returns:
|
|
877
|
+
The comparison operation.
|
|
878
|
+
"""
|
|
879
|
+
return operation(lhs, rhs)
|
|
880
|
+
|
|
881
|
+
return wrapper
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
@comparison_operator
|
|
885
|
+
def greater_than_operation(lhs: ImmutableVar, rhs: ImmutableVar):
|
|
886
|
+
"""Greater than comparison.
|
|
887
|
+
|
|
888
|
+
Args:
|
|
889
|
+
lhs: The first value.
|
|
890
|
+
rhs: The second value.
|
|
891
|
+
|
|
892
|
+
Returns:
|
|
893
|
+
The result of the comparison.
|
|
894
|
+
"""
|
|
895
|
+
return f"({lhs} > {rhs})"
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
@comparison_operator
|
|
899
|
+
def greater_than_or_equal_operation(lhs: ImmutableVar, rhs: ImmutableVar):
|
|
900
|
+
"""Greater than or equal comparison.
|
|
901
|
+
|
|
902
|
+
Args:
|
|
903
|
+
lhs: The first value.
|
|
904
|
+
rhs: The second value.
|
|
905
|
+
|
|
906
|
+
Returns:
|
|
907
|
+
The result of the comparison.
|
|
908
|
+
"""
|
|
909
|
+
return f"({lhs} >= {rhs})"
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
@comparison_operator
|
|
913
|
+
def less_than_operation(lhs: ImmutableVar, rhs: ImmutableVar):
|
|
914
|
+
"""Less than comparison.
|
|
915
|
+
|
|
916
|
+
Args:
|
|
917
|
+
lhs: The first value.
|
|
918
|
+
rhs: The second value.
|
|
919
|
+
|
|
920
|
+
Returns:
|
|
921
|
+
The result of the comparison.
|
|
922
|
+
"""
|
|
923
|
+
return f"({lhs} < {rhs})"
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
@comparison_operator
|
|
927
|
+
def less_than_or_equal_operation(lhs: ImmutableVar, rhs: ImmutableVar):
|
|
928
|
+
"""Less than or equal comparison.
|
|
929
|
+
|
|
930
|
+
Args:
|
|
931
|
+
lhs: The first value.
|
|
932
|
+
rhs: The second value.
|
|
933
|
+
|
|
934
|
+
Returns:
|
|
935
|
+
The result of the comparison.
|
|
936
|
+
"""
|
|
937
|
+
return f"({lhs} <= {rhs})"
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
@comparison_operator
|
|
941
|
+
def equal_operation(lhs: ImmutableVar, rhs: ImmutableVar):
|
|
942
|
+
"""Equal comparison.
|
|
943
|
+
|
|
944
|
+
Args:
|
|
945
|
+
lhs: The first value.
|
|
946
|
+
rhs: The second value.
|
|
947
|
+
|
|
948
|
+
Returns:
|
|
949
|
+
The result of the comparison.
|
|
950
|
+
"""
|
|
951
|
+
return f"({lhs} === {rhs})"
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
@comparison_operator
|
|
955
|
+
def not_equal_operation(lhs: ImmutableVar, rhs: ImmutableVar):
|
|
956
|
+
"""Not equal comparison.
|
|
957
|
+
|
|
958
|
+
Args:
|
|
959
|
+
lhs: The first value.
|
|
960
|
+
rhs: The second value.
|
|
961
|
+
|
|
962
|
+
Returns:
|
|
963
|
+
The result of the comparison.
|
|
964
|
+
"""
|
|
965
|
+
return f"({lhs} !== {rhs})"
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
@var_operation
|
|
969
|
+
def boolean_not_operation(value: BooleanVar):
|
|
970
|
+
"""Boolean NOT the boolean.
|
|
971
|
+
|
|
972
|
+
Args:
|
|
973
|
+
value: The boolean.
|
|
974
|
+
|
|
975
|
+
Returns:
|
|
976
|
+
The boolean NOT operation.
|
|
977
|
+
"""
|
|
978
|
+
return var_operation_return(js_expression=f"!({value})", var_type=bool)
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
@dataclasses.dataclass(
|
|
982
|
+
eq=False,
|
|
983
|
+
frozen=True,
|
|
984
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
985
|
+
)
|
|
986
|
+
class LiteralBooleanVar(LiteralVar, BooleanVar):
|
|
987
|
+
"""Base class for immutable literal boolean vars."""
|
|
988
|
+
|
|
989
|
+
_var_value: bool = dataclasses.field(default=False)
|
|
990
|
+
|
|
991
|
+
def json(self) -> str:
|
|
992
|
+
"""Get the JSON representation of the var.
|
|
993
|
+
|
|
994
|
+
Returns:
|
|
995
|
+
The JSON representation of the var.
|
|
996
|
+
"""
|
|
997
|
+
return "true" if self._var_value else "false"
|
|
998
|
+
|
|
999
|
+
def __hash__(self) -> int:
|
|
1000
|
+
"""Calculate the hash value of the object.
|
|
1001
|
+
|
|
1002
|
+
Returns:
|
|
1003
|
+
int: The hash value of the object.
|
|
1004
|
+
"""
|
|
1005
|
+
return hash((self.__class__.__name__, self._var_value))
|
|
1006
|
+
|
|
1007
|
+
@classmethod
|
|
1008
|
+
def create(cls, value: bool, _var_data: VarData | None = None):
|
|
1009
|
+
"""Create the boolean var.
|
|
1010
|
+
|
|
1011
|
+
Args:
|
|
1012
|
+
value: The value of the var.
|
|
1013
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
1014
|
+
|
|
1015
|
+
Returns:
|
|
1016
|
+
The boolean var.
|
|
1017
|
+
"""
|
|
1018
|
+
return cls(
|
|
1019
|
+
_var_name="true" if value else "false",
|
|
1020
|
+
_var_type=bool,
|
|
1021
|
+
_var_data=_var_data,
|
|
1022
|
+
_var_value=value,
|
|
1023
|
+
)
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
@dataclasses.dataclass(
|
|
1027
|
+
eq=False,
|
|
1028
|
+
frozen=True,
|
|
1029
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
1030
|
+
)
|
|
1031
|
+
class LiteralNumberVar(LiteralVar, NumberVar):
|
|
1032
|
+
"""Base class for immutable literal number vars."""
|
|
1033
|
+
|
|
1034
|
+
_var_value: float | int = dataclasses.field(default=0)
|
|
1035
|
+
|
|
1036
|
+
def json(self) -> str:
|
|
1037
|
+
"""Get the JSON representation of the var.
|
|
1038
|
+
|
|
1039
|
+
Returns:
|
|
1040
|
+
The JSON representation of the var.
|
|
1041
|
+
"""
|
|
1042
|
+
return json.dumps(self._var_value)
|
|
1043
|
+
|
|
1044
|
+
def __hash__(self) -> int:
|
|
1045
|
+
"""Calculate the hash value of the object.
|
|
1046
|
+
|
|
1047
|
+
Returns:
|
|
1048
|
+
int: The hash value of the object.
|
|
1049
|
+
"""
|
|
1050
|
+
return hash((self.__class__.__name__, self._var_value))
|
|
1051
|
+
|
|
1052
|
+
@classmethod
|
|
1053
|
+
def create(cls, value: float | int, _var_data: VarData | None = None):
|
|
1054
|
+
"""Create the number var.
|
|
1055
|
+
|
|
1056
|
+
Args:
|
|
1057
|
+
value: The value of the var.
|
|
1058
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
1059
|
+
|
|
1060
|
+
Returns:
|
|
1061
|
+
The number var.
|
|
1062
|
+
"""
|
|
1063
|
+
return cls(
|
|
1064
|
+
_var_name=str(value),
|
|
1065
|
+
_var_type=type(value),
|
|
1066
|
+
_var_data=_var_data,
|
|
1067
|
+
_var_value=value,
|
|
1068
|
+
)
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
number_types = Union[NumberVar, int, float]
|
|
1072
|
+
boolean_types = Union[BooleanVar, bool]
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
@dataclasses.dataclass(
|
|
1076
|
+
eq=False,
|
|
1077
|
+
frozen=True,
|
|
1078
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
1079
|
+
)
|
|
1080
|
+
class ToNumberVarOperation(ToOperation, NumberVar):
|
|
1081
|
+
"""Base class for immutable number vars that are the result of a number operation."""
|
|
1082
|
+
|
|
1083
|
+
_original: Var = dataclasses.field(default_factory=lambda: LiteralNoneVar.create())
|
|
1084
|
+
|
|
1085
|
+
_default_var_type: ClassVar[Type] = float
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
@dataclasses.dataclass(
|
|
1089
|
+
eq=False,
|
|
1090
|
+
frozen=True,
|
|
1091
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
1092
|
+
)
|
|
1093
|
+
class ToBooleanVarOperation(ToOperation, BooleanVar):
|
|
1094
|
+
"""Base class for immutable boolean vars that are the result of a boolean operation."""
|
|
1095
|
+
|
|
1096
|
+
_original: Var = dataclasses.field(default_factory=lambda: LiteralNoneVar.create())
|
|
1097
|
+
|
|
1098
|
+
_default_var_type: ClassVar[Type] = bool
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
@var_operation
|
|
1102
|
+
def boolify(value: Var):
|
|
1103
|
+
"""Convert the value to a boolean.
|
|
1104
|
+
|
|
1105
|
+
Args:
|
|
1106
|
+
value: The value.
|
|
1107
|
+
|
|
1108
|
+
Returns:
|
|
1109
|
+
The boolean value.
|
|
1110
|
+
"""
|
|
1111
|
+
return var_operation_return(
|
|
1112
|
+
js_expression=f"Boolean({value})",
|
|
1113
|
+
var_type=bool,
|
|
1114
|
+
)
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
@var_operation
|
|
1118
|
+
def ternary_operation(
|
|
1119
|
+
condition: BooleanVar, if_true: ImmutableVar, if_false: ImmutableVar
|
|
1120
|
+
):
|
|
1121
|
+
"""Create a ternary operation.
|
|
1122
|
+
|
|
1123
|
+
Args:
|
|
1124
|
+
condition: The condition.
|
|
1125
|
+
if_true: The value if the condition is true.
|
|
1126
|
+
if_false: The value if the condition is false.
|
|
1127
|
+
|
|
1128
|
+
Returns:
|
|
1129
|
+
The ternary operation.
|
|
1130
|
+
"""
|
|
1131
|
+
return var_operation_return(
|
|
1132
|
+
js_expression=f"({condition} ? {if_true} : {if_false})",
|
|
1133
|
+
var_type=unionize(if_true._var_type, if_false._var_type),
|
|
1134
|
+
)
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
NUMBER_TYPES = (int, float, NumberVar)
|