reflex 0.6.0a1__py3-none-any.whl → 0.6.0a2__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/_app.js.jinja2 +1 -1
- reflex/.templates/jinja/web/pages/utils.js.jinja2 +2 -2
- reflex/__init__.py +8 -2
- reflex/__init__.pyi +2 -1
- reflex/app.py +4 -2
- reflex/base.py +1 -1
- reflex/compiler/compiler.py +2 -2
- reflex/compiler/utils.py +3 -3
- reflex/components/base/app_wrap.py +2 -2
- reflex/components/base/app_wrap.pyi +17 -27
- reflex/components/base/bare.py +4 -5
- reflex/components/base/body.pyi +17 -27
- reflex/components/base/document.pyi +81 -131
- reflex/components/base/error_boundary.py +6 -7
- reflex/components/base/error_boundary.pyi +20 -33
- reflex/components/base/fragment.pyi +17 -27
- reflex/components/base/head.pyi +33 -53
- reflex/components/base/link.py +1 -1
- reflex/components/base/link.pyi +33 -54
- reflex/components/base/meta.pyi +65 -105
- reflex/components/base/script.py +1 -2
- reflex/components/base/script.pyi +21 -38
- reflex/components/component.py +48 -47
- reflex/components/core/banner.py +23 -27
- reflex/components/core/banner.pyi +134 -171
- reflex/components/core/client_side_routing.py +2 -3
- reflex/components/core/client_side_routing.pyi +33 -54
- reflex/components/core/clipboard.py +2 -1
- reflex/components/core/clipboard.pyi +20 -33
- reflex/components/core/cond.py +5 -5
- reflex/components/core/debounce.py +5 -5
- reflex/components/core/debounce.pyi +20 -33
- reflex/components/core/foreach.py +3 -4
- reflex/components/core/html.py +1 -1
- reflex/components/core/html.pyi +35 -46
- reflex/components/core/match.py +17 -17
- reflex/components/core/upload.py +17 -23
- reflex/components/core/upload.pyi +78 -124
- reflex/components/datadisplay/code.py +9 -10
- reflex/components/datadisplay/code.pyi +302 -412
- reflex/components/datadisplay/dataeditor.py +8 -10
- reflex/components/datadisplay/dataeditor.pyi +40 -53
- reflex/components/el/element.pyi +17 -27
- reflex/components/el/elements/base.py +1 -1
- reflex/components/el/elements/base.pyi +34 -45
- reflex/components/el/elements/forms.py +16 -16
- reflex/components/el/elements/forms.pyi +554 -707
- reflex/components/el/elements/inline.py +1 -1
- reflex/components/el/elements/inline.pyi +937 -1218
- reflex/components/el/elements/media.py +1 -1
- reflex/components/el/elements/media.pyi +786 -997
- reflex/components/el/elements/metadata.py +3 -6
- reflex/components/el/elements/metadata.pyi +181 -242
- reflex/components/el/elements/other.py +1 -1
- reflex/components/el/elements/other.pyi +235 -306
- reflex/components/el/elements/scripts.py +1 -1
- reflex/components/el/elements/scripts.pyi +109 -140
- reflex/components/el/elements/sectioning.py +0 -2
- reflex/components/el/elements/sectioning.pyi +496 -647
- reflex/components/el/elements/tables.py +1 -1
- reflex/components/el/elements/tables.pyi +351 -452
- reflex/components/el/elements/typography.py +1 -1
- reflex/components/el/elements/typography.pyi +506 -657
- reflex/components/gridjs/datatable.py +6 -9
- reflex/components/gridjs/datatable.pyi +35 -56
- reflex/components/lucide/icon.py +1 -1
- reflex/components/lucide/icon.pyi +33 -54
- reflex/components/markdown/markdown.py +26 -31
- reflex/components/markdown/markdown.pyi +27 -37
- reflex/components/moment/moment.py +13 -12
- reflex/components/moment/moment.pyi +23 -35
- reflex/components/next/base.pyi +17 -27
- reflex/components/next/image.py +1 -1
- reflex/components/next/image.pyi +22 -37
- reflex/components/next/link.py +1 -1
- reflex/components/next/link.pyi +17 -28
- reflex/components/next/video.py +1 -1
- reflex/components/next/video.pyi +17 -28
- reflex/components/plotly/plotly.py +12 -13
- reflex/components/plotly/plotly.pyi +39 -54
- reflex/components/props.py +1 -1
- reflex/components/radix/__init__.pyi +1 -0
- reflex/components/radix/primitives/__init__.pyi +1 -0
- reflex/components/radix/primitives/accordion.py +4 -4
- reflex/components/radix/primitives/accordion.pyi +424 -495
- reflex/components/radix/primitives/base.py +1 -1
- reflex/components/radix/primitives/base.pyi +33 -54
- reflex/components/radix/primitives/drawer.py +1 -1
- reflex/components/radix/primitives/drawer.pyi +172 -273
- reflex/components/radix/primitives/form.py +1 -1
- reflex/components/radix/primitives/form.pyi +257 -364
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/progress.pyi +231 -282
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/primitives/slider.pyi +87 -138
- reflex/components/radix/themes/base.py +3 -24
- reflex/components/radix/themes/base.pyi +178 -250
- reflex/components/radix/themes/color_mode.py +5 -5
- reflex/components/radix/themes/color_mode.pyi +187 -220
- reflex/components/radix/themes/components/alert_dialog.py +1 -1
- reflex/components/radix/themes/components/alert_dialog.pyi +136 -207
- reflex/components/radix/themes/components/aspect_ratio.py +1 -1
- reflex/components/radix/themes/components/aspect_ratio.pyi +17 -28
- reflex/components/radix/themes/components/avatar.py +1 -1
- reflex/components/radix/themes/components/avatar.pyi +70 -81
- reflex/components/radix/themes/components/badge.py +1 -1
- reflex/components/radix/themes/components/badge.pyi +88 -99
- reflex/components/radix/themes/components/button.py +1 -1
- reflex/components/radix/themes/components/button.pyi +98 -109
- reflex/components/radix/themes/components/callout.py +1 -1
- reflex/components/radix/themes/components/callout.pyi +322 -373
- reflex/components/radix/themes/components/card.py +1 -1
- reflex/components/radix/themes/components/card.pyi +38 -49
- reflex/components/radix/themes/components/checkbox.py +1 -2
- reflex/components/radix/themes/components/checkbox.pyi +208 -245
- reflex/components/radix/themes/components/checkbox_cards.py +1 -1
- reflex/components/radix/themes/components/checkbox_cards.pyi +94 -115
- reflex/components/radix/themes/components/checkbox_group.py +1 -1
- reflex/components/radix/themes/components/checkbox_group.pyi +86 -107
- reflex/components/radix/themes/components/context_menu.py +1 -1
- reflex/components/radix/themes/components/context_menu.pyi +238 -319
- reflex/components/radix/themes/components/data_list.py +1 -1
- reflex/components/radix/themes/components/data_list.pyi +130 -171
- reflex/components/radix/themes/components/dialog.py +1 -1
- reflex/components/radix/themes/components/dialog.pyi +139 -210
- reflex/components/radix/themes/components/dropdown_menu.py +1 -1
- reflex/components/radix/themes/components/dropdown_menu.pyi +249 -332
- reflex/components/radix/themes/components/hover_card.py +1 -1
- reflex/components/radix/themes/components/hover_card.pyi +90 -131
- reflex/components/radix/themes/components/icon_button.py +2 -3
- reflex/components/radix/themes/components/icon_button.pyi +98 -109
- reflex/components/radix/themes/components/inset.py +1 -1
- reflex/components/radix/themes/components/inset.pyi +47 -58
- reflex/components/radix/themes/components/popover.py +1 -1
- reflex/components/radix/themes/components/popover.pyi +95 -136
- reflex/components/radix/themes/components/progress.py +1 -1
- reflex/components/radix/themes/components/progress.pyi +71 -82
- reflex/components/radix/themes/components/radio.py +1 -1
- reflex/components/radix/themes/components/radio.pyi +69 -80
- reflex/components/radix/themes/components/radio_cards.py +1 -1
- reflex/components/radix/themes/components/radio_cards.pyi +98 -119
- reflex/components/radix/themes/components/radio_group.py +8 -11
- reflex/components/radix/themes/components/radio_group.pyi +228 -271
- reflex/components/radix/themes/components/scroll_area.py +1 -1
- reflex/components/radix/themes/components/scroll_area.pyi +21 -32
- reflex/components/radix/themes/components/segmented_control.py +1 -1
- reflex/components/radix/themes/components/segmented_control.pyi +90 -113
- reflex/components/radix/themes/components/select.py +2 -3
- reflex/components/radix/themes/components/select.pyi +374 -471
- reflex/components/radix/themes/components/separator.py +1 -2
- reflex/components/radix/themes/components/separator.pyi +69 -80
- reflex/components/radix/themes/components/skeleton.py +1 -1
- reflex/components/radix/themes/components/skeleton.pyi +23 -34
- reflex/components/radix/themes/components/slider.py +2 -3
- reflex/components/radix/themes/components/slider.pyi +75 -88
- reflex/components/radix/themes/components/spinner.py +1 -1
- reflex/components/radix/themes/components/spinner.pyi +19 -30
- reflex/components/radix/themes/components/switch.py +1 -1
- reflex/components/radix/themes/components/switch.pyi +71 -84
- reflex/components/radix/themes/components/table.py +1 -1
- reflex/components/radix/themes/components/table.pyi +261 -332
- reflex/components/radix/themes/components/tabs.py +1 -1
- reflex/components/radix/themes/components/tabs.pyi +139 -194
- reflex/components/radix/themes/components/text_area.py +1 -1
- reflex/components/radix/themes/components/text_area.pyi +96 -111
- reflex/components/radix/themes/components/text_field.py +1 -1
- reflex/components/radix/themes/components/text_field.pyi +247 -286
- reflex/components/radix/themes/components/tooltip.py +1 -1
- reflex/components/radix/themes/components/tooltip.pyi +26 -37
- reflex/components/radix/themes/layout/__init__.pyi +1 -0
- reflex/components/radix/themes/layout/base.py +1 -1
- reflex/components/radix/themes/layout/base.pyi +56 -67
- reflex/components/radix/themes/layout/box.pyi +34 -45
- reflex/components/radix/themes/layout/center.pyi +56 -67
- reflex/components/radix/themes/layout/container.py +1 -2
- reflex/components/radix/themes/layout/container.pyi +36 -47
- reflex/components/radix/themes/layout/flex.py +1 -1
- reflex/components/radix/themes/layout/flex.pyi +56 -67
- reflex/components/radix/themes/layout/grid.py +1 -1
- reflex/components/radix/themes/layout/grid.pyi +64 -75
- reflex/components/radix/themes/layout/list.py +5 -6
- reflex/components/radix/themes/layout/list.pyi +193 -244
- reflex/components/radix/themes/layout/section.py +1 -2
- reflex/components/radix/themes/layout/section.pyi +36 -47
- reflex/components/radix/themes/layout/spacer.pyi +56 -67
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/radix/themes/layout/stack.pyi +128 -159
- reflex/components/radix/themes/typography/blockquote.py +1 -1
- reflex/components/radix/themes/typography/blockquote.pyi +89 -100
- reflex/components/radix/themes/typography/code.py +1 -1
- reflex/components/radix/themes/typography/code.pyi +90 -101
- reflex/components/radix/themes/typography/heading.py +1 -1
- reflex/components/radix/themes/typography/heading.pyi +96 -107
- reflex/components/radix/themes/typography/link.py +1 -1
- reflex/components/radix/themes/typography/link.pyi +102 -113
- reflex/components/radix/themes/typography/text.py +1 -1
- reflex/components/radix/themes/typography/text.pyi +501 -572
- reflex/components/react_player/audio.pyi +33 -60
- reflex/components/react_player/react_player.py +1 -1
- reflex/components/react_player/react_player.pyi +33 -60
- reflex/components/react_player/video.pyi +33 -60
- reflex/components/recharts/cartesian.py +2 -3
- reflex/components/recharts/cartesian.pyi +678 -861
- reflex/components/recharts/charts.py +4 -5
- reflex/components/recharts/charts.pyi +252 -357
- reflex/components/recharts/general.py +1 -2
- reflex/components/recharts/general.pyi +180 -231
- reflex/components/recharts/polar.py +4 -5
- reflex/components/recharts/polar.pyi +144 -181
- reflex/components/recharts/recharts.pyi +33 -53
- reflex/components/sonner/toast.py +16 -17
- reflex/components/sonner/toast.pyi +36 -47
- reflex/components/suneditor/editor.py +2 -3
- reflex/components/suneditor/editor.pyi +55 -78
- reflex/components/tags/cond_tag.py +6 -4
- reflex/components/tags/iter_tag.py +28 -16
- reflex/components/tags/match_tag.py +6 -4
- reflex/components/tags/tag.py +40 -23
- reflex/event.py +113 -65
- reflex/experimental/client_state.py +18 -18
- reflex/experimental/hooks.py +16 -16
- reflex/experimental/layout.py +5 -5
- reflex/experimental/layout.pyi +136 -187
- reflex/middleware/hydrate_middleware.py +2 -0
- reflex/middleware/middleware.py +3 -3
- reflex/state.py +148 -82
- reflex/style.py +21 -22
- reflex/utils/exceptions.py +16 -0
- reflex/utils/format.py +22 -34
- reflex/utils/imports.py +16 -73
- reflex/utils/prerequisites.py +15 -8
- reflex/utils/pyi_generator.py +13 -8
- reflex/utils/serializers.py +12 -22
- reflex/utils/telemetry.py +2 -1
- reflex/utils/types.py +10 -5
- reflex/{ivars → vars}/__init__.py +6 -2
- reflex/{ivars → vars}/base.py +567 -206
- reflex/{ivars → vars}/function.py +15 -19
- reflex/{ivars → vars}/number.py +16 -18
- reflex/{ivars → vars}/object.py +28 -30
- reflex/{ivars → vars}/sequence.py +53 -42
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/METADATA +2 -2
- reflex-0.6.0a2.dist-info/RECORD +382 -0
- reflex/.templates/web/components/reflex/chakra_color_mode_provider.js +0 -36
- reflex/vars.py +0 -501
- reflex-0.6.0a1.dist-info/RECORD +0 -384
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/LICENSE +0 -0
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/WHEEL +0 -0
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/entry_points.txt +0 -0
reflex/utils/format.py
CHANGED
|
@@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any, Callable, List, Optional, Union
|
|
|
10
10
|
|
|
11
11
|
from reflex import constants
|
|
12
12
|
from reflex.utils import exceptions, types
|
|
13
|
-
from reflex.vars import Var
|
|
14
13
|
|
|
15
14
|
if TYPE_CHECKING:
|
|
16
15
|
from reflex.components.component import ComponentStyle
|
|
@@ -298,9 +297,9 @@ def format_route(route: str, format_case=True) -> str:
|
|
|
298
297
|
|
|
299
298
|
|
|
300
299
|
def format_match(
|
|
301
|
-
cond: str |
|
|
302
|
-
match_cases: List[List[
|
|
303
|
-
default:
|
|
300
|
+
cond: str | Var,
|
|
301
|
+
match_cases: List[List[Var]],
|
|
302
|
+
default: Var,
|
|
304
303
|
) -> str:
|
|
305
304
|
"""Format a match expression whose return type is a Var.
|
|
306
305
|
|
|
@@ -332,7 +331,7 @@ def format_match(
|
|
|
332
331
|
|
|
333
332
|
|
|
334
333
|
def format_prop(
|
|
335
|
-
prop: Union[
|
|
334
|
+
prop: Union[Var, EventChain, ComponentStyle, str],
|
|
336
335
|
) -> Union[int, float, str]:
|
|
337
336
|
"""Format a prop.
|
|
338
337
|
|
|
@@ -348,12 +347,12 @@ def format_prop(
|
|
|
348
347
|
"""
|
|
349
348
|
# import here to avoid circular import.
|
|
350
349
|
from reflex.event import EventChain
|
|
351
|
-
from reflex.ivars import ImmutableVar
|
|
352
350
|
from reflex.utils import serializers
|
|
351
|
+
from reflex.vars import Var
|
|
353
352
|
|
|
354
353
|
try:
|
|
355
354
|
# Handle var props.
|
|
356
|
-
if isinstance(prop,
|
|
355
|
+
if isinstance(prop, Var):
|
|
357
356
|
return str(prop)
|
|
358
357
|
|
|
359
358
|
# Handle event props.
|
|
@@ -406,26 +405,15 @@ def format_props(*single_props, **key_value_props) -> list[str]:
|
|
|
406
405
|
The formatted props list.
|
|
407
406
|
"""
|
|
408
407
|
# Format all the props.
|
|
409
|
-
from reflex.
|
|
408
|
+
from reflex.vars.base import LiteralVar, Var
|
|
410
409
|
|
|
411
410
|
return [
|
|
412
411
|
(
|
|
413
|
-
f"{name}={format_prop(prop)}"
|
|
414
|
-
if isinstance(prop, ImmutableVar) and not isinstance(prop, ImmutableVar)
|
|
415
|
-
else (
|
|
416
|
-
f"{name}={{{format_prop(prop if isinstance(prop, ImmutableVar) else LiteralVar.create(prop))}}}"
|
|
417
|
-
)
|
|
412
|
+
f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}"
|
|
418
413
|
)
|
|
419
414
|
for name, prop in sorted(key_value_props.items())
|
|
420
415
|
if prop is not None
|
|
421
|
-
] + [
|
|
422
|
-
(
|
|
423
|
-
str(prop)
|
|
424
|
-
if isinstance(prop, ImmutableVar) and not isinstance(prop, ImmutableVar)
|
|
425
|
-
else f"{str(LiteralVar.create(prop))}"
|
|
426
|
-
)
|
|
427
|
-
for prop in single_props
|
|
428
|
-
]
|
|
416
|
+
] + [(f"{str(LiteralVar.create(prop))}") for prop in single_props]
|
|
429
417
|
|
|
430
418
|
|
|
431
419
|
def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
|
|
@@ -486,10 +474,10 @@ def format_event(event_spec: EventSpec) -> str:
|
|
|
486
474
|
[
|
|
487
475
|
":".join(
|
|
488
476
|
(
|
|
489
|
-
name.
|
|
477
|
+
name._js_expr,
|
|
490
478
|
(
|
|
491
479
|
wrap(
|
|
492
|
-
json.dumps(val.
|
|
480
|
+
json.dumps(val._js_expr).strip('"').replace("`", "\\`"),
|
|
493
481
|
"`",
|
|
494
482
|
)
|
|
495
483
|
if val._var_is_string
|
|
@@ -511,7 +499,7 @@ def format_event(event_spec: EventSpec) -> str:
|
|
|
511
499
|
|
|
512
500
|
|
|
513
501
|
if TYPE_CHECKING:
|
|
514
|
-
from reflex.
|
|
502
|
+
from reflex.vars import Var
|
|
515
503
|
|
|
516
504
|
|
|
517
505
|
def format_queue_events(
|
|
@@ -523,7 +511,7 @@ def format_queue_events(
|
|
|
523
511
|
| None
|
|
524
512
|
) = None,
|
|
525
513
|
args_spec: Optional[ArgsSpec] = None,
|
|
526
|
-
) ->
|
|
514
|
+
) -> Var[EventChain]:
|
|
527
515
|
"""Format a list of event handler / event spec as a javascript callback.
|
|
528
516
|
|
|
529
517
|
The resulting code can be passed to interfaces that expect a callback
|
|
@@ -549,10 +537,10 @@ def format_queue_events(
|
|
|
549
537
|
call_event_fn,
|
|
550
538
|
call_event_handler,
|
|
551
539
|
)
|
|
552
|
-
from reflex.
|
|
540
|
+
from reflex.vars import FunctionVar, Var
|
|
553
541
|
|
|
554
542
|
if not events:
|
|
555
|
-
return
|
|
543
|
+
return Var("(() => null)").to(FunctionVar, EventChain) # type: ignore
|
|
556
544
|
|
|
557
545
|
# If no spec is provided, the function will take no arguments.
|
|
558
546
|
def _default_args_spec():
|
|
@@ -577,7 +565,7 @@ def format_queue_events(
|
|
|
577
565
|
specs = [call_event_handler(spec, args_spec or _default_args_spec)]
|
|
578
566
|
elif isinstance(spec, type(lambda: None)):
|
|
579
567
|
specs = call_event_fn(spec, args_spec or _default_args_spec) # type: ignore
|
|
580
|
-
if isinstance(specs,
|
|
568
|
+
if isinstance(specs, Var):
|
|
581
569
|
raise ValueError(
|
|
582
570
|
f"Invalid event spec: {specs}. Expected a list of EventSpecs."
|
|
583
571
|
)
|
|
@@ -585,7 +573,7 @@ def format_queue_events(
|
|
|
585
573
|
|
|
586
574
|
# Return the final code snippet, expecting queueEvents, processEvent, and socket to be in scope.
|
|
587
575
|
# Typically this snippet will _only_ run from within an rx.call_script eval context.
|
|
588
|
-
return
|
|
576
|
+
return Var(
|
|
589
577
|
f"{arg_def} => {{queueEvents([{','.join(payloads)}], {constants.CompileVars.SOCKET}); "
|
|
590
578
|
f"processEvent({constants.CompileVars.SOCKET})}}",
|
|
591
579
|
).to(FunctionVar, EventChain) # type: ignore
|
|
@@ -727,7 +715,7 @@ def collect_form_dict_names(form_dict: dict[str, Any]) -> dict[str, Any]:
|
|
|
727
715
|
return collapsed
|
|
728
716
|
|
|
729
717
|
|
|
730
|
-
def format_array_ref(refs: str, idx:
|
|
718
|
+
def format_array_ref(refs: str, idx: Var | None) -> str:
|
|
731
719
|
"""Format a ref accessed by array.
|
|
732
720
|
|
|
733
721
|
Args:
|
|
@@ -756,7 +744,7 @@ def format_data_editor_column(col: str | dict):
|
|
|
756
744
|
Returns:
|
|
757
745
|
The formatted column.
|
|
758
746
|
"""
|
|
759
|
-
from reflex.
|
|
747
|
+
from reflex.vars import Var
|
|
760
748
|
|
|
761
749
|
if isinstance(col, str):
|
|
762
750
|
return {"title": col, "id": col.lower(), "type": "str"}
|
|
@@ -770,7 +758,7 @@ def format_data_editor_column(col: str | dict):
|
|
|
770
758
|
col["overlayIcon"] = None
|
|
771
759
|
return col
|
|
772
760
|
|
|
773
|
-
if isinstance(col,
|
|
761
|
+
if isinstance(col, Var):
|
|
774
762
|
return col
|
|
775
763
|
|
|
776
764
|
raise ValueError(
|
|
@@ -787,9 +775,9 @@ def format_data_editor_cell(cell: Any):
|
|
|
787
775
|
Returns:
|
|
788
776
|
The formatted cell.
|
|
789
777
|
"""
|
|
790
|
-
from reflex.
|
|
778
|
+
from reflex.vars.base import Var
|
|
791
779
|
|
|
792
780
|
return {
|
|
793
|
-
"kind":
|
|
781
|
+
"kind": Var(_js_expr="GridCellKind.Text"),
|
|
794
782
|
"data": cell,
|
|
795
783
|
}
|
reflex/utils/imports.py
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import dataclasses
|
|
5
6
|
from collections import defaultdict
|
|
6
|
-
from typing import Dict, List, Optional, Tuple, Union
|
|
7
|
-
|
|
8
|
-
from reflex.base import Base
|
|
7
|
+
from typing import DefaultDict, Dict, List, Optional, Tuple, Union
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def merge_imports(
|
|
@@ -19,12 +18,22 @@ def merge_imports(
|
|
|
19
18
|
Returns:
|
|
20
19
|
The merged import dicts.
|
|
21
20
|
"""
|
|
22
|
-
all_imports = defaultdict(list)
|
|
21
|
+
all_imports: DefaultDict[str, List[ImportVar]] = defaultdict(list)
|
|
23
22
|
for import_dict in imports:
|
|
24
23
|
for lib, fields in (
|
|
25
24
|
import_dict if isinstance(import_dict, tuple) else import_dict.items()
|
|
26
25
|
):
|
|
27
|
-
|
|
26
|
+
if isinstance(fields, (list, tuple, set)):
|
|
27
|
+
all_imports[lib].extend(
|
|
28
|
+
(
|
|
29
|
+
ImportVar(field) if isinstance(field, str) else field
|
|
30
|
+
for field in fields
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
else:
|
|
34
|
+
all_imports[lib].append(
|
|
35
|
+
ImportVar(fields) if isinstance(fields, str) else fields
|
|
36
|
+
)
|
|
28
37
|
return all_imports
|
|
29
38
|
|
|
30
39
|
|
|
@@ -75,7 +84,8 @@ def collapse_imports(
|
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
|
|
78
|
-
|
|
87
|
+
@dataclasses.dataclass(order=True, frozen=True)
|
|
88
|
+
class ImportVar:
|
|
79
89
|
"""An import var."""
|
|
80
90
|
|
|
81
91
|
# The name of the import tag.
|
|
@@ -111,73 +121,6 @@ class ImportVar(Base):
|
|
|
111
121
|
else:
|
|
112
122
|
return self.tag or ""
|
|
113
123
|
|
|
114
|
-
def __lt__(self, other: ImportVar) -> bool:
|
|
115
|
-
"""Compare two ImportVar objects.
|
|
116
|
-
|
|
117
|
-
Args:
|
|
118
|
-
other: The other ImportVar object to compare.
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
Whether this ImportVar object is less than the other.
|
|
122
|
-
"""
|
|
123
|
-
return (
|
|
124
|
-
self.tag,
|
|
125
|
-
self.is_default,
|
|
126
|
-
self.alias,
|
|
127
|
-
self.install,
|
|
128
|
-
self.render,
|
|
129
|
-
self.transpile,
|
|
130
|
-
) < (
|
|
131
|
-
other.tag,
|
|
132
|
-
other.is_default,
|
|
133
|
-
other.alias,
|
|
134
|
-
other.install,
|
|
135
|
-
other.render,
|
|
136
|
-
other.transpile,
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
def __eq__(self, other: ImportVar) -> bool:
|
|
140
|
-
"""Check if two ImportVar objects are equal.
|
|
141
|
-
|
|
142
|
-
Args:
|
|
143
|
-
other: The other ImportVar object to compare.
|
|
144
|
-
|
|
145
|
-
Returns:
|
|
146
|
-
Whether the two ImportVar objects are equal.
|
|
147
|
-
"""
|
|
148
|
-
return (
|
|
149
|
-
self.tag,
|
|
150
|
-
self.is_default,
|
|
151
|
-
self.alias,
|
|
152
|
-
self.install,
|
|
153
|
-
self.render,
|
|
154
|
-
self.transpile,
|
|
155
|
-
) == (
|
|
156
|
-
other.tag,
|
|
157
|
-
other.is_default,
|
|
158
|
-
other.alias,
|
|
159
|
-
other.install,
|
|
160
|
-
other.render,
|
|
161
|
-
other.transpile,
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
def __hash__(self) -> int:
|
|
165
|
-
"""Hash the ImportVar object.
|
|
166
|
-
|
|
167
|
-
Returns:
|
|
168
|
-
The hash of the ImportVar object.
|
|
169
|
-
"""
|
|
170
|
-
return hash(
|
|
171
|
-
(
|
|
172
|
-
self.tag,
|
|
173
|
-
self.is_default,
|
|
174
|
-
self.alias,
|
|
175
|
-
self.install,
|
|
176
|
-
self.render,
|
|
177
|
-
self.transpile,
|
|
178
|
-
)
|
|
179
|
-
)
|
|
180
|
-
|
|
181
124
|
|
|
182
125
|
ImportTypes = Union[str, ImportVar, List[Union[str, ImportVar]], List[ImportVar]]
|
|
183
126
|
ImportDict = Dict[str, ImportTypes]
|
reflex/utils/prerequisites.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import dataclasses
|
|
5
6
|
import functools
|
|
6
7
|
import glob
|
|
7
8
|
import importlib
|
|
@@ -32,7 +33,6 @@ from redis import exceptions
|
|
|
32
33
|
from redis.asyncio import Redis
|
|
33
34
|
|
|
34
35
|
from reflex import constants, model
|
|
35
|
-
from reflex.base import Base
|
|
36
36
|
from reflex.compiler import templates
|
|
37
37
|
from reflex.config import Config, get_config
|
|
38
38
|
from reflex.utils import console, net, path_ops, processes
|
|
@@ -42,7 +42,8 @@ from reflex.utils.registry import _get_best_registry
|
|
|
42
42
|
CURRENTLY_INSTALLING_NODE = False
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
@dataclasses.dataclass(frozen=True)
|
|
46
|
+
class Template:
|
|
46
47
|
"""A template for a Reflex app."""
|
|
47
48
|
|
|
48
49
|
name: str
|
|
@@ -51,7 +52,8 @@ class Template(Base):
|
|
|
51
52
|
demo_url: str
|
|
52
53
|
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
@dataclasses.dataclass(frozen=True)
|
|
56
|
+
class CpuInfo:
|
|
55
57
|
"""Model to save cpu info."""
|
|
56
58
|
|
|
57
59
|
manufacturer_id: Optional[str]
|
|
@@ -1277,11 +1279,16 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
|
|
|
1277
1279
|
),
|
|
1278
1280
|
None,
|
|
1279
1281
|
)
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
if
|
|
1284
|
-
|
|
1282
|
+
|
|
1283
|
+
filtered_templates = {}
|
|
1284
|
+
for tp in templates_data:
|
|
1285
|
+
if tp["hidden"] or tp["code_url"] is None:
|
|
1286
|
+
continue
|
|
1287
|
+
known_fields = set(f.name for f in dataclasses.fields(Template))
|
|
1288
|
+
filtered_templates[tp["name"]] = Template(
|
|
1289
|
+
**{k: v for k, v in tp.items() if k in known_fields}
|
|
1290
|
+
)
|
|
1291
|
+
return filtered_templates
|
|
1285
1292
|
|
|
1286
1293
|
|
|
1287
1294
|
def create_config_init_app_from_remote_template(app_name: str, template_url: str):
|
reflex/utils/pyi_generator.py
CHANGED
|
@@ -19,8 +19,8 @@ from types import ModuleType, SimpleNamespace
|
|
|
19
19
|
from typing import Any, Callable, Iterable, Type, get_args
|
|
20
20
|
|
|
21
21
|
from reflex.components.component import Component
|
|
22
|
-
from reflex.ivars.base import ImmutableVar
|
|
23
22
|
from reflex.utils import types as rx_types
|
|
23
|
+
from reflex.vars.base import Var
|
|
24
24
|
|
|
25
25
|
logger = logging.getLogger("pyi_generator")
|
|
26
26
|
|
|
@@ -69,11 +69,10 @@ DEFAULT_TYPING_IMPORTS = {
|
|
|
69
69
|
# TODO: fix import ordering and unused imports with ruff later
|
|
70
70
|
DEFAULT_IMPORTS = {
|
|
71
71
|
"typing": sorted(DEFAULT_TYPING_IMPORTS),
|
|
72
|
-
"reflex.vars": ["Var"],
|
|
73
72
|
"reflex.components.core.breakpoints": ["Breakpoints"],
|
|
74
73
|
"reflex.event": ["EventChain", "EventHandler", "EventSpec"],
|
|
75
74
|
"reflex.style": ["Style"],
|
|
76
|
-
"reflex.
|
|
75
|
+
"reflex.vars.base": ["Var"],
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
|
|
@@ -151,7 +150,7 @@ def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
|
|
|
151
150
|
|
|
152
151
|
if args:
|
|
153
152
|
inner_container_type_args = (
|
|
154
|
-
|
|
153
|
+
sorted((repr(arg) for arg in args))
|
|
155
154
|
if rx_types.is_literal(value)
|
|
156
155
|
else [
|
|
157
156
|
_get_type_hint(arg, type_hint_globals, is_optional=False)
|
|
@@ -185,7 +184,7 @@ def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
|
|
|
185
184
|
if arg is not type(None)
|
|
186
185
|
]
|
|
187
186
|
if len(types) > 1:
|
|
188
|
-
res = ", ".join(types)
|
|
187
|
+
res = ", ".join(sorted(types))
|
|
189
188
|
res = f"Union[{res}]"
|
|
190
189
|
elif isinstance(value, str):
|
|
191
190
|
ev = eval(value, type_hint_globals)
|
|
@@ -356,7 +355,7 @@ def _extract_class_props_as_ast_nodes(
|
|
|
356
355
|
with contextlib.suppress(AttributeError, KeyError):
|
|
357
356
|
# Try to get default from pydantic field definition.
|
|
358
357
|
default = target_class.__fields__[name].default
|
|
359
|
-
if isinstance(default,
|
|
358
|
+
if isinstance(default, Var):
|
|
360
359
|
default = default._decode() # type: ignore
|
|
361
360
|
|
|
362
361
|
kwargs.append(
|
|
@@ -434,7 +433,7 @@ def _generate_component_create_functiondef(
|
|
|
434
433
|
ast.arg(
|
|
435
434
|
arg=trigger,
|
|
436
435
|
annotation=ast.Name(
|
|
437
|
-
id="Optional[Union[EventHandler, EventSpec, list, Callable,
|
|
436
|
+
id="Optional[Union[EventHandler, EventSpec, list, Callable, Var]]"
|
|
438
437
|
),
|
|
439
438
|
),
|
|
440
439
|
ast.Constant(value=None),
|
|
@@ -903,7 +902,13 @@ class PyiGenerator:
|
|
|
903
902
|
# construct the import statement and handle special cases for aliases
|
|
904
903
|
sub_mod_attrs_imports = [
|
|
905
904
|
f"from .{path} import {mod if not isinstance(mod, tuple) else mod[0]} as {mod if not isinstance(mod, tuple) else mod[1]}"
|
|
906
|
-
+ (
|
|
905
|
+
+ (
|
|
906
|
+
" # type: ignore"
|
|
907
|
+
if mod in pyright_ignore_imports
|
|
908
|
+
else " # noqa" # ignore ruff formatting here for cases like rx.list.
|
|
909
|
+
if isinstance(mod, tuple)
|
|
910
|
+
else ""
|
|
911
|
+
)
|
|
907
912
|
for mod, path in sub_mod_attrs.items()
|
|
908
913
|
]
|
|
909
914
|
sub_mod_attrs_imports.append("")
|
reflex/utils/serializers.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import dataclasses
|
|
5
6
|
import functools
|
|
6
7
|
import json
|
|
7
8
|
import warnings
|
|
@@ -29,7 +30,7 @@ from reflex.utils import types
|
|
|
29
30
|
|
|
30
31
|
# Mapping from type to a serializer.
|
|
31
32
|
# The serializer should convert the type to a JSON object.
|
|
32
|
-
SerializedType = Union[str, bool, int, float, list, dict]
|
|
33
|
+
SerializedType = Union[str, bool, int, float, list, dict, None]
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
Serializer = Callable[[Type], SerializedType]
|
|
@@ -124,6 +125,8 @@ def serialize(
|
|
|
124
125
|
|
|
125
126
|
# If there is no serializer, return None.
|
|
126
127
|
if serializer is None:
|
|
128
|
+
if dataclasses.is_dataclass(value) and not isinstance(value, type):
|
|
129
|
+
return serialize(dataclasses.asdict(value))
|
|
127
130
|
if get_type:
|
|
128
131
|
return None, None
|
|
129
132
|
return None
|
|
@@ -225,7 +228,7 @@ def serialize_str(value: str) -> str:
|
|
|
225
228
|
|
|
226
229
|
|
|
227
230
|
@serializer
|
|
228
|
-
def serialize_primitive(value: Union[bool, int, float, None])
|
|
231
|
+
def serialize_primitive(value: Union[bool, int, float, None]):
|
|
229
232
|
"""Serialize a primitive type.
|
|
230
233
|
|
|
231
234
|
Args:
|
|
@@ -234,13 +237,11 @@ def serialize_primitive(value: Union[bool, int, float, None]) -> str:
|
|
|
234
237
|
Returns:
|
|
235
238
|
The serialized number/bool/None.
|
|
236
239
|
"""
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return format.json_dumps(value)
|
|
240
|
+
return value
|
|
240
241
|
|
|
241
242
|
|
|
242
243
|
@serializer
|
|
243
|
-
def serialize_base(value: Base) ->
|
|
244
|
+
def serialize_base(value: Base) -> dict:
|
|
244
245
|
"""Serialize a Base instance.
|
|
245
246
|
|
|
246
247
|
Args:
|
|
@@ -249,18 +250,11 @@ def serialize_base(value: Base) -> str:
|
|
|
249
250
|
Returns:
|
|
250
251
|
The serialized Base.
|
|
251
252
|
"""
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return str(
|
|
255
|
-
LiteralObjectVar.create(
|
|
256
|
-
{k: (None if callable(v) else v) for k, v in value.dict().items()},
|
|
257
|
-
_var_type=type(value),
|
|
258
|
-
)
|
|
259
|
-
)
|
|
253
|
+
return {k: serialize(v) for k, v in value.dict().items() if not callable(v)}
|
|
260
254
|
|
|
261
255
|
|
|
262
256
|
@serializer
|
|
263
|
-
def serialize_list(value: Union[List, Tuple, Set]) ->
|
|
257
|
+
def serialize_list(value: Union[List, Tuple, Set]) -> list:
|
|
264
258
|
"""Serialize a list to a JSON string.
|
|
265
259
|
|
|
266
260
|
Args:
|
|
@@ -269,13 +263,11 @@ def serialize_list(value: Union[List, Tuple, Set]) -> str:
|
|
|
269
263
|
Returns:
|
|
270
264
|
The serialized list.
|
|
271
265
|
"""
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return str(LiteralArrayVar.create(value))
|
|
266
|
+
return [serialize(item) for item in value]
|
|
275
267
|
|
|
276
268
|
|
|
277
269
|
@serializer
|
|
278
|
-
def serialize_dict(prop: Dict[str, Any]) ->
|
|
270
|
+
def serialize_dict(prop: Dict[str, Any]) -> dict:
|
|
279
271
|
"""Serialize a dictionary to a JSON string.
|
|
280
272
|
|
|
281
273
|
Args:
|
|
@@ -284,9 +276,7 @@ def serialize_dict(prop: Dict[str, Any]) -> str:
|
|
|
284
276
|
Returns:
|
|
285
277
|
The serialized dictionary.
|
|
286
278
|
"""
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return str(LiteralObjectVar.create(prop))
|
|
279
|
+
return {k: serialize(v) for k, v in prop.items()}
|
|
290
280
|
|
|
291
281
|
|
|
292
282
|
@serializer(to=str)
|
reflex/utils/telemetry.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import dataclasses
|
|
6
7
|
import multiprocessing
|
|
7
8
|
import platform
|
|
8
9
|
import warnings
|
|
@@ -144,7 +145,7 @@ def _prepare_event(event: str, **kwargs) -> dict:
|
|
|
144
145
|
"python_version": get_python_version(),
|
|
145
146
|
"cpu_count": get_cpu_count(),
|
|
146
147
|
"memory": get_memory(),
|
|
147
|
-
"cpu_info":
|
|
148
|
+
"cpu_info": dataclasses.asdict(cpuinfo) if cpuinfo else {},
|
|
148
149
|
**additional_fields,
|
|
149
150
|
},
|
|
150
151
|
"timestamp": stamp,
|
reflex/utils/types.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import contextlib
|
|
6
|
+
import dataclasses
|
|
6
7
|
import inspect
|
|
7
8
|
import sys
|
|
8
9
|
import types
|
|
@@ -95,7 +96,7 @@ PrimitiveType = Union[int, float, bool, str, list, dict, set, tuple]
|
|
|
95
96
|
StateVar = Union[PrimitiveType, Base, None]
|
|
96
97
|
StateIterVar = Union[list, set, tuple]
|
|
97
98
|
|
|
98
|
-
# ArgsSpec = Callable[[
|
|
99
|
+
# ArgsSpec = Callable[[Var], list[Var]]
|
|
99
100
|
ArgsSpec = Callable
|
|
100
101
|
|
|
101
102
|
|
|
@@ -480,7 +481,11 @@ def is_valid_var_type(type_: Type) -> bool:
|
|
|
480
481
|
|
|
481
482
|
if is_union(type_):
|
|
482
483
|
return all((is_valid_var_type(arg) for arg in get_args(type_)))
|
|
483
|
-
return
|
|
484
|
+
return (
|
|
485
|
+
_issubclass(type_, StateVar)
|
|
486
|
+
or serializers.has_serializer(type_)
|
|
487
|
+
or dataclasses.is_dataclass(type_)
|
|
488
|
+
)
|
|
484
489
|
|
|
485
490
|
|
|
486
491
|
def is_backend_base_variable(name: str, cls: Type) -> bool:
|
|
@@ -514,7 +519,7 @@ def is_backend_base_variable(name: str, cls: Type) -> bool:
|
|
|
514
519
|
if name in cls.inherited_backend_vars:
|
|
515
520
|
return False
|
|
516
521
|
|
|
517
|
-
from reflex.
|
|
522
|
+
from reflex.vars.base import is_computed_var
|
|
518
523
|
|
|
519
524
|
if name in cls.__dict__:
|
|
520
525
|
value = cls.__dict__[name]
|
|
@@ -590,11 +595,11 @@ def validate_literal(key: str, value: Any, expected_type: Type, comp_name: str):
|
|
|
590
595
|
Raises:
|
|
591
596
|
ValueError: When the value is not a valid literal.
|
|
592
597
|
"""
|
|
593
|
-
from reflex.
|
|
598
|
+
from reflex.vars import Var
|
|
594
599
|
|
|
595
600
|
if (
|
|
596
601
|
is_literal(expected_type)
|
|
597
|
-
and not isinstance(value,
|
|
602
|
+
and not isinstance(value, Var) # validating vars is not supported yet.
|
|
598
603
|
and not is_encoded_fstring(value) # f-strings are not supported.
|
|
599
604
|
and value not in expected_type.__args__
|
|
600
605
|
):
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Immutable-Based Var System."""
|
|
2
2
|
|
|
3
|
-
from .base import ImmutableVar as ImmutableVar
|
|
4
3
|
from .base import LiteralVar as LiteralVar
|
|
4
|
+
from .base import Var as Var
|
|
5
|
+
from .base import VarData as VarData
|
|
6
|
+
from .base import get_unique_variable_name as get_unique_variable_name
|
|
7
|
+
from .base import get_uuid_string_var as get_uuid_string_var
|
|
5
8
|
from .base import var_operation as var_operation
|
|
9
|
+
from .base import var_operation_return as var_operation_return
|
|
6
10
|
from .function import FunctionStringVar as FunctionStringVar
|
|
7
11
|
from .function import FunctionVar as FunctionVar
|
|
8
12
|
from .function import VarOperationCall as VarOperationCall
|