reflex 0.5.3a2__py3-none-any.whl → 0.5.4a1__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/apps/demo/code/webui/state.py +3 -2
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +19 -20
- reflex/.templates/web/utils/state.js +6 -0
- reflex/__init__.py +7 -1
- reflex/__init__.pyi +2 -0
- reflex/app.py +2 -5
- reflex/compiler/compiler.py +2 -2
- reflex/components/component.py +19 -6
- reflex/components/core/client_side_routing.py +2 -2
- reflex/components/core/client_side_routing.pyi +1 -0
- reflex/components/core/upload.py +1 -1
- reflex/components/datadisplay/dataeditor.py +7 -2
- reflex/components/datadisplay/dataeditor.pyi +1 -0
- reflex/components/el/elements/forms.py +18 -11
- reflex/components/el/elements/forms.pyi +1 -0
- reflex/components/markdown/markdown.py +1 -1
- reflex/components/plotly/plotly.py +76 -12
- reflex/components/plotly/plotly.pyi +15 -82
- reflex/components/radix/themes/base.py +9 -2
- reflex/components/radix/themes/base.pyi +1 -0
- reflex/components/recharts/cartesian.py +42 -14
- reflex/components/recharts/cartesian.pyi +81 -17
- reflex/components/recharts/charts.py +12 -21
- reflex/components/recharts/charts.pyi +53 -14
- reflex/components/sonner/toast.py +30 -14
- reflex/components/sonner/toast.pyi +8 -4
- reflex/config.py +22 -14
- reflex/constants/__init__.py +2 -0
- reflex/constants/config.py +7 -0
- reflex/event.py +12 -6
- reflex/experimental/__init__.py +22 -2
- reflex/experimental/client_state.py +81 -23
- reflex/experimental/hooks.py +29 -35
- reflex/experimental/layout.py +8 -3
- reflex/experimental/layout.pyi +536 -0
- reflex/reflex.py +9 -5
- reflex/style.py +1 -0
- reflex/testing.py +44 -13
- reflex/utils/format.py +8 -1
- reflex/utils/processes.py +27 -0
- reflex/utils/pyi_generator.py +11 -4
- reflex/utils/serializers.py +114 -15
- reflex/utils/types.py +6 -2
- reflex/vars.py +39 -10
- reflex/vars.pyi +2 -2
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/METADATA +1 -1
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/RECORD +50 -49
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/LICENSE +0 -0
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/WHEEL +0 -0
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/entry_points.txt +0 -0
reflex/utils/processes.py
CHANGED
|
@@ -109,6 +109,33 @@ def change_port(port: str, _type: str) -> str:
|
|
|
109
109
|
return new_port
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
def handle_port(service_name: str, port: str, default_port: str) -> str:
|
|
113
|
+
"""Change port if the specified port is in use and is not explicitly specified as a CLI arg or config arg.
|
|
114
|
+
otherwise tell the user the port is in use and exit the app.
|
|
115
|
+
|
|
116
|
+
We make an assumption that when port is the default port,then it hasnt been explicitly set since its not straightforward
|
|
117
|
+
to know whether a port was explicitly provided by the user unless its any other than the default.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
service_name: The frontend or backend.
|
|
121
|
+
port: The provided port.
|
|
122
|
+
default_port: The default port number associated with the specified service.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
The port to run the service on.
|
|
126
|
+
|
|
127
|
+
Raises:
|
|
128
|
+
Exit:when the port is in use.
|
|
129
|
+
"""
|
|
130
|
+
if is_process_on_port(port):
|
|
131
|
+
if int(port) == int(default_port):
|
|
132
|
+
return change_port(port, service_name)
|
|
133
|
+
else:
|
|
134
|
+
console.error(f"{service_name.capitalize()} port: {port} is already in use")
|
|
135
|
+
raise typer.Exit()
|
|
136
|
+
return port
|
|
137
|
+
|
|
138
|
+
|
|
112
139
|
def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
|
|
113
140
|
"""Wrapper over subprocess.Popen to unify the launch of child processes.
|
|
114
141
|
|
reflex/utils/pyi_generator.py
CHANGED
|
@@ -32,7 +32,7 @@ logger = logging.getLogger("pyi_generator")
|
|
|
32
32
|
PWD = Path(".").resolve()
|
|
33
33
|
|
|
34
34
|
EXCLUDED_FILES = [
|
|
35
|
-
|
|
35
|
+
"app.py",
|
|
36
36
|
"component.py",
|
|
37
37
|
"bare.py",
|
|
38
38
|
"foreach.py",
|
|
@@ -424,7 +424,7 @@ def _generate_component_create_functiondef(
|
|
|
424
424
|
),
|
|
425
425
|
ast.Constant(value=None),
|
|
426
426
|
)
|
|
427
|
-
for trigger in sorted(clz().get_event_triggers()
|
|
427
|
+
for trigger in sorted(clz().get_event_triggers())
|
|
428
428
|
)
|
|
429
429
|
logger.debug(f"Generated {clz.__name__}.create method with {len(kwargs)} kwargs")
|
|
430
430
|
create_args = ast.arguments(
|
|
@@ -488,7 +488,9 @@ def _generate_staticmethod_call_functiondef(
|
|
|
488
488
|
kwonlyargs=[],
|
|
489
489
|
kw_defaults=[],
|
|
490
490
|
kwarg=ast.arg(arg="props"),
|
|
491
|
-
defaults=[]
|
|
491
|
+
defaults=[ast.Constant(value=default) for default in fullspec.defaults]
|
|
492
|
+
if fullspec.defaults
|
|
493
|
+
else [],
|
|
492
494
|
)
|
|
493
495
|
definition = ast.FunctionDef(
|
|
494
496
|
name="__call__",
|
|
@@ -854,7 +856,11 @@ class PyiGenerator:
|
|
|
854
856
|
mode=black.mode.Mode(is_pyi=True),
|
|
855
857
|
).splitlines():
|
|
856
858
|
# Bit of a hack here, since the AST cannot represent comments.
|
|
857
|
-
if
|
|
859
|
+
if (
|
|
860
|
+
"def create(" in formatted_line
|
|
861
|
+
or "Figure" in formatted_line
|
|
862
|
+
or "Var[Template]" in formatted_line
|
|
863
|
+
):
|
|
858
864
|
pyi_content.append(formatted_line + " # type: ignore")
|
|
859
865
|
else:
|
|
860
866
|
pyi_content.append(formatted_line)
|
|
@@ -954,6 +960,7 @@ class PyiGenerator:
|
|
|
954
960
|
target_path.is_file()
|
|
955
961
|
and target_path.suffix == ".py"
|
|
956
962
|
and target_path.name not in EXCLUDED_FILES
|
|
963
|
+
and "reflex/components" in str(target_path)
|
|
957
964
|
):
|
|
958
965
|
file_targets.append(target_path)
|
|
959
966
|
continue
|
reflex/utils/serializers.py
CHANGED
|
@@ -2,13 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import functools
|
|
5
6
|
import json
|
|
6
7
|
import types as builtin_types
|
|
7
8
|
import warnings
|
|
8
9
|
from datetime import date, datetime, time, timedelta
|
|
9
10
|
from enum import Enum
|
|
10
11
|
from pathlib import Path
|
|
11
|
-
from typing import
|
|
12
|
+
from typing import (
|
|
13
|
+
Any,
|
|
14
|
+
Callable,
|
|
15
|
+
Dict,
|
|
16
|
+
List,
|
|
17
|
+
Literal,
|
|
18
|
+
Optional,
|
|
19
|
+
Set,
|
|
20
|
+
Tuple,
|
|
21
|
+
Type,
|
|
22
|
+
Union,
|
|
23
|
+
get_type_hints,
|
|
24
|
+
overload,
|
|
25
|
+
)
|
|
12
26
|
|
|
13
27
|
from reflex.base import Base
|
|
14
28
|
from reflex.constants.colors import Color, format_color
|
|
@@ -17,15 +31,24 @@ from reflex.utils import exceptions, types
|
|
|
17
31
|
# Mapping from type to a serializer.
|
|
18
32
|
# The serializer should convert the type to a JSON object.
|
|
19
33
|
SerializedType = Union[str, bool, int, float, list, dict]
|
|
34
|
+
|
|
35
|
+
|
|
20
36
|
Serializer = Callable[[Type], SerializedType]
|
|
37
|
+
|
|
38
|
+
|
|
21
39
|
SERIALIZERS: dict[Type, Serializer] = {}
|
|
40
|
+
SERIALIZER_TYPES: dict[Type, Type] = {}
|
|
22
41
|
|
|
23
42
|
|
|
24
|
-
def serializer(
|
|
43
|
+
def serializer(
|
|
44
|
+
fn: Serializer | None = None,
|
|
45
|
+
to: Type | None = None,
|
|
46
|
+
) -> Serializer:
|
|
25
47
|
"""Decorator to add a serializer for a given type.
|
|
26
48
|
|
|
27
49
|
Args:
|
|
28
50
|
fn: The function to decorate.
|
|
51
|
+
to: The type returned by the serializer. If this is `str`, then any Var created from this type will be treated as a string.
|
|
29
52
|
|
|
30
53
|
Returns:
|
|
31
54
|
The decorated function.
|
|
@@ -33,8 +56,9 @@ def serializer(fn: Serializer) -> Serializer:
|
|
|
33
56
|
Raises:
|
|
34
57
|
ValueError: If the function does not take a single argument.
|
|
35
58
|
"""
|
|
36
|
-
|
|
37
|
-
|
|
59
|
+
if fn is None:
|
|
60
|
+
# If the function is not provided, return a partial that acts as a decorator.
|
|
61
|
+
return functools.partial(serializer, to=to) # type: ignore
|
|
38
62
|
|
|
39
63
|
# Check the type hints to get the type of the argument.
|
|
40
64
|
type_hints = get_type_hints(fn)
|
|
@@ -54,18 +78,47 @@ def serializer(fn: Serializer) -> Serializer:
|
|
|
54
78
|
f"Serializer for type {type_} is already registered as {registered_fn.__qualname__}."
|
|
55
79
|
)
|
|
56
80
|
|
|
81
|
+
# Apply type transformation if requested
|
|
82
|
+
if to is not None:
|
|
83
|
+
SERIALIZER_TYPES[type_] = to
|
|
84
|
+
get_serializer_type.cache_clear()
|
|
85
|
+
|
|
57
86
|
# Register the serializer.
|
|
58
87
|
SERIALIZERS[type_] = fn
|
|
88
|
+
get_serializer.cache_clear()
|
|
59
89
|
|
|
60
90
|
# Return the function.
|
|
61
91
|
return fn
|
|
62
92
|
|
|
63
93
|
|
|
64
|
-
|
|
94
|
+
@overload
|
|
95
|
+
def serialize(
|
|
96
|
+
value: Any, get_type: Literal[True]
|
|
97
|
+
) -> Tuple[Optional[SerializedType], Optional[types.GenericType]]:
|
|
98
|
+
...
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@overload
|
|
102
|
+
def serialize(value: Any, get_type: Literal[False]) -> Optional[SerializedType]:
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@overload
|
|
107
|
+
def serialize(value: Any) -> Optional[SerializedType]:
|
|
108
|
+
...
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def serialize(
|
|
112
|
+
value: Any, get_type: bool = False
|
|
113
|
+
) -> Union[
|
|
114
|
+
Optional[SerializedType],
|
|
115
|
+
Tuple[Optional[SerializedType], Optional[types.GenericType]],
|
|
116
|
+
]:
|
|
65
117
|
"""Serialize the value to a JSON string.
|
|
66
118
|
|
|
67
119
|
Args:
|
|
68
120
|
value: The value to serialize.
|
|
121
|
+
get_type: Whether to return the type of the serialized value.
|
|
69
122
|
|
|
70
123
|
Returns:
|
|
71
124
|
The serialized value, or None if a serializer is not found.
|
|
@@ -75,13 +128,22 @@ def serialize(value: Any) -> SerializedType | None:
|
|
|
75
128
|
|
|
76
129
|
# If there is no serializer, return None.
|
|
77
130
|
if serializer is None:
|
|
131
|
+
if get_type:
|
|
132
|
+
return None, None
|
|
78
133
|
return None
|
|
79
134
|
|
|
80
135
|
# Serialize the value.
|
|
81
|
-
|
|
136
|
+
serialized = serializer(value)
|
|
82
137
|
|
|
138
|
+
# Return the serialized value and the type.
|
|
139
|
+
if get_type:
|
|
140
|
+
return serialized, get_serializer_type(type(value))
|
|
141
|
+
else:
|
|
142
|
+
return serialized
|
|
83
143
|
|
|
84
|
-
|
|
144
|
+
|
|
145
|
+
@functools.lru_cache
|
|
146
|
+
def get_serializer(type_: Type) -> Optional[Serializer]:
|
|
85
147
|
"""Get the serializer for the type.
|
|
86
148
|
|
|
87
149
|
Args:
|
|
@@ -90,8 +152,6 @@ def get_serializer(type_: Type) -> Serializer | None:
|
|
|
90
152
|
Returns:
|
|
91
153
|
The serializer for the type, or None if there is no serializer.
|
|
92
154
|
"""
|
|
93
|
-
global SERIALIZERS
|
|
94
|
-
|
|
95
155
|
# First, check if the type is registered.
|
|
96
156
|
serializer = SERIALIZERS.get(type_)
|
|
97
157
|
if serializer is not None:
|
|
@@ -106,6 +166,30 @@ def get_serializer(type_: Type) -> Serializer | None:
|
|
|
106
166
|
return None
|
|
107
167
|
|
|
108
168
|
|
|
169
|
+
@functools.lru_cache
|
|
170
|
+
def get_serializer_type(type_: Type) -> Optional[Type]:
|
|
171
|
+
"""Get the converted type for the type after serializing.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
type_: The type to get the serializer type for.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
The serialized type for the type, or None if there is no type conversion registered.
|
|
178
|
+
"""
|
|
179
|
+
# First, check if the type is registered.
|
|
180
|
+
serializer = SERIALIZER_TYPES.get(type_)
|
|
181
|
+
if serializer is not None:
|
|
182
|
+
return serializer
|
|
183
|
+
|
|
184
|
+
# If the type is not registered, check if it is a subclass of a registered type.
|
|
185
|
+
for registered_type, serializer in reversed(SERIALIZER_TYPES.items()):
|
|
186
|
+
if types._issubclass(type_, registered_type):
|
|
187
|
+
return serializer
|
|
188
|
+
|
|
189
|
+
# If there is no serializer, return None.
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
|
|
109
193
|
def has_serializer(type_: Type) -> bool:
|
|
110
194
|
"""Check if there is a serializer for the type.
|
|
111
195
|
|
|
@@ -118,7 +202,7 @@ def has_serializer(type_: Type) -> bool:
|
|
|
118
202
|
return get_serializer(type_) is not None
|
|
119
203
|
|
|
120
204
|
|
|
121
|
-
@serializer
|
|
205
|
+
@serializer(to=str)
|
|
122
206
|
def serialize_type(value: type) -> str:
|
|
123
207
|
"""Serialize a python type.
|
|
124
208
|
|
|
@@ -226,7 +310,7 @@ def serialize_dict(prop: Dict[str, Any]) -> str:
|
|
|
226
310
|
return format.unwrap_vars(fprop)
|
|
227
311
|
|
|
228
312
|
|
|
229
|
-
@serializer
|
|
313
|
+
@serializer(to=str)
|
|
230
314
|
def serialize_datetime(dt: Union[date, datetime, time, timedelta]) -> str:
|
|
231
315
|
"""Serialize a datetime to a JSON string.
|
|
232
316
|
|
|
@@ -239,8 +323,8 @@ def serialize_datetime(dt: Union[date, datetime, time, timedelta]) -> str:
|
|
|
239
323
|
return str(dt)
|
|
240
324
|
|
|
241
325
|
|
|
242
|
-
@serializer
|
|
243
|
-
def serialize_path(path: Path):
|
|
326
|
+
@serializer(to=str)
|
|
327
|
+
def serialize_path(path: Path) -> str:
|
|
244
328
|
"""Serialize a pathlib.Path to a JSON string.
|
|
245
329
|
|
|
246
330
|
Args:
|
|
@@ -265,7 +349,7 @@ def serialize_enum(en: Enum) -> str:
|
|
|
265
349
|
return en.value
|
|
266
350
|
|
|
267
351
|
|
|
268
|
-
@serializer
|
|
352
|
+
@serializer(to=str)
|
|
269
353
|
def serialize_color(color: Color) -> str:
|
|
270
354
|
"""Serialize a color.
|
|
271
355
|
|
|
@@ -314,7 +398,7 @@ except ImportError:
|
|
|
314
398
|
pass
|
|
315
399
|
|
|
316
400
|
try:
|
|
317
|
-
from plotly.graph_objects import Figure
|
|
401
|
+
from plotly.graph_objects import Figure, layout
|
|
318
402
|
from plotly.io import to_json
|
|
319
403
|
|
|
320
404
|
@serializer
|
|
@@ -329,6 +413,21 @@ try:
|
|
|
329
413
|
"""
|
|
330
414
|
return json.loads(str(to_json(figure)))
|
|
331
415
|
|
|
416
|
+
@serializer
|
|
417
|
+
def serialize_template(template: layout.Template) -> dict:
|
|
418
|
+
"""Serialize a plotly template.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
template: The template to serialize.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
The serialized template.
|
|
425
|
+
"""
|
|
426
|
+
return {
|
|
427
|
+
"data": json.loads(str(to_json(template.data))),
|
|
428
|
+
"layout": json.loads(str(to_json(template.layout))),
|
|
429
|
+
}
|
|
430
|
+
|
|
332
431
|
except ImportError:
|
|
333
432
|
pass
|
|
334
433
|
|
reflex/utils/types.py
CHANGED
|
@@ -215,7 +215,11 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
|
|
|
215
215
|
attr = getattr(cls, name, None)
|
|
216
216
|
if hint := get_property_hint(attr):
|
|
217
217
|
return hint
|
|
218
|
-
if
|
|
218
|
+
if (
|
|
219
|
+
hasattr(cls, "__fields__")
|
|
220
|
+
and name in cls.__fields__
|
|
221
|
+
and hasattr(cls.__fields__[name], "outer_type_")
|
|
222
|
+
):
|
|
219
223
|
# pydantic models
|
|
220
224
|
field = cls.__fields__[name]
|
|
221
225
|
type_ = field.outer_type_
|
|
@@ -505,7 +509,7 @@ def validate_parameter_literals(func):
|
|
|
505
509
|
annotations = {param[0]: param[1].annotation for param in func_params}
|
|
506
510
|
|
|
507
511
|
# validate args
|
|
508
|
-
for param, arg in zip(annotations
|
|
512
|
+
for param, arg in zip(annotations, args):
|
|
509
513
|
if annotations[param] is inspect.Parameter.empty:
|
|
510
514
|
continue
|
|
511
515
|
validate_literal(param, arg, annotations[param], func.__name__)
|
reflex/vars.py
CHANGED
|
@@ -347,7 +347,7 @@ class Var:
|
|
|
347
347
|
cls,
|
|
348
348
|
value: Any,
|
|
349
349
|
_var_is_local: bool = True,
|
|
350
|
-
_var_is_string: bool =
|
|
350
|
+
_var_is_string: bool | None = None,
|
|
351
351
|
_var_data: Optional[VarData] = None,
|
|
352
352
|
) -> Var | None:
|
|
353
353
|
"""Create a var from a value.
|
|
@@ -380,18 +380,39 @@ class Var:
|
|
|
380
380
|
|
|
381
381
|
# Try to serialize the value.
|
|
382
382
|
type_ = type(value)
|
|
383
|
-
|
|
383
|
+
if type_ in types.JSONType:
|
|
384
|
+
name = value
|
|
385
|
+
else:
|
|
386
|
+
name, serialized_type = serializers.serialize(value, get_type=True)
|
|
387
|
+
if (
|
|
388
|
+
serialized_type is not None
|
|
389
|
+
and _var_is_string is None
|
|
390
|
+
and issubclass(serialized_type, str)
|
|
391
|
+
):
|
|
392
|
+
_var_is_string = True
|
|
384
393
|
if name is None:
|
|
385
394
|
raise VarTypeError(
|
|
386
395
|
f"No JSON serializer found for var {value} of type {type_}."
|
|
387
396
|
)
|
|
388
397
|
name = name if isinstance(name, str) else format.json_dumps(name)
|
|
389
398
|
|
|
399
|
+
if _var_is_string is None and type_ is str:
|
|
400
|
+
console.deprecate(
|
|
401
|
+
feature_name="Creating a Var from a string without specifying _var_is_string",
|
|
402
|
+
reason=(
|
|
403
|
+
"Specify _var_is_string=False to create a Var that is not a string literal. "
|
|
404
|
+
"In the future, creating a Var from a string will be treated as a string literal "
|
|
405
|
+
"by default."
|
|
406
|
+
),
|
|
407
|
+
deprecation_version="0.5.4",
|
|
408
|
+
removal_version="0.6.0",
|
|
409
|
+
)
|
|
410
|
+
|
|
390
411
|
return BaseVar(
|
|
391
412
|
_var_name=name,
|
|
392
413
|
_var_type=type_,
|
|
393
414
|
_var_is_local=_var_is_local,
|
|
394
|
-
_var_is_string=_var_is_string,
|
|
415
|
+
_var_is_string=_var_is_string if _var_is_string is not None else False,
|
|
395
416
|
_var_data=_var_data,
|
|
396
417
|
)
|
|
397
418
|
|
|
@@ -400,7 +421,7 @@ class Var:
|
|
|
400
421
|
cls,
|
|
401
422
|
value: Any,
|
|
402
423
|
_var_is_local: bool = True,
|
|
403
|
-
_var_is_string: bool =
|
|
424
|
+
_var_is_string: bool | None = None,
|
|
404
425
|
_var_data: Optional[VarData] = None,
|
|
405
426
|
) -> Var:
|
|
406
427
|
"""Create a var from a value, asserting that it is not None.
|
|
@@ -531,6 +552,14 @@ class Var:
|
|
|
531
552
|
fn = "JSON.stringify" if json else "String"
|
|
532
553
|
return self.operation(fn=fn, type_=str)
|
|
533
554
|
|
|
555
|
+
def to_int(self) -> Var:
|
|
556
|
+
"""Convert a var to an int.
|
|
557
|
+
|
|
558
|
+
Returns:
|
|
559
|
+
The parseInt var.
|
|
560
|
+
"""
|
|
561
|
+
return self.operation(fn="parseInt", type_=int)
|
|
562
|
+
|
|
534
563
|
def __hash__(self) -> int:
|
|
535
564
|
"""Define a hash function for a var.
|
|
536
565
|
|
|
@@ -847,19 +876,19 @@ class Var:
|
|
|
847
876
|
if invoke_fn:
|
|
848
877
|
# invoke the function on left operand.
|
|
849
878
|
operation_name = (
|
|
850
|
-
f"{left_operand_full_name}.{fn}({right_operand_full_name})"
|
|
851
|
-
)
|
|
879
|
+
f"{left_operand_full_name}.{fn}({right_operand_full_name})" # type: ignore
|
|
880
|
+
)
|
|
852
881
|
else:
|
|
853
882
|
# pass the operands as arguments to the function.
|
|
854
883
|
operation_name = (
|
|
855
|
-
f"{left_operand_full_name} {op} {right_operand_full_name}"
|
|
856
|
-
)
|
|
884
|
+
f"{left_operand_full_name} {op} {right_operand_full_name}" # type: ignore
|
|
885
|
+
)
|
|
857
886
|
operation_name = f"{fn}({operation_name})"
|
|
858
887
|
else:
|
|
859
888
|
# apply operator to operands (left operand <operator> right_operand)
|
|
860
889
|
operation_name = (
|
|
861
|
-
f"{left_operand_full_name} {op} {right_operand_full_name}"
|
|
862
|
-
)
|
|
890
|
+
f"{left_operand_full_name} {op} {right_operand_full_name}" # type: ignore
|
|
891
|
+
)
|
|
863
892
|
operation_name = format.wrap(operation_name, "(")
|
|
864
893
|
else:
|
|
865
894
|
# apply operator to left operand (<operator> left_operand)
|
reflex/vars.pyi
CHANGED
|
@@ -51,11 +51,11 @@ class Var:
|
|
|
51
51
|
_var_data: VarData | None = None
|
|
52
52
|
@classmethod
|
|
53
53
|
def create(
|
|
54
|
-
cls, value: Any, _var_is_local: bool =
|
|
54
|
+
cls, value: Any, _var_is_local: bool = True, _var_is_string: bool | None = None, _var_data: VarData | None = None,
|
|
55
55
|
) -> Optional[Var]: ...
|
|
56
56
|
@classmethod
|
|
57
57
|
def create_safe(
|
|
58
|
-
cls, value: Any, _var_is_local: bool =
|
|
58
|
+
cls, value: Any, _var_is_local: bool = True, _var_is_string: bool | None = None, _var_data: VarData | None = None,
|
|
59
59
|
) -> Var: ...
|
|
60
60
|
@classmethod
|
|
61
61
|
def __class_getitem__(cls, type_: Type) -> _GenericAlias: ...
|