reflex 0.7.13a2__py3-none-any.whl → 0.7.14a1__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/blank/code/blank.py +0 -2
- reflex/app.py +64 -69
- reflex/app_mixins/lifespan.py +2 -3
- reflex/app_mixins/middleware.py +1 -0
- reflex/app_mixins/mixin.py +0 -1
- reflex/assets.py +6 -3
- reflex/base.py +3 -2
- reflex/compiler/compiler.py +77 -64
- reflex/compiler/utils.py +8 -6
- reflex/components/base/app_wrap.pyi +0 -1
- reflex/components/base/bare.py +5 -7
- reflex/components/base/body.pyi +0 -1
- reflex/components/base/document.pyi +0 -5
- reflex/components/base/error_boundary.pyi +0 -1
- reflex/components/base/fragment.pyi +0 -1
- reflex/components/base/head.pyi +0 -2
- reflex/components/base/link.pyi +0 -2
- reflex/components/base/meta.py +2 -1
- reflex/components/base/meta.pyi +0 -4
- reflex/components/base/script.py +2 -1
- reflex/components/base/script.pyi +0 -1
- reflex/components/base/strict_mode.pyi +0 -1
- reflex/components/component.py +38 -40
- reflex/components/core/auto_scroll.pyi +0 -1
- reflex/components/core/banner.pyi +0 -6
- reflex/components/core/breakpoints.py +9 -11
- reflex/components/core/client_side_routing.pyi +0 -2
- reflex/components/core/clipboard.pyi +0 -1
- reflex/components/core/colors.py +10 -7
- reflex/components/core/cond.py +4 -2
- reflex/components/core/debounce.py +5 -3
- reflex/components/core/debounce.pyi +0 -1
- reflex/components/core/foreach.py +8 -6
- reflex/components/core/html.py +3 -3
- reflex/components/core/html.pyi +0 -1
- reflex/components/core/match.py +19 -17
- reflex/components/core/sticky.pyi +0 -4
- reflex/components/core/upload.pyi +0 -5
- reflex/components/datadisplay/code.py +1 -2
- reflex/components/datadisplay/code.pyi +0 -2
- reflex/components/datadisplay/dataeditor.py +7 -10
- reflex/components/datadisplay/dataeditor.pyi +0 -1
- reflex/components/datadisplay/logo.py +3 -4
- reflex/components/datadisplay/shiki_code_block.py +8 -11
- reflex/components/datadisplay/shiki_code_block.pyi +0 -3
- reflex/components/dynamic.py +2 -3
- reflex/components/el/__init__.pyi +2 -0
- reflex/components/el/element.pyi +0 -1
- reflex/components/el/elements/__init__.py +1 -0
- reflex/components/el/elements/__init__.pyi +3 -0
- reflex/components/el/elements/base.pyi +0 -1
- reflex/components/el/elements/forms.py +3 -4
- reflex/components/el/elements/forms.pyi +1 -18
- reflex/components/el/elements/inline.pyi +0 -28
- reflex/components/el/elements/media.py +26 -0
- reflex/components/el/elements/media.pyi +259 -25
- reflex/components/el/elements/metadata.py +0 -1
- reflex/components/el/elements/metadata.pyi +0 -6
- reflex/components/el/elements/other.pyi +0 -7
- reflex/components/el/elements/scripts.pyi +0 -3
- reflex/components/el/elements/sectioning.pyi +0 -15
- reflex/components/el/elements/tables.pyi +0 -10
- reflex/components/el/elements/typography.pyi +0 -15
- reflex/components/gridjs/datatable.py +10 -13
- reflex/components/gridjs/datatable.pyi +0 -2
- reflex/components/lucide/icon.py +10 -9
- reflex/components/lucide/icon.pyi +0 -3
- reflex/components/markdown/markdown.py +6 -8
- reflex/components/markdown/markdown.pyi +0 -1
- reflex/components/moment/moment.pyi +0 -1
- reflex/components/next/base.py +0 -2
- reflex/components/next/base.pyi +0 -3
- reflex/components/next/image.pyi +0 -1
- reflex/components/next/link.pyi +0 -1
- reflex/components/next/video.pyi +0 -1
- reflex/components/plotly/plotly.pyi +0 -9
- reflex/components/props.py +4 -3
- reflex/components/radix/primitives/accordion.pyi +0 -7
- reflex/components/radix/primitives/base.py +1 -3
- reflex/components/radix/primitives/base.pyi +0 -2
- reflex/components/radix/primitives/drawer.pyi +0 -11
- reflex/components/radix/primitives/form.py +4 -8
- reflex/components/radix/primitives/form.pyi +0 -12
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/progress.pyi +0 -5
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/primitives/slider.pyi +0 -5
- reflex/components/radix/themes/base.pyi +0 -8
- reflex/components/radix/themes/color_mode.pyi +0 -3
- reflex/components/radix/themes/components/alert_dialog.py +4 -2
- reflex/components/radix/themes/components/alert_dialog.pyi +4 -9
- reflex/components/radix/themes/components/aspect_ratio.py +1 -2
- reflex/components/radix/themes/components/aspect_ratio.pyi +1 -3
- reflex/components/radix/themes/components/avatar.py +5 -2
- reflex/components/radix/themes/components/avatar.pyi +1 -3
- reflex/components/radix/themes/components/badge.py +5 -2
- reflex/components/radix/themes/components/badge.pyi +1 -3
- reflex/components/radix/themes/components/button.py +2 -3
- reflex/components/radix/themes/components/button.pyi +1 -3
- reflex/components/radix/themes/components/callout.py +1 -2
- reflex/components/radix/themes/components/callout.pyi +1 -7
- reflex/components/radix/themes/components/card.py +1 -2
- reflex/components/radix/themes/components/card.pyi +1 -3
- reflex/components/radix/themes/components/checkbox.py +7 -4
- reflex/components/radix/themes/components/checkbox.pyi +1 -5
- reflex/components/radix/themes/components/checkbox_cards.py +1 -2
- reflex/components/radix/themes/components/checkbox_cards.pyi +1 -4
- reflex/components/radix/themes/components/checkbox_group.py +1 -2
- reflex/components/radix/themes/components/checkbox_group.pyi +1 -4
- reflex/components/radix/themes/components/context_menu.py +1 -1
- reflex/components/radix/themes/components/context_menu.pyi +1 -14
- reflex/components/radix/themes/components/data_list.py +1 -2
- reflex/components/radix/themes/components/data_list.pyi +1 -6
- reflex/components/radix/themes/components/dialog.py +4 -2
- reflex/components/radix/themes/components/dialog.pyi +4 -9
- reflex/components/radix/themes/components/dropdown_menu.py +5 -2
- reflex/components/radix/themes/components/dropdown_menu.pyi +4 -10
- reflex/components/radix/themes/components/hover_card.py +4 -2
- reflex/components/radix/themes/components/hover_card.pyi +4 -6
- reflex/components/radix/themes/components/icon_button.py +7 -8
- reflex/components/radix/themes/components/icon_button.pyi +1 -3
- reflex/components/radix/themes/components/inset.py +1 -2
- reflex/components/radix/themes/components/inset.pyi +1 -3
- reflex/components/radix/themes/components/popover.py +4 -2
- reflex/components/radix/themes/components/popover.pyi +4 -6
- reflex/components/radix/themes/components/progress.py +1 -2
- reflex/components/radix/themes/components/progress.pyi +1 -3
- reflex/components/radix/themes/components/radio.py +1 -2
- reflex/components/radix/themes/components/radio.pyi +1 -3
- reflex/components/radix/themes/components/radio_cards.py +1 -2
- reflex/components/radix/themes/components/radio_cards.pyi +1 -4
- reflex/components/radix/themes/components/radio_group.py +7 -5
- reflex/components/radix/themes/components/radio_group.pyi +1 -6
- reflex/components/radix/themes/components/scroll_area.py +1 -2
- reflex/components/radix/themes/components/scroll_area.pyi +1 -3
- reflex/components/radix/themes/components/segmented_control.py +1 -2
- reflex/components/radix/themes/components/segmented_control.pyi +1 -4
- reflex/components/radix/themes/components/select.py +5 -2
- reflex/components/radix/themes/components/select.pyi +1 -11
- reflex/components/radix/themes/components/separator.py +1 -2
- reflex/components/radix/themes/components/separator.pyi +1 -3
- reflex/components/radix/themes/components/skeleton.py +1 -2
- reflex/components/radix/themes/components/skeleton.pyi +1 -3
- reflex/components/radix/themes/components/slider.py +1 -2
- reflex/components/radix/themes/components/slider.pyi +1 -3
- reflex/components/radix/themes/components/spinner.py +1 -2
- reflex/components/radix/themes/components/spinner.pyi +1 -3
- reflex/components/radix/themes/components/switch.py +1 -2
- reflex/components/radix/themes/components/switch.pyi +1 -3
- reflex/components/radix/themes/components/table.py +1 -2
- reflex/components/radix/themes/components/table.pyi +1 -9
- reflex/components/radix/themes/components/tabs.py +1 -2
- reflex/components/radix/themes/components/tabs.pyi +1 -7
- reflex/components/radix/themes/components/text_area.py +5 -2
- reflex/components/radix/themes/components/text_area.pyi +1 -3
- reflex/components/radix/themes/components/text_field.py +5 -2
- reflex/components/radix/themes/components/text_field.pyi +1 -5
- reflex/components/radix/themes/components/tooltip.py +1 -2
- reflex/components/radix/themes/components/tooltip.pyi +1 -3
- reflex/components/radix/themes/layout/base.py +5 -2
- reflex/components/radix/themes/layout/base.pyi +5 -3
- reflex/components/radix/themes/layout/box.py +1 -2
- reflex/components/radix/themes/layout/box.pyi +1 -3
- reflex/components/radix/themes/layout/center.pyi +0 -1
- reflex/components/radix/themes/layout/container.py +1 -2
- reflex/components/radix/themes/layout/container.pyi +1 -3
- reflex/components/radix/themes/layout/flex.py +6 -2
- reflex/components/radix/themes/layout/flex.pyi +1 -3
- reflex/components/radix/themes/layout/grid.py +6 -2
- reflex/components/radix/themes/layout/grid.pyi +1 -3
- reflex/components/radix/themes/layout/list.py +2 -1
- reflex/components/radix/themes/layout/list.pyi +0 -5
- reflex/components/radix/themes/layout/section.py +1 -2
- reflex/components/radix/themes/layout/section.pyi +1 -3
- reflex/components/radix/themes/layout/spacer.pyi +0 -1
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/radix/themes/layout/stack.pyi +0 -3
- reflex/components/radix/themes/typography/blockquote.py +1 -1
- reflex/components/radix/themes/typography/blockquote.pyi +1 -3
- reflex/components/radix/themes/typography/code.py +5 -1
- reflex/components/radix/themes/typography/code.pyi +1 -3
- reflex/components/radix/themes/typography/heading.py +1 -1
- reflex/components/radix/themes/typography/heading.pyi +1 -3
- reflex/components/radix/themes/typography/link.py +3 -2
- reflex/components/radix/themes/typography/link.pyi +1 -3
- reflex/components/radix/themes/typography/text.py +1 -1
- reflex/components/radix/themes/typography/text.pyi +1 -9
- reflex/components/react_player/audio.py +0 -2
- reflex/components/react_player/audio.pyi +0 -3
- reflex/components/react_player/react_player.pyi +0 -1
- reflex/components/react_player/video.py +0 -2
- reflex/components/react_player/video.pyi +0 -3
- reflex/components/recharts/__init__.py +1 -1
- reflex/components/recharts/__init__.pyi +1 -1
- reflex/components/recharts/cartesian.py +20 -25
- reflex/components/recharts/cartesian.pyi +20 -37
- reflex/components/recharts/charts.py +2 -1
- reflex/components/recharts/charts.pyi +0 -12
- reflex/components/recharts/general.pyi +0 -6
- reflex/components/recharts/polar.py +5 -4
- reflex/components/recharts/polar.pyi +4 -10
- reflex/components/recharts/recharts.py +12 -10
- reflex/components/recharts/recharts.pyi +10 -11
- reflex/components/sonner/toast.py +2 -2
- reflex/components/sonner/toast.pyi +0 -2
- reflex/components/suneditor/editor.py +2 -1
- reflex/components/suneditor/editor.pyi +0 -1
- reflex/components/tags/iter_tag.py +4 -2
- reflex/config.py +47 -35
- reflex/constants/base.py +3 -3
- reflex/constants/compiler.py +8 -6
- reflex/constants/installer.py +24 -15
- reflex/custom_components/custom_components.py +1 -2
- reflex/event.py +58 -60
- reflex/experimental/__init__.py +2 -2
- reflex/experimental/client_state.py +9 -4
- reflex/experimental/layout.pyi +0 -5
- reflex/istate/manager.py +15 -19
- reflex/istate/proxy.py +19 -12
- reflex/model.py +6 -4
- reflex/plugins/base.py +8 -0
- reflex/plugins/tailwind_v3.py +8 -0
- reflex/plugins/tailwind_v4.py +8 -0
- reflex/reflex.py +9 -11
- reflex/route.py +7 -9
- reflex/state.py +66 -70
- reflex/style.py +3 -1
- reflex/testing.py +46 -29
- reflex/utils/build.py +2 -1
- reflex/utils/console.py +9 -17
- reflex/utils/exec.py +9 -11
- reflex/utils/format.py +21 -24
- reflex/utils/imports.py +4 -3
- reflex/utils/lazy_loader.py +3 -3
- reflex/utils/misc.py +2 -1
- reflex/utils/net.py +2 -2
- reflex/utils/path_ops.py +2 -1
- reflex/utils/prerequisites.py +67 -38
- reflex/utils/processes.py +4 -6
- reflex/utils/pyi_generator.py +46 -41
- reflex/utils/redir.py +1 -1
- reflex/utils/serializers.py +4 -4
- reflex/utils/telemetry.py +42 -4
- reflex/utils/types.py +16 -13
- reflex/vars/base.py +96 -109
- reflex/vars/datetime.py +2 -1
- reflex/vars/dep_tracking.py +19 -28
- reflex/vars/number.py +6 -7
- reflex/vars/object.py +5 -6
- reflex/vars/sequence.py +11 -11
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a1.dist-info}/METADATA +1 -1
- reflex-0.7.14a1.dist-info/RECORD +407 -0
- reflex-0.7.13a2.dist-info/RECORD +0 -407
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a1.dist-info}/WHEEL +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a1.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a1.dist-info}/licenses/LICENSE +0 -0
reflex/utils/types.py
CHANGED
|
@@ -263,8 +263,12 @@ def is_classvar(a_type: Any) -> bool:
|
|
|
263
263
|
Returns:
|
|
264
264
|
Whether the type is a ClassVar.
|
|
265
265
|
"""
|
|
266
|
-
return
|
|
267
|
-
|
|
266
|
+
return (
|
|
267
|
+
a_type is ClassVar
|
|
268
|
+
or (type(a_type) is _GenericAlias and a_type.__origin__ is ClassVar)
|
|
269
|
+
or (
|
|
270
|
+
type(a_type) is ForwardRef and a_type.__forward_arg__.startswith("ClassVar")
|
|
271
|
+
)
|
|
268
272
|
)
|
|
269
273
|
|
|
270
274
|
|
|
@@ -378,7 +382,7 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
|
|
|
378
382
|
if hasattr(cls, "__fields__") and name in cls.__fields__:
|
|
379
383
|
# pydantic models
|
|
380
384
|
return get_field_type(cls, name)
|
|
381
|
-
|
|
385
|
+
if isinstance(cls, type) and issubclass(cls, DeclarativeBase):
|
|
382
386
|
insp = sqlalchemy.inspect(cls)
|
|
383
387
|
if name in insp.columns:
|
|
384
388
|
# check for list types
|
|
@@ -410,8 +414,7 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
|
|
|
410
414
|
if isinstance(prop, Relationship):
|
|
411
415
|
type_ = prop.mapper.class_
|
|
412
416
|
# TODO: check for nullable?
|
|
413
|
-
|
|
414
|
-
return type_
|
|
417
|
+
return list[type_] if prop.uselist else type_ | None
|
|
415
418
|
if isinstance(attr, AssociationProxyInstance):
|
|
416
419
|
return list[
|
|
417
420
|
get_attribute_access_type(
|
|
@@ -444,7 +447,6 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
|
|
|
444
447
|
return hints[name]
|
|
445
448
|
except exceptions as e:
|
|
446
449
|
console.warn(f"Failed to resolve ForwardRefs for {cls}.{name} due to {e}")
|
|
447
|
-
pass
|
|
448
450
|
return None # Attribute is not accessible.
|
|
449
451
|
|
|
450
452
|
|
|
@@ -465,7 +467,8 @@ def get_base_class(cls: GenericType) -> type:
|
|
|
465
467
|
# only literals of the same type are supported.
|
|
466
468
|
arg_type = type(get_args(cls)[0])
|
|
467
469
|
if not all(type(arg) is arg_type for arg in get_args(cls)):
|
|
468
|
-
|
|
470
|
+
msg = "only literals of the same type are supported"
|
|
471
|
+
raise TypeError(msg)
|
|
469
472
|
return type(get_args(cls)[0])
|
|
470
473
|
|
|
471
474
|
if is_union(cls):
|
|
@@ -493,13 +496,13 @@ def _breakpoints_satisfies_typing(cls_check: GenericType, instance: Any) -> bool
|
|
|
493
496
|
if not isinstance(value, str) or value not in get_args(expected_type):
|
|
494
497
|
return False
|
|
495
498
|
return True
|
|
496
|
-
|
|
499
|
+
if isinstance(cls_check_base, tuple):
|
|
497
500
|
# union type, so check all types
|
|
498
501
|
return any(
|
|
499
502
|
_breakpoints_satisfies_typing(type_to_check, instance)
|
|
500
503
|
for type_to_check in get_args(cls_check)
|
|
501
504
|
)
|
|
502
|
-
|
|
505
|
+
if cls_check_base == reflex.vars.Var and "__args__" in cls_check.__dict__:
|
|
503
506
|
return _breakpoints_satisfies_typing(get_args(cls_check)[0], instance)
|
|
504
507
|
|
|
505
508
|
return False
|
|
@@ -551,7 +554,8 @@ def _issubclass(cls: GenericType, cls_check: GenericType, instance: Any = None)
|
|
|
551
554
|
except TypeError as te:
|
|
552
555
|
# These errors typically arise from bad annotations and are hard to
|
|
553
556
|
# debug without knowing the type that we tried to compare.
|
|
554
|
-
|
|
557
|
+
msg = f"Invalid type for issubclass: {cls_base}"
|
|
558
|
+
raise TypeError(msg) from te
|
|
555
559
|
|
|
556
560
|
|
|
557
561
|
def does_obj_satisfy_typed_dict(obj: Any, cls: GenericType) -> bool:
|
|
@@ -909,9 +913,8 @@ def validate_literal(key: str, value: Any, expected_type: type, comp_name: str):
|
|
|
909
913
|
[str(v) if not isinstance(v, str) else f"'{v}'" for v in allowed_values]
|
|
910
914
|
)
|
|
911
915
|
value_str = f"'{value}'" if isinstance(value, str) else value
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
)
|
|
916
|
+
msg = f"prop value for {key!s} of the `{comp_name}` component should be one of the following: {allowed_value_str}. Got {value_str} instead"
|
|
917
|
+
raise ValueError(msg)
|
|
915
918
|
|
|
916
919
|
|
|
917
920
|
def validate_parameter_literals(func: Callable):
|
reflex/vars/base.py
CHANGED
|
@@ -247,9 +247,8 @@ class VarData:
|
|
|
247
247
|
)
|
|
248
248
|
if positions:
|
|
249
249
|
if len(positions) > 1:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
)
|
|
250
|
+
msg = f"Cannot merge var data with different positions: {positions}"
|
|
251
|
+
raise exceptions.ReflexError(msg)
|
|
253
252
|
position = positions[0]
|
|
254
253
|
else:
|
|
255
254
|
position = None
|
|
@@ -511,14 +510,12 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
511
510
|
TypeError: If _js_expr is not a string.
|
|
512
511
|
"""
|
|
513
512
|
if not isinstance(self._js_expr, str):
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
)
|
|
513
|
+
msg = f"Expected _js_expr to be a string, got value {self._js_expr!r} of type {type(self._js_expr).__name__}"
|
|
514
|
+
raise TypeError(msg)
|
|
517
515
|
|
|
518
516
|
if self._var_data is not None and not isinstance(self._var_data, VarData):
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
)
|
|
517
|
+
msg = f"Expected _var_data to be a VarData, got value {self._var_data!r} of type {type(self._var_data).__name__}"
|
|
518
|
+
raise TypeError(msg)
|
|
522
519
|
|
|
523
520
|
# Decode any inline Var markup and apply it to the instance
|
|
524
521
|
_var_data, _js_expr = _decode_var_immutable(self._js_expr)
|
|
@@ -597,15 +594,16 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
597
594
|
TypeError: If _var_is_local, _var_is_string, or _var_full_name_needs_state_prefix is not None.
|
|
598
595
|
"""
|
|
599
596
|
if kwargs.get("_var_is_local", False) is not False:
|
|
600
|
-
|
|
597
|
+
msg = "The _var_is_local argument is not supported for Var."
|
|
598
|
+
raise TypeError(msg)
|
|
601
599
|
|
|
602
600
|
if kwargs.get("_var_is_string", False) is not False:
|
|
603
|
-
|
|
601
|
+
msg = "The _var_is_string argument is not supported for Var."
|
|
602
|
+
raise TypeError(msg)
|
|
604
603
|
|
|
605
604
|
if kwargs.get("_var_full_name_needs_state_prefix", False) is not False:
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
)
|
|
605
|
+
msg = "The _var_full_name_needs_state_prefix argument is not supported for Var."
|
|
606
|
+
raise TypeError(msg)
|
|
609
607
|
value_with_replaced = dataclasses.replace(
|
|
610
608
|
self,
|
|
611
609
|
_var_type=_var_type or self._var_type,
|
|
@@ -850,10 +848,9 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
850
848
|
new_var_type = var_type
|
|
851
849
|
else:
|
|
852
850
|
new_var_type = var_type or current_var_type
|
|
853
|
-
|
|
851
|
+
return var_subclass.to_var_subclass.create( # pyright: ignore [reportReturnType]
|
|
854
852
|
value=self, _var_type=new_var_type
|
|
855
853
|
)
|
|
856
|
-
return to_operation_return # pyright: ignore [reportReturnType]
|
|
857
854
|
|
|
858
855
|
# If we can't determine the first argument, we just replace the _var_type.
|
|
859
856
|
if not safe_issubclass(output, Var) or var_type is None:
|
|
@@ -940,7 +937,8 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
940
937
|
fixed_type = unionize(*(type(arg) for arg in args))
|
|
941
938
|
|
|
942
939
|
if not inspect.isclass(fixed_type):
|
|
943
|
-
|
|
940
|
+
msg = f"Unsupported type {var_type} for guess_type."
|
|
941
|
+
raise TypeError(msg)
|
|
944
942
|
|
|
945
943
|
if fixed_type is None:
|
|
946
944
|
return self.to(None)
|
|
@@ -992,9 +990,8 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
992
990
|
|
|
993
991
|
return pd.DataFrame()
|
|
994
992
|
except ImportError as e:
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
) from e
|
|
993
|
+
msg = "Please install pandas to use dataframes in your app."
|
|
994
|
+
raise ImportError(msg) from e
|
|
998
995
|
return set() if safe_issubclass(type_, set) else None
|
|
999
996
|
|
|
1000
997
|
def _get_setter_name(self, include_state: bool = True) -> str:
|
|
@@ -1012,7 +1009,7 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
1012
1009
|
return setter
|
|
1013
1010
|
if not include_state or var_data.state == "":
|
|
1014
1011
|
return setter
|
|
1015
|
-
return
|
|
1012
|
+
return var_data.state + "." + setter
|
|
1016
1013
|
|
|
1017
1014
|
def _get_setter(self) -> Callable[[BaseState, Any], None]:
|
|
1018
1015
|
"""Get the var's setter function.
|
|
@@ -1348,9 +1345,8 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
1348
1345
|
self,
|
|
1349
1346
|
f"access the item '{key}'",
|
|
1350
1347
|
)
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
)
|
|
1348
|
+
msg = f"Var of type {self._var_type} does not support item access."
|
|
1349
|
+
raise TypeError(msg)
|
|
1354
1350
|
|
|
1355
1351
|
def __getattr__(self, name: str):
|
|
1356
1352
|
"""Get an attribute of the var.
|
|
@@ -1366,14 +1362,15 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
1366
1362
|
# noqa: DAR101 self
|
|
1367
1363
|
"""
|
|
1368
1364
|
if name.startswith("_"):
|
|
1369
|
-
|
|
1365
|
+
msg = f"Attribute {name} not found."
|
|
1366
|
+
raise VarAttributeError(msg)
|
|
1370
1367
|
|
|
1371
1368
|
if name == "contains":
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
)
|
|
1369
|
+
msg = f"Var of type {self._var_type} does not support contains check."
|
|
1370
|
+
raise TypeError(msg)
|
|
1375
1371
|
if name == "reverse":
|
|
1376
|
-
|
|
1372
|
+
msg = "Cannot reverse non-list var."
|
|
1373
|
+
raise TypeError(msg)
|
|
1377
1374
|
|
|
1378
1375
|
if self._var_type is Any:
|
|
1379
1376
|
raise exceptions.UntypedVarError(
|
|
@@ -1381,9 +1378,8 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
1381
1378
|
f"access the attribute '{name}'",
|
|
1382
1379
|
)
|
|
1383
1380
|
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
)
|
|
1381
|
+
msg = f"The State var {escape(self._js_expr)} of type {escape(str(self._var_type))} has no attribute '{name}' or may have been annotated wrongly."
|
|
1382
|
+
raise VarAttributeError(msg)
|
|
1387
1383
|
|
|
1388
1384
|
def __bool__(self) -> bool:
|
|
1389
1385
|
"""Raise exception if using Var in a boolean context.
|
|
@@ -1393,10 +1389,11 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
1393
1389
|
|
|
1394
1390
|
# noqa: DAR101 self
|
|
1395
1391
|
"""
|
|
1396
|
-
|
|
1392
|
+
msg = (
|
|
1397
1393
|
f"Cannot convert Var {str(self)!r} to bool for use with `if`, `and`, `or`, and `not`. "
|
|
1398
1394
|
"Instead use `rx.cond` and bitwise operators `&` (and), `|` (or), `~` (invert)."
|
|
1399
1395
|
)
|
|
1396
|
+
raise VarTypeError(msg)
|
|
1400
1397
|
|
|
1401
1398
|
def __iter__(self) -> Any:
|
|
1402
1399
|
"""Raise exception if using Var in an iterable context.
|
|
@@ -1406,9 +1403,8 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
1406
1403
|
|
|
1407
1404
|
# noqa: DAR101 self
|
|
1408
1405
|
"""
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
)
|
|
1406
|
+
msg = f"Cannot iterate over Var {str(self)!r}. Instead use `rx.foreach`."
|
|
1407
|
+
raise VarTypeError(msg)
|
|
1412
1408
|
|
|
1413
1409
|
def __contains__(self, _: Any) -> Var:
|
|
1414
1410
|
"""Override the 'in' operator to alert the user that it is not supported.
|
|
@@ -1418,9 +1414,10 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
|
|
|
1418
1414
|
|
|
1419
1415
|
# noqa: DAR101 self
|
|
1420
1416
|
"""
|
|
1421
|
-
|
|
1417
|
+
msg = (
|
|
1422
1418
|
"'in' operator not supported for Var types, use Var.contains() instead."
|
|
1423
1419
|
)
|
|
1420
|
+
raise VarTypeError(msg)
|
|
1424
1421
|
|
|
1425
1422
|
|
|
1426
1423
|
OUTPUT = TypeVar("OUTPUT", bound=Var)
|
|
@@ -1522,9 +1519,8 @@ class LiteralVar(Var):
|
|
|
1522
1519
|
]
|
|
1523
1520
|
|
|
1524
1521
|
if not possible_bases:
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
)
|
|
1522
|
+
msg = f"LiteralVar subclass {cls} must have a base class that is a subclass of Var and not LiteralVar."
|
|
1523
|
+
raise TypeError(msg)
|
|
1528
1524
|
|
|
1529
1525
|
var_subclasses = [
|
|
1530
1526
|
var_subclass
|
|
@@ -1533,14 +1529,12 @@ class LiteralVar(Var):
|
|
|
1533
1529
|
]
|
|
1534
1530
|
|
|
1535
1531
|
if not var_subclasses:
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
)
|
|
1532
|
+
msg = f"LiteralVar {cls} must have a base class annotated with `python_types`."
|
|
1533
|
+
raise TypeError(msg)
|
|
1539
1534
|
|
|
1540
1535
|
if len(var_subclasses) != 1:
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
)
|
|
1536
|
+
msg = f"LiteralVar {cls} must have exactly one base class annotated with `python_types`."
|
|
1537
|
+
raise TypeError(msg)
|
|
1544
1538
|
|
|
1545
1539
|
var_subclass = var_subclasses[0]
|
|
1546
1540
|
|
|
@@ -1630,9 +1624,8 @@ class LiteralVar(Var):
|
|
|
1630
1624
|
if isinstance(value, range):
|
|
1631
1625
|
return ArrayVar.range(value.start, value.stop, value.step)
|
|
1632
1626
|
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
)
|
|
1627
|
+
msg = f"Unsupported type {type(value)} for LiteralVar. Tried to create a LiteralVar from {value}."
|
|
1628
|
+
raise TypeError(msg)
|
|
1636
1629
|
|
|
1637
1630
|
if not TYPE_CHECKING:
|
|
1638
1631
|
create = _create_literal_var
|
|
@@ -1642,9 +1635,8 @@ class LiteralVar(Var):
|
|
|
1642
1635
|
|
|
1643
1636
|
@property
|
|
1644
1637
|
def _var_value(self) -> Any:
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
)
|
|
1638
|
+
msg = "LiteralVar subclasses must implement the _var_value property."
|
|
1639
|
+
raise NotImplementedError(msg)
|
|
1648
1640
|
|
|
1649
1641
|
def json(self) -> str:
|
|
1650
1642
|
"""Serialize the var to a JSON string.
|
|
@@ -1652,9 +1644,8 @@ class LiteralVar(Var):
|
|
|
1652
1644
|
Raises:
|
|
1653
1645
|
NotImplementedError: If the method is not implemented.
|
|
1654
1646
|
"""
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
)
|
|
1647
|
+
msg = "LiteralVar subclasses must implement the json method."
|
|
1648
|
+
raise NotImplementedError(msg)
|
|
1658
1649
|
|
|
1659
1650
|
|
|
1660
1651
|
@serializers.serializer
|
|
@@ -1881,10 +1872,11 @@ class cached_property: # noqa: N801
|
|
|
1881
1872
|
owner.__del__ = delete_property
|
|
1882
1873
|
|
|
1883
1874
|
elif name != self._attrname:
|
|
1884
|
-
|
|
1875
|
+
msg = (
|
|
1885
1876
|
"Cannot assign the same cached_property to two different names "
|
|
1886
1877
|
f"({self._attrname!r} and {name!r})."
|
|
1887
1878
|
)
|
|
1879
|
+
raise TypeError(msg)
|
|
1888
1880
|
|
|
1889
1881
|
def __get__(self, instance: Any, owner: type | None = None):
|
|
1890
1882
|
"""Get the cached property.
|
|
@@ -1900,9 +1892,8 @@ class cached_property: # noqa: N801
|
|
|
1900
1892
|
TypeError: If the class does not have __set_name__.
|
|
1901
1893
|
"""
|
|
1902
1894
|
if self._attrname is None:
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
)
|
|
1895
|
+
msg = "Cannot use cached_property on a class without __set_name__."
|
|
1896
|
+
raise TypeError(msg)
|
|
1906
1897
|
cached_field_name = "_reflex_cache_" + self._attrname
|
|
1907
1898
|
try:
|
|
1908
1899
|
unique_id = object.__getattribute__(instance, cached_field_name)
|
|
@@ -2164,7 +2155,8 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|
|
2164
2155
|
)
|
|
2165
2156
|
|
|
2166
2157
|
if kwargs:
|
|
2167
|
-
|
|
2158
|
+
msg = f"Unexpected keyword arguments: {tuple(kwargs)}"
|
|
2159
|
+
raise TypeError(msg)
|
|
2168
2160
|
|
|
2169
2161
|
if backend is None:
|
|
2170
2162
|
backend = fget.__name__.startswith("_")
|
|
@@ -2239,9 +2231,8 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|
|
2239
2231
|
elif isinstance(dep, str) and dep != "":
|
|
2240
2232
|
deps.setdefault(None, set()).add(dep)
|
|
2241
2233
|
else:
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
)
|
|
2234
|
+
msg = "ComputedVar dependencies must be Var instances or var names (non-empty strings)."
|
|
2235
|
+
raise TypeError(msg)
|
|
2245
2236
|
return deps
|
|
2246
2237
|
|
|
2247
2238
|
@override
|
|
@@ -2282,7 +2273,8 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|
|
2282
2273
|
|
|
2283
2274
|
if kwargs:
|
|
2284
2275
|
unexpected_kwargs = ", ".join(kwargs.keys())
|
|
2285
|
-
|
|
2276
|
+
msg = f"Unexpected keyword arguments: {unexpected_kwargs}"
|
|
2277
|
+
raise TypeError(msg)
|
|
2286
2278
|
|
|
2287
2279
|
return type(self)(**field_values)
|
|
2288
2280
|
|
|
@@ -2529,10 +2521,11 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|
|
2529
2521
|
(objclass.get_full_name(), self._js_expr)
|
|
2530
2522
|
)
|
|
2531
2523
|
return
|
|
2532
|
-
|
|
2524
|
+
msg = (
|
|
2533
2525
|
"ComputedVar dependencies must be Var instances with a state and "
|
|
2534
2526
|
f"field name, got {dep!r}."
|
|
2535
2527
|
)
|
|
2528
|
+
raise VarDependencyError(msg)
|
|
2536
2529
|
|
|
2537
2530
|
def _determine_var_type(self) -> type:
|
|
2538
2531
|
"""Get the type of the var.
|
|
@@ -2567,8 +2560,6 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|
|
2567
2560
|
class DynamicRouteVar(ComputedVar[str | list[str]]):
|
|
2568
2561
|
"""A ComputedVar that represents a dynamic route."""
|
|
2569
2562
|
|
|
2570
|
-
pass
|
|
2571
|
-
|
|
2572
2563
|
|
|
2573
2564
|
async def _default_async_computed_var(_self: BaseState) -> Any:
|
|
2574
2565
|
return None
|
|
@@ -2683,23 +2674,21 @@ class AsyncComputedVar(ComputedVar[RETURN_TYPE]):
|
|
|
2683
2674
|
return value
|
|
2684
2675
|
|
|
2685
2676
|
return _awaitable_result()
|
|
2686
|
-
else:
|
|
2687
|
-
# handle caching
|
|
2688
|
-
async def _awaitable_result(instance: BaseState = instance) -> RETURN_TYPE:
|
|
2689
|
-
if not hasattr(instance, self._cache_attr) or self.needs_update(
|
|
2690
|
-
instance
|
|
2691
|
-
):
|
|
2692
|
-
# Set cache attr on state instance.
|
|
2693
|
-
setattr(instance, self._cache_attr, await self.fget(instance))
|
|
2694
|
-
# Ensure the computed var gets serialized to redis.
|
|
2695
|
-
instance._was_touched = True
|
|
2696
|
-
# Set the last updated timestamp on the state instance.
|
|
2697
|
-
setattr(instance, self._last_updated_attr, datetime.datetime.now())
|
|
2698
|
-
value = getattr(instance, self._cache_attr)
|
|
2699
|
-
self._check_deprecated_return_type(instance, value)
|
|
2700
|
-
return value
|
|
2701
2677
|
|
|
2702
|
-
|
|
2678
|
+
# handle caching
|
|
2679
|
+
async def _awaitable_result(instance: BaseState = instance) -> RETURN_TYPE:
|
|
2680
|
+
if not hasattr(instance, self._cache_attr) or self.needs_update(instance):
|
|
2681
|
+
# Set cache attr on state instance.
|
|
2682
|
+
setattr(instance, self._cache_attr, await self.fget(instance))
|
|
2683
|
+
# Ensure the computed var gets serialized to redis.
|
|
2684
|
+
instance._was_touched = True
|
|
2685
|
+
# Set the last updated timestamp on the state instance.
|
|
2686
|
+
setattr(instance, self._last_updated_attr, datetime.datetime.now())
|
|
2687
|
+
value = getattr(instance, self._cache_attr)
|
|
2688
|
+
self._check_deprecated_return_type(instance, value)
|
|
2689
|
+
return value
|
|
2690
|
+
|
|
2691
|
+
return _awaitable_result()
|
|
2703
2692
|
|
|
2704
2693
|
@property
|
|
2705
2694
|
def fget(self) -> Callable[[BaseState], Coroutine[None, None, RETURN_TYPE]]:
|
|
@@ -2806,10 +2795,12 @@ def computed_var(
|
|
|
2806
2795
|
ComputedVarSignatureError: If the getter function has more than one argument.
|
|
2807
2796
|
"""
|
|
2808
2797
|
if cache is False and interval is not None:
|
|
2809
|
-
|
|
2798
|
+
msg = "Cannot set update interval without caching."
|
|
2799
|
+
raise ValueError(msg)
|
|
2810
2800
|
|
|
2811
2801
|
if cache is False and (deps is not None or auto_deps is False):
|
|
2812
|
-
|
|
2802
|
+
msg = "Cannot track dependencies without caching."
|
|
2803
|
+
raise VarDependencyError(msg)
|
|
2813
2804
|
|
|
2814
2805
|
if fget is not None:
|
|
2815
2806
|
sign = inspect.signature(fget)
|
|
@@ -3031,7 +3022,8 @@ def get_to_operation(var_subclass: type[Var]) -> type[ToOperation]:
|
|
|
3031
3022
|
if saved_var_subclass.var_subclass is var_subclass
|
|
3032
3023
|
]
|
|
3033
3024
|
if not possible_classes:
|
|
3034
|
-
|
|
3025
|
+
msg = f"Could not find ToOperation for {var_subclass}."
|
|
3026
|
+
raise ValueError(msg)
|
|
3035
3027
|
return possible_classes[0]
|
|
3036
3028
|
|
|
3037
3029
|
|
|
@@ -3172,21 +3164,20 @@ def transform(fn: Callable[[Var], Var]) -> Callable[[Var], Var]:
|
|
|
3172
3164
|
origin = get_origin(return_type)
|
|
3173
3165
|
|
|
3174
3166
|
if origin is not Var:
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
)
|
|
3167
|
+
msg = f"Expected return type of {fn.__name__} to be a Var, got {origin}."
|
|
3168
|
+
raise TypeError(msg)
|
|
3178
3169
|
|
|
3179
3170
|
generic_args = get_args(return_type)
|
|
3180
3171
|
|
|
3181
3172
|
if not generic_args:
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
)
|
|
3173
|
+
msg = f"Expected Var return type of {fn.__name__} to have a generic type."
|
|
3174
|
+
raise TypeError(msg)
|
|
3185
3175
|
|
|
3186
3176
|
generic_type = get_origin(generic_args[0]) or generic_args[0]
|
|
3187
3177
|
|
|
3188
3178
|
if generic_type in dispatchers:
|
|
3189
|
-
|
|
3179
|
+
msg = f"Function for {generic_type} already registered."
|
|
3180
|
+
raise ValueError(msg)
|
|
3190
3181
|
|
|
3191
3182
|
dispatchers[generic_type] = fn
|
|
3192
3183
|
|
|
@@ -3215,17 +3206,15 @@ def generic_type_to_actual_type_map(
|
|
|
3215
3206
|
if generic_origin is not actual_origin:
|
|
3216
3207
|
if isinstance(generic_origin, TypeVar):
|
|
3217
3208
|
return {generic_origin: actual_origin}
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
)
|
|
3209
|
+
msg = f"Type mismatch: expected {generic_origin}, got {actual_origin}."
|
|
3210
|
+
raise TypeError(msg)
|
|
3221
3211
|
|
|
3222
3212
|
generic_args = get_args(generic_type)
|
|
3223
3213
|
actual_args = get_args(actual_type)
|
|
3224
3214
|
|
|
3225
3215
|
if len(generic_args) != len(actual_args):
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
)
|
|
3216
|
+
msg = f"Number of generic arguments mismatch: expected {len(generic_args)}, got {len(actual_args)}."
|
|
3217
|
+
raise TypeError(msg)
|
|
3229
3218
|
|
|
3230
3219
|
# call recursively for nested generic types and merge the results
|
|
3231
3220
|
return {
|
|
@@ -3326,28 +3315,26 @@ def dispatch(
|
|
|
3326
3315
|
fn_return_origin = get_origin(fn_return) or fn_return
|
|
3327
3316
|
|
|
3328
3317
|
if fn_return_origin is not Var:
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
)
|
|
3318
|
+
msg = f"Expected return type of {fn.__name__} to be a Var, got {fn_return}."
|
|
3319
|
+
raise TypeError(msg)
|
|
3332
3320
|
|
|
3333
3321
|
fn_return_generic_args = get_args(fn_return)
|
|
3334
3322
|
|
|
3335
3323
|
if not fn_return_generic_args:
|
|
3336
|
-
|
|
3324
|
+
msg = f"Expected generic type of {fn_return} to be a type."
|
|
3325
|
+
raise TypeError(msg)
|
|
3337
3326
|
|
|
3338
3327
|
arg_origin = get_origin(fn_first_arg_type) or fn_first_arg_type
|
|
3339
3328
|
|
|
3340
3329
|
if arg_origin is not Var:
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
)
|
|
3330
|
+
msg = f"Expected first argument of {fn.__name__} to be a Var, got {fn_first_arg_type}."
|
|
3331
|
+
raise TypeError(msg)
|
|
3344
3332
|
|
|
3345
3333
|
arg_generic_args = get_args(fn_first_arg_type)
|
|
3346
3334
|
|
|
3347
3335
|
if not arg_generic_args:
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
)
|
|
3336
|
+
msg = f"Expected generic type of {fn_first_arg_type} to be a type."
|
|
3337
|
+
raise TypeError(msg)
|
|
3351
3338
|
|
|
3352
3339
|
arg_type = arg_generic_args[0]
|
|
3353
3340
|
fn_return_type = fn_return_generic_args[0]
|
reflex/vars/datetime.py
CHANGED
|
@@ -29,7 +29,8 @@ def raise_var_type_error():
|
|
|
29
29
|
Raises:
|
|
30
30
|
VarTypeError: Cannot compare a datetime object with a non-datetime object.
|
|
31
31
|
"""
|
|
32
|
-
|
|
32
|
+
msg = "Cannot compare a datetime object with a non-datetime object."
|
|
33
|
+
raise VarTypeError(msg)
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
|