reflex 0.7.13a2__py3-none-any.whl → 0.7.14a2__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 +49 -41
- 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 +14 -15
- reflex/components/el/elements/forms.pyi +15 -32
- 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 +2 -4
- 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 +20 -2
- 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.14a2.dist-info}/METADATA +1 -1
- reflex-0.7.14a2.dist-info/RECORD +407 -0
- reflex-0.7.13a2.dist-info/RECORD +0 -407
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/WHEEL +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/licenses/LICENSE +0 -0
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)):
|
reflex/vars/dep_tracking.py
CHANGED
|
@@ -73,7 +73,7 @@ class DependencyTracker:
|
|
|
73
73
|
self.func = cast(FunctionType, self.func.func) # pyright: ignore[reportAttributeAccessIssue]
|
|
74
74
|
with contextlib.suppress(AttributeError):
|
|
75
75
|
# unbox EventHandler
|
|
76
|
-
self.func = cast(FunctionType, self.func.fn) # pyright: ignore[reportAttributeAccessIssue]
|
|
76
|
+
self.func = cast(FunctionType, self.func.fn) # pyright: ignore[reportAttributeAccessIssue,reportFunctionMemberAccess]
|
|
77
77
|
|
|
78
78
|
if isinstance(self.func, FunctionType):
|
|
79
79
|
with contextlib.suppress(AttributeError, IndexError):
|
|
@@ -106,9 +106,8 @@ class DependencyTracker:
|
|
|
106
106
|
from .base import ComputedVar
|
|
107
107
|
|
|
108
108
|
if instruction.argval in self.INVALID_NAMES:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
109
|
+
msg = f"Cached var {self!s} cannot access arbitrary state via `{instruction.argval}`."
|
|
110
|
+
raise VarValueError(msg)
|
|
112
111
|
if instruction.argval == "get_state":
|
|
113
112
|
# Special case: arbitrary state access requested.
|
|
114
113
|
self.scan_status = ScanStatus.GETTING_STATE
|
|
@@ -193,37 +192,32 @@ class DependencyTracker:
|
|
|
193
192
|
from reflex.state import BaseState
|
|
194
193
|
|
|
195
194
|
if instruction.opname == "LOAD_FAST":
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
)
|
|
195
|
+
msg = f"Dependency detection cannot identify get_state class from local var {instruction.argval}."
|
|
196
|
+
raise VarValueError(msg)
|
|
199
197
|
if isinstance(self.func, CodeType):
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
)
|
|
198
|
+
msg = "Dependency detection cannot identify get_state class from a code object."
|
|
199
|
+
raise VarValueError(msg)
|
|
203
200
|
if instruction.opname == "LOAD_GLOBAL":
|
|
204
201
|
# Special case: referencing state class from global scope.
|
|
205
202
|
try:
|
|
206
203
|
self._getting_state_class = self._get_globals()[instruction.argval]
|
|
207
204
|
except (ValueError, KeyError) as ve:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
) from ve
|
|
205
|
+
msg = f"Cached var {self!s} cannot access arbitrary state `{instruction.argval}`, not found in globals."
|
|
206
|
+
raise VarValueError(msg) from ve
|
|
211
207
|
elif instruction.opname == "LOAD_DEREF":
|
|
212
208
|
# Special case: referencing state class from closure.
|
|
213
209
|
try:
|
|
214
210
|
self._getting_state_class = self._get_closure()[instruction.argval]
|
|
215
211
|
except (ValueError, KeyError) as ve:
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
) from ve
|
|
212
|
+
msg = f"Cached var {self!s} cannot access arbitrary state `{instruction.argval}`, is it defined yet?"
|
|
213
|
+
raise VarValueError(msg) from ve
|
|
219
214
|
elif instruction.opname == "STORE_FAST":
|
|
220
215
|
# Storing the result of get_state in a local variable.
|
|
221
216
|
if not isinstance(self._getting_state_class, type) or not issubclass(
|
|
222
217
|
self._getting_state_class, BaseState
|
|
223
218
|
):
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
)
|
|
219
|
+
msg = f"Cached var {self!s} cannot determine dependencies in fetched state `{instruction.argval}`."
|
|
220
|
+
raise VarValueError(msg)
|
|
227
221
|
self.tracked_locals[instruction.argval] = self._getting_state_class
|
|
228
222
|
self.scan_status = ScanStatus.SCANNING
|
|
229
223
|
self._getting_state_class = None
|
|
@@ -242,9 +236,8 @@ class DependencyTracker:
|
|
|
242
236
|
positions0 = self._getting_var_instructions[0].positions
|
|
243
237
|
positions1 = self._getting_var_instructions[-1].positions
|
|
244
238
|
if module is None or positions0 is None or positions1 is None:
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
)
|
|
239
|
+
msg = f"Cannot determine the source code for the var in {self.func!r}."
|
|
240
|
+
raise VarValueError(msg)
|
|
248
241
|
start_line = positions0.lineno
|
|
249
242
|
start_column = positions0.col_offset
|
|
250
243
|
end_line = positions1.end_lineno
|
|
@@ -255,9 +248,8 @@ class DependencyTracker:
|
|
|
255
248
|
or end_line is None
|
|
256
249
|
or end_column is None
|
|
257
250
|
):
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
)
|
|
251
|
+
msg = f"Cannot determine the source code for the var in {self.func!r}."
|
|
252
|
+
raise VarValueError(msg)
|
|
261
253
|
source = inspect.getsource(module).splitlines(True)[start_line - 1 : end_line]
|
|
262
254
|
# Create a python source string snippet.
|
|
263
255
|
if len(source) > 1:
|
|
@@ -292,9 +284,8 @@ class DependencyTracker:
|
|
|
292
284
|
the_var = self._eval_var()
|
|
293
285
|
the_var_data = the_var._get_all_var_data()
|
|
294
286
|
if the_var_data is None:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
)
|
|
287
|
+
msg = f"Cannot determine the source code for the var in {self.func!r}."
|
|
288
|
+
raise VarValueError(msg)
|
|
298
289
|
self.dependencies.setdefault(the_var_data.state, set()).add(
|
|
299
290
|
the_var_data.field_name
|
|
300
291
|
)
|
reflex/vars/number.py
CHANGED
|
@@ -53,9 +53,8 @@ def raise_unsupported_operand_types(
|
|
|
53
53
|
Raises:
|
|
54
54
|
VarTypeError: The operand types are unsupported.
|
|
55
55
|
"""
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
56
|
+
msg = f"Unsupported Operand type(s) for {operator}: {', '.join(t.__name__ for t in operands_types)}"
|
|
57
|
+
raise VarTypeError(msg)
|
|
59
58
|
|
|
60
59
|
|
|
61
60
|
class NumberVar(Var[NUMBER_T], python_types=(int, float, decimal.Decimal)):
|
|
@@ -486,10 +485,11 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float, decimal.Decimal)):
|
|
|
486
485
|
)
|
|
487
486
|
|
|
488
487
|
if format_spec:
|
|
489
|
-
|
|
488
|
+
msg = (
|
|
490
489
|
f"Unknown format code '{format_spec}' for object of type 'NumberVar'. It is only supported to use ',', '_', and '.f' for float numbers."
|
|
491
490
|
"If possible, use computed variables instead: https://reflex.dev/docs/vars/computed-vars/"
|
|
492
491
|
)
|
|
492
|
+
raise VarValueError(msg)
|
|
493
493
|
|
|
494
494
|
return super().__format__(format_spec)
|
|
495
495
|
|
|
@@ -961,9 +961,8 @@ class LiteralNumberVar(LiteralVar, NumberVar[NUMBER_T]):
|
|
|
961
961
|
if isinstance(self._var_value, decimal.Decimal):
|
|
962
962
|
return json.dumps(float(self._var_value))
|
|
963
963
|
if math.isinf(self._var_value) or math.isnan(self._var_value):
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
)
|
|
964
|
+
msg = f"No valid JSON representation for {self}"
|
|
965
|
+
raise PrimitiveUnserializableToJSONError(msg)
|
|
967
966
|
return json.dumps(self._var_value)
|
|
968
967
|
|
|
969
968
|
def __hash__(self) -> int:
|
reflex/vars/object.py
CHANGED
|
@@ -333,13 +333,13 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
|
|
|
333
333
|
):
|
|
334
334
|
attribute_type = get_attribute_access_type(var_type, name)
|
|
335
335
|
if attribute_type is None:
|
|
336
|
-
|
|
336
|
+
msg = (
|
|
337
337
|
f"The State var `{self!s}` of type {escape(str(self._var_type))} has no attribute '{name}' or may have been annotated "
|
|
338
338
|
f"wrongly."
|
|
339
339
|
)
|
|
340
|
+
raise VarAttributeError(msg)
|
|
340
341
|
return ObjectItemOperation.create(self, name, attribute_type).guess_type()
|
|
341
|
-
|
|
342
|
-
return ObjectItemOperation.create(self, name).guess_type()
|
|
342
|
+
return ObjectItemOperation.create(self, name).guess_type()
|
|
343
343
|
|
|
344
344
|
def contains(self, key: Var | Any) -> BooleanVar:
|
|
345
345
|
"""Check if the object contains a key.
|
|
@@ -413,9 +413,8 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
|
|
413
413
|
key = LiteralVar.create(key)
|
|
414
414
|
value = LiteralVar.create(value)
|
|
415
415
|
if not isinstance(key, LiteralVar) or not isinstance(value, LiteralVar):
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
)
|
|
416
|
+
msg = "The keys and values of the object must be literal vars to get the JSON representation."
|
|
417
|
+
raise TypeError(msg)
|
|
419
418
|
keys_and_values.append(f"{key.json()}:{value.json()}")
|
|
420
419
|
return "{" + ", ".join(keys_and_values) + "}"
|
|
421
420
|
|