reflex 0.6.5a3__py3-none-any.whl → 0.6.6a1__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/web/utils/state.js +15 -1
- reflex/__init__.py +3 -1
- reflex/__init__.pyi +3 -0
- reflex/app.py +4 -2
- reflex/assets.py +95 -0
- reflex/base.py +2 -2
- reflex/components/base/error_boundary.py +99 -36
- reflex/components/base/error_boundary.pyi +3 -4
- reflex/components/component.py +29 -7
- reflex/components/core/cond.py +8 -0
- reflex/components/datadisplay/code.py +1 -1
- reflex/components/datadisplay/logo.py +26 -13
- reflex/components/el/__init__.pyi +2 -0
- reflex/components/el/elements/__init__.py +1 -0
- reflex/components/el/elements/__init__.pyi +3 -0
- reflex/components/el/elements/forms.py +1 -0
- reflex/components/el/elements/forms.pyi +1 -0
- reflex/components/moment/moment.py +4 -3
- reflex/components/moment/moment.pyi +12 -2
- reflex/components/radix/primitives/drawer.py +5 -23
- reflex/components/radix/themes/base.py +3 -0
- reflex/components/radix/themes/components/segmented_control.py +3 -1
- reflex/components/radix/themes/components/segmented_control.pyi +7 -2
- reflex/components/radix/themes/components/text_field.py +3 -0
- reflex/components/radix/themes/components/text_field.pyi +4 -0
- reflex/components/sonner/toast.py +23 -12
- reflex/components/sonner/toast.pyi +6 -6
- reflex/config.py +60 -9
- reflex/constants/base.py +12 -0
- reflex/constants/installer.py +3 -3
- reflex/constants/style.py +1 -1
- reflex/event.py +22 -5
- reflex/experimental/assets.py +14 -36
- reflex/reflex.py +15 -34
- reflex/state.py +81 -23
- reflex/utils/exceptions.py +4 -0
- reflex/utils/prerequisites.py +174 -40
- reflex/utils/redir.py +13 -4
- reflex/utils/serializers.py +52 -1
- reflex/utils/telemetry.py +2 -1
- reflex/utils/types.py +52 -1
- reflex/vars/base.py +18 -4
- reflex/vars/function.py +283 -37
- {reflex-0.6.5a3.dist-info → reflex-0.6.6a1.dist-info}/METADATA +3 -2
- {reflex-0.6.5a3.dist-info → reflex-0.6.6a1.dist-info}/RECORD +48 -47
- {reflex-0.6.5a3.dist-info → reflex-0.6.6a1.dist-info}/LICENSE +0 -0
- {reflex-0.6.5a3.dist-info → reflex-0.6.6a1.dist-info}/WHEEL +0 -0
- {reflex-0.6.5a3.dist-info → reflex-0.6.6a1.dist-info}/entry_points.txt +0 -0
reflex/utils/redir.py
CHANGED
|
@@ -10,6 +10,18 @@ from .. import constants
|
|
|
10
10
|
from . import console
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
def open_browser(target_url: str) -> None:
|
|
14
|
+
"""Open a browser window to target_url.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
target_url: The URL to open in the browser.
|
|
18
|
+
"""
|
|
19
|
+
if not webbrowser.open(target_url):
|
|
20
|
+
console.warn(
|
|
21
|
+
f"Unable to automatically open the browser. Please navigate to {target_url} in your browser."
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
13
25
|
def open_browser_and_wait(
|
|
14
26
|
target_url: str, poll_url: str, interval: int = 2
|
|
15
27
|
) -> httpx.Response:
|
|
@@ -23,10 +35,7 @@ def open_browser_and_wait(
|
|
|
23
35
|
Returns:
|
|
24
36
|
The response from the poll_url.
|
|
25
37
|
"""
|
|
26
|
-
|
|
27
|
-
console.warn(
|
|
28
|
-
f"Unable to automatically open the browser. Please navigate to {target_url} in your browser."
|
|
29
|
-
)
|
|
38
|
+
open_browser(target_url)
|
|
30
39
|
console.info("[b]Complete the workflow in the browser to continue.[/b]")
|
|
31
40
|
while True:
|
|
32
41
|
try:
|
reflex/utils/serializers.py
CHANGED
|
@@ -263,7 +263,58 @@ def serialize_base(value: Base) -> dict:
|
|
|
263
263
|
Returns:
|
|
264
264
|
The serialized Base.
|
|
265
265
|
"""
|
|
266
|
-
|
|
266
|
+
from reflex.vars.base import Var
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
k: v for k, v in value.dict().items() if isinstance(v, Var) or not callable(v)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
try:
|
|
274
|
+
from pydantic.v1 import BaseModel as BaseModelV1
|
|
275
|
+
|
|
276
|
+
@serializer(to=dict)
|
|
277
|
+
def serialize_base_model_v1(model: BaseModelV1) -> dict:
|
|
278
|
+
"""Serialize a pydantic v1 BaseModel instance.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
model: The BaseModel to serialize.
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
The serialized BaseModel.
|
|
285
|
+
"""
|
|
286
|
+
return model.dict()
|
|
287
|
+
|
|
288
|
+
from pydantic import BaseModel as BaseModelV2
|
|
289
|
+
|
|
290
|
+
if BaseModelV1 is not BaseModelV2:
|
|
291
|
+
|
|
292
|
+
@serializer(to=dict)
|
|
293
|
+
def serialize_base_model_v2(model: BaseModelV2) -> dict:
|
|
294
|
+
"""Serialize a pydantic v2 BaseModel instance.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
model: The BaseModel to serialize.
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
The serialized BaseModel.
|
|
301
|
+
"""
|
|
302
|
+
return model.model_dump()
|
|
303
|
+
except ImportError:
|
|
304
|
+
# Older pydantic v1 import
|
|
305
|
+
from pydantic import BaseModel as BaseModelV1
|
|
306
|
+
|
|
307
|
+
@serializer(to=dict)
|
|
308
|
+
def serialize_base_model_v1(model: BaseModelV1) -> dict:
|
|
309
|
+
"""Serialize a pydantic v1 BaseModel instance.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
model: The BaseModel to serialize.
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
The serialized BaseModel.
|
|
316
|
+
"""
|
|
317
|
+
return model.dict()
|
|
267
318
|
|
|
268
319
|
|
|
269
320
|
@serializer
|
reflex/utils/telemetry.py
CHANGED
|
@@ -51,7 +51,8 @@ def get_python_version() -> str:
|
|
|
51
51
|
Returns:
|
|
52
52
|
The Python version.
|
|
53
53
|
"""
|
|
54
|
-
|
|
54
|
+
# Remove the "+" from the version string in case user is using a pre-release version.
|
|
55
|
+
return platform.python_version().rstrip("+")
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
def get_reflex_version() -> str:
|
reflex/utils/types.py
CHANGED
|
@@ -14,9 +14,11 @@ from typing import (
|
|
|
14
14
|
Callable,
|
|
15
15
|
ClassVar,
|
|
16
16
|
Dict,
|
|
17
|
+
FrozenSet,
|
|
17
18
|
Iterable,
|
|
18
19
|
List,
|
|
19
20
|
Literal,
|
|
21
|
+
Mapping,
|
|
20
22
|
Optional,
|
|
21
23
|
Sequence,
|
|
22
24
|
Tuple,
|
|
@@ -29,6 +31,7 @@ from typing import (
|
|
|
29
31
|
from typing import get_origin as get_origin_og
|
|
30
32
|
|
|
31
33
|
import sqlalchemy
|
|
34
|
+
from typing_extensions import is_typeddict
|
|
32
35
|
|
|
33
36
|
import reflex
|
|
34
37
|
from reflex.components.core.breakpoints import Breakpoints
|
|
@@ -494,6 +497,14 @@ def _issubclass(cls: GenericType, cls_check: GenericType, instance: Any = None)
|
|
|
494
497
|
if isinstance(instance, Breakpoints):
|
|
495
498
|
return _breakpoints_satisfies_typing(cls_check, instance)
|
|
496
499
|
|
|
500
|
+
if isinstance(cls_check_base, tuple):
|
|
501
|
+
cls_check_base = tuple(
|
|
502
|
+
cls_check_one if not is_typeddict(cls_check_one) else dict
|
|
503
|
+
for cls_check_one in cls_check_base
|
|
504
|
+
)
|
|
505
|
+
if is_typeddict(cls_check_base):
|
|
506
|
+
cls_check_base = dict
|
|
507
|
+
|
|
497
508
|
# Check if the types match.
|
|
498
509
|
try:
|
|
499
510
|
return cls_check_base == Any or issubclass(cls_base, cls_check_base)
|
|
@@ -503,6 +514,36 @@ def _issubclass(cls: GenericType, cls_check: GenericType, instance: Any = None)
|
|
|
503
514
|
raise TypeError(f"Invalid type for issubclass: {cls_base}") from te
|
|
504
515
|
|
|
505
516
|
|
|
517
|
+
def does_obj_satisfy_typed_dict(obj: Any, cls: GenericType) -> bool:
|
|
518
|
+
"""Check if an object satisfies a typed dict.
|
|
519
|
+
|
|
520
|
+
Args:
|
|
521
|
+
obj: The object to check.
|
|
522
|
+
cls: The typed dict to check against.
|
|
523
|
+
|
|
524
|
+
Returns:
|
|
525
|
+
Whether the object satisfies the typed dict.
|
|
526
|
+
"""
|
|
527
|
+
if not isinstance(obj, Mapping):
|
|
528
|
+
return False
|
|
529
|
+
|
|
530
|
+
key_names_to_values = get_type_hints(cls)
|
|
531
|
+
required_keys: FrozenSet[str] = getattr(cls, "__required_keys__", frozenset())
|
|
532
|
+
|
|
533
|
+
if not all(
|
|
534
|
+
isinstance(key, str)
|
|
535
|
+
and key in key_names_to_values
|
|
536
|
+
and _isinstance(value, key_names_to_values[key])
|
|
537
|
+
for key, value in obj.items()
|
|
538
|
+
):
|
|
539
|
+
return False
|
|
540
|
+
|
|
541
|
+
# TODO in 3.14: Implement https://peps.python.org/pep-0728/ if it's approved
|
|
542
|
+
|
|
543
|
+
# required keys are all present
|
|
544
|
+
return required_keys.issubset(required_keys)
|
|
545
|
+
|
|
546
|
+
|
|
506
547
|
def _isinstance(obj: Any, cls: GenericType, nested: bool = False) -> bool:
|
|
507
548
|
"""Check if an object is an instance of a class.
|
|
508
549
|
|
|
@@ -529,6 +570,16 @@ def _isinstance(obj: Any, cls: GenericType, nested: bool = False) -> bool:
|
|
|
529
570
|
origin = get_origin(cls)
|
|
530
571
|
|
|
531
572
|
if origin is None:
|
|
573
|
+
# cls is a typed dict
|
|
574
|
+
if is_typeddict(cls):
|
|
575
|
+
if nested:
|
|
576
|
+
return does_obj_satisfy_typed_dict(obj, cls)
|
|
577
|
+
return isinstance(obj, dict)
|
|
578
|
+
|
|
579
|
+
# cls is a float
|
|
580
|
+
if cls is float:
|
|
581
|
+
return isinstance(obj, (float, int))
|
|
582
|
+
|
|
532
583
|
# cls is a simple class
|
|
533
584
|
return isinstance(obj, cls)
|
|
534
585
|
|
|
@@ -553,7 +604,7 @@ def _isinstance(obj: Any, cls: GenericType, nested: bool = False) -> bool:
|
|
|
553
604
|
and len(obj) == len(args)
|
|
554
605
|
and all(_isinstance(item, arg) for item, arg in zip(obj, args))
|
|
555
606
|
)
|
|
556
|
-
if origin
|
|
607
|
+
if origin in (dict, Breakpoints):
|
|
557
608
|
return isinstance(obj, dict) and all(
|
|
558
609
|
_isinstance(key, args[0]) and _isinstance(value, args[1])
|
|
559
610
|
for key, value in obj.items()
|
reflex/vars/base.py
CHANGED
|
@@ -361,21 +361,29 @@ class Var(Generic[VAR_TYPE]):
|
|
|
361
361
|
return False
|
|
362
362
|
|
|
363
363
|
def __init_subclass__(
|
|
364
|
-
cls,
|
|
364
|
+
cls,
|
|
365
|
+
python_types: Tuple[GenericType, ...] | GenericType = types.Unset(),
|
|
366
|
+
default_type: GenericType = types.Unset(),
|
|
367
|
+
**kwargs,
|
|
365
368
|
):
|
|
366
369
|
"""Initialize the subclass.
|
|
367
370
|
|
|
368
371
|
Args:
|
|
369
372
|
python_types: The python types that the var represents.
|
|
373
|
+
default_type: The default type of the var. Defaults to the first python type.
|
|
370
374
|
**kwargs: Additional keyword arguments.
|
|
371
375
|
"""
|
|
372
376
|
super().__init_subclass__(**kwargs)
|
|
373
377
|
|
|
374
|
-
if python_types
|
|
378
|
+
if python_types or default_type:
|
|
375
379
|
python_types = (
|
|
376
|
-
python_types if isinstance(python_types, tuple) else (python_types,)
|
|
380
|
+
(python_types if isinstance(python_types, tuple) else (python_types,))
|
|
381
|
+
if python_types
|
|
382
|
+
else ()
|
|
377
383
|
)
|
|
378
384
|
|
|
385
|
+
default_type = default_type or (python_types[0] if python_types else Any)
|
|
386
|
+
|
|
379
387
|
@dataclasses.dataclass(
|
|
380
388
|
eq=False,
|
|
381
389
|
frozen=True,
|
|
@@ -388,7 +396,7 @@ class Var(Generic[VAR_TYPE]):
|
|
|
388
396
|
default=Var(_js_expr="null", _var_type=None),
|
|
389
397
|
)
|
|
390
398
|
|
|
391
|
-
_default_var_type: ClassVar[GenericType] =
|
|
399
|
+
_default_var_type: ClassVar[GenericType] = default_type
|
|
392
400
|
|
|
393
401
|
ToVarOperation.__name__ = f'To{cls.__name__.removesuffix("Var")}Operation'
|
|
394
402
|
|
|
@@ -588,6 +596,12 @@ class Var(Generic[VAR_TYPE]):
|
|
|
588
596
|
output: type[list] | type[tuple] | type[set],
|
|
589
597
|
) -> ArrayVar: ...
|
|
590
598
|
|
|
599
|
+
@overload
|
|
600
|
+
def to(
|
|
601
|
+
self,
|
|
602
|
+
output: type[dict],
|
|
603
|
+
) -> ObjectVar[dict]: ...
|
|
604
|
+
|
|
591
605
|
@overload
|
|
592
606
|
def to(
|
|
593
607
|
self, output: Type[ObjectVar], var_type: Type[VAR_INSIDE]
|
reflex/vars/function.py
CHANGED
|
@@ -4,32 +4,177 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import dataclasses
|
|
6
6
|
import sys
|
|
7
|
-
from typing import Any, Callable, Optional, Sequence, Tuple, Type, Union
|
|
7
|
+
from typing import Any, Callable, Optional, Sequence, Tuple, Type, Union, overload
|
|
8
|
+
|
|
9
|
+
from typing_extensions import Concatenate, Generic, ParamSpec, Protocol, TypeVar
|
|
8
10
|
|
|
9
11
|
from reflex.utils import format
|
|
10
12
|
from reflex.utils.types import GenericType
|
|
11
13
|
|
|
12
14
|
from .base import CachedVarOperation, LiteralVar, Var, VarData, cached_property_no_lock
|
|
13
15
|
|
|
16
|
+
P = ParamSpec("P")
|
|
17
|
+
V1 = TypeVar("V1")
|
|
18
|
+
V2 = TypeVar("V2")
|
|
19
|
+
V3 = TypeVar("V3")
|
|
20
|
+
V4 = TypeVar("V4")
|
|
21
|
+
V5 = TypeVar("V5")
|
|
22
|
+
V6 = TypeVar("V6")
|
|
23
|
+
R = TypeVar("R")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ReflexCallable(Protocol[P, R]):
|
|
27
|
+
"""Protocol for a callable."""
|
|
28
|
+
|
|
29
|
+
__call__: Callable[P, R]
|
|
30
|
+
|
|
14
31
|
|
|
15
|
-
|
|
32
|
+
CALLABLE_TYPE = TypeVar("CALLABLE_TYPE", bound=ReflexCallable, infer_variance=True)
|
|
33
|
+
OTHER_CALLABLE_TYPE = TypeVar(
|
|
34
|
+
"OTHER_CALLABLE_TYPE", bound=ReflexCallable, infer_variance=True
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class FunctionVar(Var[CALLABLE_TYPE], default_type=ReflexCallable[Any, Any]):
|
|
16
39
|
"""Base class for immutable function vars."""
|
|
17
40
|
|
|
18
|
-
|
|
19
|
-
|
|
41
|
+
@overload
|
|
42
|
+
def partial(self) -> FunctionVar[CALLABLE_TYPE]: ...
|
|
43
|
+
|
|
44
|
+
@overload
|
|
45
|
+
def partial(
|
|
46
|
+
self: FunctionVar[ReflexCallable[Concatenate[V1, P], R]],
|
|
47
|
+
arg1: Union[V1, Var[V1]],
|
|
48
|
+
) -> FunctionVar[ReflexCallable[P, R]]: ...
|
|
49
|
+
|
|
50
|
+
@overload
|
|
51
|
+
def partial(
|
|
52
|
+
self: FunctionVar[ReflexCallable[Concatenate[V1, V2, P], R]],
|
|
53
|
+
arg1: Union[V1, Var[V1]],
|
|
54
|
+
arg2: Union[V2, Var[V2]],
|
|
55
|
+
) -> FunctionVar[ReflexCallable[P, R]]: ...
|
|
56
|
+
|
|
57
|
+
@overload
|
|
58
|
+
def partial(
|
|
59
|
+
self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, P], R]],
|
|
60
|
+
arg1: Union[V1, Var[V1]],
|
|
61
|
+
arg2: Union[V2, Var[V2]],
|
|
62
|
+
arg3: Union[V3, Var[V3]],
|
|
63
|
+
) -> FunctionVar[ReflexCallable[P, R]]: ...
|
|
64
|
+
|
|
65
|
+
@overload
|
|
66
|
+
def partial(
|
|
67
|
+
self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, V4, P], R]],
|
|
68
|
+
arg1: Union[V1, Var[V1]],
|
|
69
|
+
arg2: Union[V2, Var[V2]],
|
|
70
|
+
arg3: Union[V3, Var[V3]],
|
|
71
|
+
arg4: Union[V4, Var[V4]],
|
|
72
|
+
) -> FunctionVar[ReflexCallable[P, R]]: ...
|
|
73
|
+
|
|
74
|
+
@overload
|
|
75
|
+
def partial(
|
|
76
|
+
self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, V4, V5, P], R]],
|
|
77
|
+
arg1: Union[V1, Var[V1]],
|
|
78
|
+
arg2: Union[V2, Var[V2]],
|
|
79
|
+
arg3: Union[V3, Var[V3]],
|
|
80
|
+
arg4: Union[V4, Var[V4]],
|
|
81
|
+
arg5: Union[V5, Var[V5]],
|
|
82
|
+
) -> FunctionVar[ReflexCallable[P, R]]: ...
|
|
83
|
+
|
|
84
|
+
@overload
|
|
85
|
+
def partial(
|
|
86
|
+
self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, V4, V5, V6, P], R]],
|
|
87
|
+
arg1: Union[V1, Var[V1]],
|
|
88
|
+
arg2: Union[V2, Var[V2]],
|
|
89
|
+
arg3: Union[V3, Var[V3]],
|
|
90
|
+
arg4: Union[V4, Var[V4]],
|
|
91
|
+
arg5: Union[V5, Var[V5]],
|
|
92
|
+
arg6: Union[V6, Var[V6]],
|
|
93
|
+
) -> FunctionVar[ReflexCallable[P, R]]: ...
|
|
94
|
+
|
|
95
|
+
@overload
|
|
96
|
+
def partial(
|
|
97
|
+
self: FunctionVar[ReflexCallable[P, R]], *args: Var | Any
|
|
98
|
+
) -> FunctionVar[ReflexCallable[P, R]]: ...
|
|
99
|
+
|
|
100
|
+
@overload
|
|
101
|
+
def partial(self, *args: Var | Any) -> FunctionVar: ...
|
|
102
|
+
|
|
103
|
+
def partial(self, *args: Var | Any) -> FunctionVar: # type: ignore
|
|
104
|
+
"""Partially apply the function with the given arguments.
|
|
20
105
|
|
|
21
106
|
Args:
|
|
22
|
-
*args: The arguments to
|
|
107
|
+
*args: The arguments to partially apply the function with.
|
|
23
108
|
|
|
24
109
|
Returns:
|
|
25
|
-
The
|
|
110
|
+
The partially applied function.
|
|
26
111
|
"""
|
|
112
|
+
if not args:
|
|
113
|
+
return ArgsFunctionOperation.create((), self)
|
|
27
114
|
return ArgsFunctionOperation.create(
|
|
28
115
|
("...args",),
|
|
29
116
|
VarOperationCall.create(self, *args, Var(_js_expr="...args")),
|
|
30
117
|
)
|
|
31
118
|
|
|
32
|
-
|
|
119
|
+
@overload
|
|
120
|
+
def call(
|
|
121
|
+
self: FunctionVar[ReflexCallable[[V1], R]], arg1: Union[V1, Var[V1]]
|
|
122
|
+
) -> VarOperationCall[[V1], R]: ...
|
|
123
|
+
|
|
124
|
+
@overload
|
|
125
|
+
def call(
|
|
126
|
+
self: FunctionVar[ReflexCallable[[V1, V2], R]],
|
|
127
|
+
arg1: Union[V1, Var[V1]],
|
|
128
|
+
arg2: Union[V2, Var[V2]],
|
|
129
|
+
) -> VarOperationCall[[V1, V2], R]: ...
|
|
130
|
+
|
|
131
|
+
@overload
|
|
132
|
+
def call(
|
|
133
|
+
self: FunctionVar[ReflexCallable[[V1, V2, V3], R]],
|
|
134
|
+
arg1: Union[V1, Var[V1]],
|
|
135
|
+
arg2: Union[V2, Var[V2]],
|
|
136
|
+
arg3: Union[V3, Var[V3]],
|
|
137
|
+
) -> VarOperationCall[[V1, V2, V3], R]: ...
|
|
138
|
+
|
|
139
|
+
@overload
|
|
140
|
+
def call(
|
|
141
|
+
self: FunctionVar[ReflexCallable[[V1, V2, V3, V4], R]],
|
|
142
|
+
arg1: Union[V1, Var[V1]],
|
|
143
|
+
arg2: Union[V2, Var[V2]],
|
|
144
|
+
arg3: Union[V3, Var[V3]],
|
|
145
|
+
arg4: Union[V4, Var[V4]],
|
|
146
|
+
) -> VarOperationCall[[V1, V2, V3, V4], R]: ...
|
|
147
|
+
|
|
148
|
+
@overload
|
|
149
|
+
def call(
|
|
150
|
+
self: FunctionVar[ReflexCallable[[V1, V2, V3, V4, V5], R]],
|
|
151
|
+
arg1: Union[V1, Var[V1]],
|
|
152
|
+
arg2: Union[V2, Var[V2]],
|
|
153
|
+
arg3: Union[V3, Var[V3]],
|
|
154
|
+
arg4: Union[V4, Var[V4]],
|
|
155
|
+
arg5: Union[V5, Var[V5]],
|
|
156
|
+
) -> VarOperationCall[[V1, V2, V3, V4, V5], R]: ...
|
|
157
|
+
|
|
158
|
+
@overload
|
|
159
|
+
def call(
|
|
160
|
+
self: FunctionVar[ReflexCallable[[V1, V2, V3, V4, V5, V6], R]],
|
|
161
|
+
arg1: Union[V1, Var[V1]],
|
|
162
|
+
arg2: Union[V2, Var[V2]],
|
|
163
|
+
arg3: Union[V3, Var[V3]],
|
|
164
|
+
arg4: Union[V4, Var[V4]],
|
|
165
|
+
arg5: Union[V5, Var[V5]],
|
|
166
|
+
arg6: Union[V6, Var[V6]],
|
|
167
|
+
) -> VarOperationCall[[V1, V2, V3, V4, V5, V6], R]: ...
|
|
168
|
+
|
|
169
|
+
@overload
|
|
170
|
+
def call(
|
|
171
|
+
self: FunctionVar[ReflexCallable[P, R]], *args: Var | Any
|
|
172
|
+
) -> VarOperationCall[P, R]: ...
|
|
173
|
+
|
|
174
|
+
@overload
|
|
175
|
+
def call(self, *args: Var | Any) -> Var: ...
|
|
176
|
+
|
|
177
|
+
def call(self, *args: Var | Any) -> Var: # type: ignore
|
|
33
178
|
"""Call the function with the given arguments.
|
|
34
179
|
|
|
35
180
|
Args:
|
|
@@ -38,19 +183,29 @@ class FunctionVar(Var[Callable], python_types=Callable):
|
|
|
38
183
|
Returns:
|
|
39
184
|
The function call operation.
|
|
40
185
|
"""
|
|
41
|
-
return VarOperationCall.create(self, *args)
|
|
186
|
+
return VarOperationCall.create(self, *args).guess_type()
|
|
187
|
+
|
|
188
|
+
__call__ = call
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class BuilderFunctionVar(
|
|
192
|
+
FunctionVar[CALLABLE_TYPE], default_type=ReflexCallable[Any, Any]
|
|
193
|
+
):
|
|
194
|
+
"""Base class for immutable function vars with the builder pattern."""
|
|
195
|
+
|
|
196
|
+
__call__ = FunctionVar.partial
|
|
42
197
|
|
|
43
198
|
|
|
44
|
-
class FunctionStringVar(FunctionVar):
|
|
199
|
+
class FunctionStringVar(FunctionVar[CALLABLE_TYPE]):
|
|
45
200
|
"""Base class for immutable function vars from a string."""
|
|
46
201
|
|
|
47
202
|
@classmethod
|
|
48
203
|
def create(
|
|
49
204
|
cls,
|
|
50
205
|
func: str,
|
|
51
|
-
_var_type: Type[
|
|
206
|
+
_var_type: Type[OTHER_CALLABLE_TYPE] = ReflexCallable[Any, Any],
|
|
52
207
|
_var_data: VarData | None = None,
|
|
53
|
-
) -> FunctionStringVar:
|
|
208
|
+
) -> FunctionStringVar[OTHER_CALLABLE_TYPE]:
|
|
54
209
|
"""Create a new function var from a string.
|
|
55
210
|
|
|
56
211
|
Args:
|
|
@@ -60,7 +215,7 @@ class FunctionStringVar(FunctionVar):
|
|
|
60
215
|
Returns:
|
|
61
216
|
The function var.
|
|
62
217
|
"""
|
|
63
|
-
return
|
|
218
|
+
return FunctionStringVar(
|
|
64
219
|
_js_expr=func,
|
|
65
220
|
_var_type=_var_type,
|
|
66
221
|
_var_data=_var_data,
|
|
@@ -72,10 +227,10 @@ class FunctionStringVar(FunctionVar):
|
|
|
72
227
|
frozen=True,
|
|
73
228
|
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
74
229
|
)
|
|
75
|
-
class VarOperationCall(CachedVarOperation, Var):
|
|
230
|
+
class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
|
|
76
231
|
"""Base class for immutable vars that are the result of a function call."""
|
|
77
232
|
|
|
78
|
-
_func: Optional[FunctionVar] = dataclasses.field(default=None)
|
|
233
|
+
_func: Optional[FunctionVar[ReflexCallable[P, R]]] = dataclasses.field(default=None)
|
|
79
234
|
_args: Tuple[Union[Var, Any], ...] = dataclasses.field(default_factory=tuple)
|
|
80
235
|
|
|
81
236
|
@cached_property_no_lock
|
|
@@ -103,7 +258,7 @@ class VarOperationCall(CachedVarOperation, Var):
|
|
|
103
258
|
@classmethod
|
|
104
259
|
def create(
|
|
105
260
|
cls,
|
|
106
|
-
func: FunctionVar,
|
|
261
|
+
func: FunctionVar[ReflexCallable[P, R]],
|
|
107
262
|
*args: Var | Any,
|
|
108
263
|
_var_type: GenericType = Any,
|
|
109
264
|
_var_data: VarData | None = None,
|
|
@@ -118,9 +273,15 @@ class VarOperationCall(CachedVarOperation, Var):
|
|
|
118
273
|
Returns:
|
|
119
274
|
The function call var.
|
|
120
275
|
"""
|
|
276
|
+
function_return_type = (
|
|
277
|
+
func._var_type.__args__[1]
|
|
278
|
+
if getattr(func._var_type, "__args__", None)
|
|
279
|
+
else Any
|
|
280
|
+
)
|
|
281
|
+
var_type = _var_type if _var_type is not Any else function_return_type
|
|
121
282
|
return cls(
|
|
122
283
|
_js_expr="",
|
|
123
|
-
_var_type=
|
|
284
|
+
_var_type=var_type,
|
|
124
285
|
_var_data=_var_data,
|
|
125
286
|
_func=func,
|
|
126
287
|
_args=args,
|
|
@@ -157,6 +318,33 @@ class FunctionArgs:
|
|
|
157
318
|
rest: Optional[str] = None
|
|
158
319
|
|
|
159
320
|
|
|
321
|
+
def format_args_function_operation(
|
|
322
|
+
args: FunctionArgs, return_expr: Var | Any, explicit_return: bool
|
|
323
|
+
) -> str:
|
|
324
|
+
"""Format an args function operation.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
args: The function arguments.
|
|
328
|
+
return_expr: The return expression.
|
|
329
|
+
explicit_return: Whether to use explicit return syntax.
|
|
330
|
+
|
|
331
|
+
Returns:
|
|
332
|
+
The formatted args function operation.
|
|
333
|
+
"""
|
|
334
|
+
arg_names_str = ", ".join(
|
|
335
|
+
[arg if isinstance(arg, str) else arg.to_javascript() for arg in args.args]
|
|
336
|
+
) + (f", ...{args.rest}" if args.rest else "")
|
|
337
|
+
|
|
338
|
+
return_expr_str = str(LiteralVar.create(return_expr))
|
|
339
|
+
|
|
340
|
+
# Wrap return expression in curly braces if explicit return syntax is used.
|
|
341
|
+
return_expr_str_wrapped = (
|
|
342
|
+
format.wrap(return_expr_str, "{", "}") if explicit_return else return_expr_str
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
return f"(({arg_names_str}) => {return_expr_str_wrapped})"
|
|
346
|
+
|
|
347
|
+
|
|
160
348
|
@dataclasses.dataclass(
|
|
161
349
|
eq=False,
|
|
162
350
|
frozen=True,
|
|
@@ -176,24 +364,10 @@ class ArgsFunctionOperation(CachedVarOperation, FunctionVar):
|
|
|
176
364
|
Returns:
|
|
177
365
|
The name of the var.
|
|
178
366
|
"""
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
arg if isinstance(arg, str) else arg.to_javascript()
|
|
182
|
-
for arg in self._args.args
|
|
183
|
-
]
|
|
184
|
-
) + (f", ...{self._args.rest}" if self._args.rest else "")
|
|
185
|
-
|
|
186
|
-
return_expr_str = str(LiteralVar.create(self._return_expr))
|
|
187
|
-
|
|
188
|
-
# Wrap return expression in curly braces if explicit return syntax is used.
|
|
189
|
-
return_expr_str_wrapped = (
|
|
190
|
-
format.wrap(return_expr_str, "{", "}")
|
|
191
|
-
if self._explicit_return
|
|
192
|
-
else return_expr_str
|
|
367
|
+
return format_args_function_operation(
|
|
368
|
+
self._args, self._return_expr, self._explicit_return
|
|
193
369
|
)
|
|
194
370
|
|
|
195
|
-
return f"(({arg_names_str}) => {return_expr_str_wrapped})"
|
|
196
|
-
|
|
197
371
|
@classmethod
|
|
198
372
|
def create(
|
|
199
373
|
cls,
|
|
@@ -203,7 +377,7 @@ class ArgsFunctionOperation(CachedVarOperation, FunctionVar):
|
|
|
203
377
|
explicit_return: bool = False,
|
|
204
378
|
_var_type: GenericType = Callable,
|
|
205
379
|
_var_data: VarData | None = None,
|
|
206
|
-
)
|
|
380
|
+
):
|
|
207
381
|
"""Create a new function var.
|
|
208
382
|
|
|
209
383
|
Args:
|
|
@@ -226,8 +400,80 @@ class ArgsFunctionOperation(CachedVarOperation, FunctionVar):
|
|
|
226
400
|
)
|
|
227
401
|
|
|
228
402
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
"
|
|
403
|
+
@dataclasses.dataclass(
|
|
404
|
+
eq=False,
|
|
405
|
+
frozen=True,
|
|
406
|
+
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
233
407
|
)
|
|
408
|
+
class ArgsFunctionOperationBuilder(CachedVarOperation, BuilderFunctionVar):
|
|
409
|
+
"""Base class for immutable function defined via arguments and return expression with the builder pattern."""
|
|
410
|
+
|
|
411
|
+
_args: FunctionArgs = dataclasses.field(default_factory=FunctionArgs)
|
|
412
|
+
_return_expr: Union[Var, Any] = dataclasses.field(default=None)
|
|
413
|
+
_explicit_return: bool = dataclasses.field(default=False)
|
|
414
|
+
|
|
415
|
+
@cached_property_no_lock
|
|
416
|
+
def _cached_var_name(self) -> str:
|
|
417
|
+
"""The name of the var.
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
The name of the var.
|
|
421
|
+
"""
|
|
422
|
+
return format_args_function_operation(
|
|
423
|
+
self._args, self._return_expr, self._explicit_return
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
@classmethod
|
|
427
|
+
def create(
|
|
428
|
+
cls,
|
|
429
|
+
args_names: Sequence[Union[str, DestructuredArg]],
|
|
430
|
+
return_expr: Var | Any,
|
|
431
|
+
rest: str | None = None,
|
|
432
|
+
explicit_return: bool = False,
|
|
433
|
+
_var_type: GenericType = Callable,
|
|
434
|
+
_var_data: VarData | None = None,
|
|
435
|
+
):
|
|
436
|
+
"""Create a new function var.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
args_names: The names of the arguments.
|
|
440
|
+
return_expr: The return expression of the function.
|
|
441
|
+
rest: The name of the rest argument.
|
|
442
|
+
explicit_return: Whether to use explicit return syntax.
|
|
443
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
444
|
+
|
|
445
|
+
Returns:
|
|
446
|
+
The function var.
|
|
447
|
+
"""
|
|
448
|
+
return cls(
|
|
449
|
+
_js_expr="",
|
|
450
|
+
_var_type=_var_type,
|
|
451
|
+
_var_data=_var_data,
|
|
452
|
+
_args=FunctionArgs(args=tuple(args_names), rest=rest),
|
|
453
|
+
_return_expr=return_expr,
|
|
454
|
+
_explicit_return=explicit_return,
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
if python_version := sys.version_info[:2] >= (3, 10):
|
|
459
|
+
JSON_STRINGIFY = FunctionStringVar.create(
|
|
460
|
+
"JSON.stringify", _var_type=ReflexCallable[[Any], str]
|
|
461
|
+
)
|
|
462
|
+
ARRAY_ISARRAY = FunctionStringVar.create(
|
|
463
|
+
"Array.isArray", _var_type=ReflexCallable[[Any], bool]
|
|
464
|
+
)
|
|
465
|
+
PROTOTYPE_TO_STRING = FunctionStringVar.create(
|
|
466
|
+
"((__to_string) => __to_string.toString())",
|
|
467
|
+
_var_type=ReflexCallable[[Any], str],
|
|
468
|
+
)
|
|
469
|
+
else:
|
|
470
|
+
JSON_STRINGIFY = FunctionStringVar.create(
|
|
471
|
+
"JSON.stringify", _var_type=ReflexCallable[Any, str]
|
|
472
|
+
)
|
|
473
|
+
ARRAY_ISARRAY = FunctionStringVar.create(
|
|
474
|
+
"Array.isArray", _var_type=ReflexCallable[Any, bool]
|
|
475
|
+
)
|
|
476
|
+
PROTOTYPE_TO_STRING = FunctionStringVar.create(
|
|
477
|
+
"((__to_string) => __to_string.toString())",
|
|
478
|
+
_var_type=ReflexCallable[Any, str],
|
|
479
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: reflex
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.6a1
|
|
4
4
|
Summary: Web apps in pure Python.
|
|
5
5
|
Home-page: https://reflex.dev
|
|
6
6
|
License: Apache-2.0
|
|
@@ -33,7 +33,7 @@ Requires-Dist: python-multipart (>=0.0.5,<0.1)
|
|
|
33
33
|
Requires-Dist: python-socketio (>=5.7.0,<6.0)
|
|
34
34
|
Requires-Dist: redis (>=4.3.5,<6.0)
|
|
35
35
|
Requires-Dist: reflex-chakra (>=0.6.0)
|
|
36
|
-
Requires-Dist: reflex-hosting-cli (>=0.1.
|
|
36
|
+
Requires-Dist: reflex-hosting-cli (>=0.1.17,<2.0)
|
|
37
37
|
Requires-Dist: rich (>=13.0.0,<14.0)
|
|
38
38
|
Requires-Dist: setuptools (>=75.0)
|
|
39
39
|
Requires-Dist: sqlmodel (>=0.0.14,<0.1)
|
|
@@ -41,6 +41,7 @@ Requires-Dist: starlette-admin (>=0.11.0,<1.0)
|
|
|
41
41
|
Requires-Dist: tomlkit (>=0.12.4,<1.0)
|
|
42
42
|
Requires-Dist: twine (>=4.0.0,<6.0)
|
|
43
43
|
Requires-Dist: typer (>=0.4.2,<1.0)
|
|
44
|
+
Requires-Dist: typing_extensions (>=4.6.0)
|
|
44
45
|
Requires-Dist: uvicorn (>=0.20.0)
|
|
45
46
|
Requires-Dist: wheel (>=0.42.0,<1.0)
|
|
46
47
|
Requires-Dist: wrapt (>=1.11.0,<2.0) ; python_version < "3.11"
|