reflex 0.6.0a1__py3-none-any.whl → 0.6.0a3__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.

Files changed (252) hide show
  1. reflex/.templates/jinja/custom_components/pyproject.toml.jinja2 +2 -2
  2. reflex/.templates/jinja/web/pages/_app.js.jinja2 +1 -1
  3. reflex/.templates/jinja/web/pages/utils.js.jinja2 +2 -2
  4. reflex/__init__.py +8 -2
  5. reflex/__init__.pyi +2 -1
  6. reflex/app.py +10 -4
  7. reflex/base.py +1 -1
  8. reflex/compiler/compiler.py +2 -2
  9. reflex/compiler/utils.py +3 -3
  10. reflex/components/base/app_wrap.py +2 -2
  11. reflex/components/base/app_wrap.pyi +17 -27
  12. reflex/components/base/bare.py +4 -5
  13. reflex/components/base/body.pyi +17 -27
  14. reflex/components/base/document.pyi +81 -131
  15. reflex/components/base/error_boundary.py +6 -7
  16. reflex/components/base/error_boundary.pyi +20 -33
  17. reflex/components/base/fragment.pyi +17 -27
  18. reflex/components/base/head.pyi +33 -53
  19. reflex/components/base/link.py +1 -1
  20. reflex/components/base/link.pyi +33 -54
  21. reflex/components/base/meta.pyi +65 -105
  22. reflex/components/base/script.py +1 -2
  23. reflex/components/base/script.pyi +21 -38
  24. reflex/components/component.py +45 -47
  25. reflex/components/core/banner.py +23 -27
  26. reflex/components/core/banner.pyi +134 -171
  27. reflex/components/core/breakpoints.py +3 -1
  28. reflex/components/core/client_side_routing.py +2 -3
  29. reflex/components/core/client_side_routing.pyi +33 -54
  30. reflex/components/core/clipboard.py +2 -1
  31. reflex/components/core/clipboard.pyi +20 -33
  32. reflex/components/core/cond.py +5 -5
  33. reflex/components/core/debounce.py +5 -5
  34. reflex/components/core/debounce.pyi +20 -33
  35. reflex/components/core/foreach.py +3 -4
  36. reflex/components/core/html.py +1 -1
  37. reflex/components/core/html.pyi +35 -46
  38. reflex/components/core/match.py +17 -17
  39. reflex/components/core/upload.py +17 -23
  40. reflex/components/core/upload.pyi +78 -124
  41. reflex/components/datadisplay/code.py +9 -10
  42. reflex/components/datadisplay/code.pyi +302 -412
  43. reflex/components/datadisplay/dataeditor.py +8 -10
  44. reflex/components/datadisplay/dataeditor.pyi +40 -53
  45. reflex/components/el/element.pyi +17 -27
  46. reflex/components/el/elements/base.py +1 -1
  47. reflex/components/el/elements/base.pyi +34 -45
  48. reflex/components/el/elements/forms.py +16 -16
  49. reflex/components/el/elements/forms.pyi +554 -707
  50. reflex/components/el/elements/inline.py +1 -1
  51. reflex/components/el/elements/inline.pyi +937 -1218
  52. reflex/components/el/elements/media.py +1 -1
  53. reflex/components/el/elements/media.pyi +786 -997
  54. reflex/components/el/elements/metadata.py +3 -6
  55. reflex/components/el/elements/metadata.pyi +181 -242
  56. reflex/components/el/elements/other.py +1 -1
  57. reflex/components/el/elements/other.pyi +235 -306
  58. reflex/components/el/elements/scripts.py +1 -1
  59. reflex/components/el/elements/scripts.pyi +109 -140
  60. reflex/components/el/elements/sectioning.py +0 -2
  61. reflex/components/el/elements/sectioning.pyi +496 -647
  62. reflex/components/el/elements/tables.py +1 -1
  63. reflex/components/el/elements/tables.pyi +351 -452
  64. reflex/components/el/elements/typography.py +1 -1
  65. reflex/components/el/elements/typography.pyi +506 -657
  66. reflex/components/gridjs/datatable.py +6 -9
  67. reflex/components/gridjs/datatable.pyi +35 -56
  68. reflex/components/lucide/icon.py +1 -1
  69. reflex/components/lucide/icon.pyi +33 -54
  70. reflex/components/markdown/markdown.py +26 -31
  71. reflex/components/markdown/markdown.pyi +27 -37
  72. reflex/components/moment/moment.py +13 -12
  73. reflex/components/moment/moment.pyi +23 -35
  74. reflex/components/next/base.pyi +17 -27
  75. reflex/components/next/image.py +1 -1
  76. reflex/components/next/image.pyi +22 -37
  77. reflex/components/next/link.py +1 -1
  78. reflex/components/next/link.pyi +17 -28
  79. reflex/components/next/video.py +1 -1
  80. reflex/components/next/video.pyi +17 -28
  81. reflex/components/plotly/plotly.py +12 -13
  82. reflex/components/plotly/plotly.pyi +39 -54
  83. reflex/components/props.py +1 -1
  84. reflex/components/radix/__init__.pyi +1 -0
  85. reflex/components/radix/primitives/__init__.pyi +1 -0
  86. reflex/components/radix/primitives/accordion.py +4 -4
  87. reflex/components/radix/primitives/accordion.pyi +424 -495
  88. reflex/components/radix/primitives/base.py +1 -1
  89. reflex/components/radix/primitives/base.pyi +33 -54
  90. reflex/components/radix/primitives/drawer.py +1 -1
  91. reflex/components/radix/primitives/drawer.pyi +172 -273
  92. reflex/components/radix/primitives/form.py +1 -1
  93. reflex/components/radix/primitives/form.pyi +257 -364
  94. reflex/components/radix/primitives/progress.py +1 -1
  95. reflex/components/radix/primitives/progress.pyi +231 -282
  96. reflex/components/radix/primitives/slider.py +1 -1
  97. reflex/components/radix/primitives/slider.pyi +87 -138
  98. reflex/components/radix/themes/base.py +3 -24
  99. reflex/components/radix/themes/base.pyi +178 -250
  100. reflex/components/radix/themes/color_mode.py +5 -5
  101. reflex/components/radix/themes/color_mode.pyi +187 -220
  102. reflex/components/radix/themes/components/alert_dialog.py +1 -1
  103. reflex/components/radix/themes/components/alert_dialog.pyi +136 -207
  104. reflex/components/radix/themes/components/aspect_ratio.py +1 -1
  105. reflex/components/radix/themes/components/aspect_ratio.pyi +17 -28
  106. reflex/components/radix/themes/components/avatar.py +1 -1
  107. reflex/components/radix/themes/components/avatar.pyi +70 -81
  108. reflex/components/radix/themes/components/badge.py +1 -1
  109. reflex/components/radix/themes/components/badge.pyi +88 -99
  110. reflex/components/radix/themes/components/button.py +1 -1
  111. reflex/components/radix/themes/components/button.pyi +98 -109
  112. reflex/components/radix/themes/components/callout.py +1 -1
  113. reflex/components/radix/themes/components/callout.pyi +322 -373
  114. reflex/components/radix/themes/components/card.py +1 -1
  115. reflex/components/radix/themes/components/card.pyi +38 -49
  116. reflex/components/radix/themes/components/checkbox.py +1 -2
  117. reflex/components/radix/themes/components/checkbox.pyi +208 -245
  118. reflex/components/radix/themes/components/checkbox_cards.py +1 -1
  119. reflex/components/radix/themes/components/checkbox_cards.pyi +94 -115
  120. reflex/components/radix/themes/components/checkbox_group.py +1 -1
  121. reflex/components/radix/themes/components/checkbox_group.pyi +86 -107
  122. reflex/components/radix/themes/components/context_menu.py +1 -1
  123. reflex/components/radix/themes/components/context_menu.pyi +238 -319
  124. reflex/components/radix/themes/components/data_list.py +1 -1
  125. reflex/components/radix/themes/components/data_list.pyi +130 -171
  126. reflex/components/radix/themes/components/dialog.py +1 -1
  127. reflex/components/radix/themes/components/dialog.pyi +139 -210
  128. reflex/components/radix/themes/components/dropdown_menu.py +1 -1
  129. reflex/components/radix/themes/components/dropdown_menu.pyi +249 -332
  130. reflex/components/radix/themes/components/hover_card.py +1 -1
  131. reflex/components/radix/themes/components/hover_card.pyi +90 -131
  132. reflex/components/radix/themes/components/icon_button.py +2 -3
  133. reflex/components/radix/themes/components/icon_button.pyi +98 -109
  134. reflex/components/radix/themes/components/inset.py +1 -1
  135. reflex/components/radix/themes/components/inset.pyi +47 -58
  136. reflex/components/radix/themes/components/popover.py +1 -1
  137. reflex/components/radix/themes/components/popover.pyi +95 -136
  138. reflex/components/radix/themes/components/progress.py +1 -1
  139. reflex/components/radix/themes/components/progress.pyi +71 -82
  140. reflex/components/radix/themes/components/radio.py +1 -1
  141. reflex/components/radix/themes/components/radio.pyi +69 -80
  142. reflex/components/radix/themes/components/radio_cards.py +1 -1
  143. reflex/components/radix/themes/components/radio_cards.pyi +98 -119
  144. reflex/components/radix/themes/components/radio_group.py +8 -11
  145. reflex/components/radix/themes/components/radio_group.pyi +228 -271
  146. reflex/components/radix/themes/components/scroll_area.py +1 -1
  147. reflex/components/radix/themes/components/scroll_area.pyi +21 -32
  148. reflex/components/radix/themes/components/segmented_control.py +1 -1
  149. reflex/components/radix/themes/components/segmented_control.pyi +90 -113
  150. reflex/components/radix/themes/components/select.py +2 -3
  151. reflex/components/radix/themes/components/select.pyi +374 -471
  152. reflex/components/radix/themes/components/separator.py +1 -2
  153. reflex/components/radix/themes/components/separator.pyi +69 -80
  154. reflex/components/radix/themes/components/skeleton.py +1 -1
  155. reflex/components/radix/themes/components/skeleton.pyi +23 -34
  156. reflex/components/radix/themes/components/slider.py +2 -3
  157. reflex/components/radix/themes/components/slider.pyi +75 -88
  158. reflex/components/radix/themes/components/spinner.py +1 -1
  159. reflex/components/radix/themes/components/spinner.pyi +19 -30
  160. reflex/components/radix/themes/components/switch.py +1 -1
  161. reflex/components/radix/themes/components/switch.pyi +71 -84
  162. reflex/components/radix/themes/components/table.py +1 -1
  163. reflex/components/radix/themes/components/table.pyi +261 -332
  164. reflex/components/radix/themes/components/tabs.py +1 -1
  165. reflex/components/radix/themes/components/tabs.pyi +139 -194
  166. reflex/components/radix/themes/components/text_area.py +1 -1
  167. reflex/components/radix/themes/components/text_area.pyi +96 -111
  168. reflex/components/radix/themes/components/text_field.py +1 -1
  169. reflex/components/radix/themes/components/text_field.pyi +247 -286
  170. reflex/components/radix/themes/components/tooltip.py +1 -1
  171. reflex/components/radix/themes/components/tooltip.pyi +26 -37
  172. reflex/components/radix/themes/layout/__init__.pyi +1 -0
  173. reflex/components/radix/themes/layout/base.py +1 -1
  174. reflex/components/radix/themes/layout/base.pyi +56 -67
  175. reflex/components/radix/themes/layout/box.pyi +34 -45
  176. reflex/components/radix/themes/layout/center.pyi +56 -67
  177. reflex/components/radix/themes/layout/container.py +1 -2
  178. reflex/components/radix/themes/layout/container.pyi +36 -47
  179. reflex/components/radix/themes/layout/flex.py +1 -1
  180. reflex/components/radix/themes/layout/flex.pyi +56 -67
  181. reflex/components/radix/themes/layout/grid.py +1 -1
  182. reflex/components/radix/themes/layout/grid.pyi +64 -75
  183. reflex/components/radix/themes/layout/list.py +5 -6
  184. reflex/components/radix/themes/layout/list.pyi +193 -244
  185. reflex/components/radix/themes/layout/section.py +1 -2
  186. reflex/components/radix/themes/layout/section.pyi +36 -47
  187. reflex/components/radix/themes/layout/spacer.pyi +56 -67
  188. reflex/components/radix/themes/layout/stack.py +1 -1
  189. reflex/components/radix/themes/layout/stack.pyi +128 -159
  190. reflex/components/radix/themes/typography/blockquote.py +1 -1
  191. reflex/components/radix/themes/typography/blockquote.pyi +89 -100
  192. reflex/components/radix/themes/typography/code.py +1 -1
  193. reflex/components/radix/themes/typography/code.pyi +90 -101
  194. reflex/components/radix/themes/typography/heading.py +1 -1
  195. reflex/components/radix/themes/typography/heading.pyi +96 -107
  196. reflex/components/radix/themes/typography/link.py +1 -1
  197. reflex/components/radix/themes/typography/link.pyi +102 -113
  198. reflex/components/radix/themes/typography/text.py +1 -1
  199. reflex/components/radix/themes/typography/text.pyi +501 -572
  200. reflex/components/react_player/audio.pyi +33 -60
  201. reflex/components/react_player/react_player.py +1 -1
  202. reflex/components/react_player/react_player.pyi +33 -60
  203. reflex/components/react_player/video.pyi +33 -60
  204. reflex/components/recharts/cartesian.py +2 -3
  205. reflex/components/recharts/cartesian.pyi +678 -861
  206. reflex/components/recharts/charts.py +4 -5
  207. reflex/components/recharts/charts.pyi +252 -357
  208. reflex/components/recharts/general.py +1 -2
  209. reflex/components/recharts/general.pyi +180 -231
  210. reflex/components/recharts/polar.py +4 -5
  211. reflex/components/recharts/polar.pyi +144 -181
  212. reflex/components/recharts/recharts.pyi +33 -53
  213. reflex/components/sonner/toast.py +16 -17
  214. reflex/components/sonner/toast.pyi +36 -47
  215. reflex/components/suneditor/editor.py +2 -3
  216. reflex/components/suneditor/editor.pyi +55 -78
  217. reflex/components/tags/cond_tag.py +6 -4
  218. reflex/components/tags/iter_tag.py +28 -16
  219. reflex/components/tags/match_tag.py +6 -4
  220. reflex/components/tags/tag.py +40 -23
  221. reflex/custom_components/custom_components.py +3 -1
  222. reflex/event.py +115 -67
  223. reflex/experimental/client_state.py +18 -18
  224. reflex/experimental/hooks.py +16 -16
  225. reflex/experimental/layout.py +5 -5
  226. reflex/experimental/layout.pyi +136 -187
  227. reflex/middleware/hydrate_middleware.py +2 -0
  228. reflex/middleware/middleware.py +3 -3
  229. reflex/state.py +149 -82
  230. reflex/style.py +21 -22
  231. reflex/utils/exceptions.py +20 -0
  232. reflex/utils/format.py +54 -34
  233. reflex/utils/imports.py +16 -73
  234. reflex/utils/prerequisites.py +15 -8
  235. reflex/utils/pyi_generator.py +13 -8
  236. reflex/utils/serializers.py +12 -22
  237. reflex/utils/telemetry.py +3 -2
  238. reflex/utils/types.py +11 -6
  239. reflex/{ivars → vars}/__init__.py +6 -2
  240. reflex/{ivars → vars}/base.py +599 -216
  241. reflex/{ivars → vars}/function.py +15 -19
  242. reflex/{ivars → vars}/number.py +41 -20
  243. reflex/{ivars → vars}/object.py +28 -30
  244. reflex/{ivars → vars}/sequence.py +53 -42
  245. {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/METADATA +4 -6
  246. reflex-0.6.0a3.dist-info/RECORD +382 -0
  247. reflex/.templates/web/components/reflex/chakra_color_mode_provider.js +0 -36
  248. reflex/vars.py +0 -501
  249. reflex-0.6.0a1.dist-info/RECORD +0 -384
  250. {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/LICENSE +0 -0
  251. {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/WHEEL +0 -0
  252. {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/entry_points.txt +0 -0
reflex/utils/format.py CHANGED
@@ -10,7 +10,7 @@ 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
13
+ from reflex.utils.console import deprecate
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from reflex.components.component import ComponentStyle
@@ -298,9 +298,9 @@ def format_route(route: str, format_case=True) -> str:
298
298
 
299
299
 
300
300
  def format_match(
301
- cond: str | ImmutableVar,
302
- match_cases: List[List[ImmutableVar]],
303
- default: ImmutableVar,
301
+ cond: str | Var,
302
+ match_cases: List[List[Var]],
303
+ default: Var,
304
304
  ) -> str:
305
305
  """Format a match expression whose return type is a Var.
306
306
 
@@ -332,7 +332,7 @@ def format_match(
332
332
 
333
333
 
334
334
  def format_prop(
335
- prop: Union[ImmutableVar, EventChain, ComponentStyle, str],
335
+ prop: Union[Var, EventChain, ComponentStyle, str],
336
336
  ) -> Union[int, float, str]:
337
337
  """Format a prop.
338
338
 
@@ -348,12 +348,12 @@ def format_prop(
348
348
  """
349
349
  # import here to avoid circular import.
350
350
  from reflex.event import EventChain
351
- from reflex.ivars import ImmutableVar
352
351
  from reflex.utils import serializers
352
+ from reflex.vars import Var
353
353
 
354
354
  try:
355
355
  # Handle var props.
356
- if isinstance(prop, ImmutableVar):
356
+ if isinstance(prop, Var):
357
357
  return str(prop)
358
358
 
359
359
  # Handle event props.
@@ -406,26 +406,15 @@ def format_props(*single_props, **key_value_props) -> list[str]:
406
406
  The formatted props list.
407
407
  """
408
408
  # Format all the props.
409
- from reflex.ivars.base import ImmutableVar, LiteralVar
409
+ from reflex.vars.base import LiteralVar, Var
410
410
 
411
411
  return [
412
412
  (
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
- )
413
+ f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}"
418
414
  )
419
415
  for name, prop in sorted(key_value_props.items())
420
416
  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
- ]
417
+ ] + [(f"{str(LiteralVar.create(prop))}") for prop in single_props]
429
418
 
430
419
 
431
420
  def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
@@ -486,10 +475,10 @@ def format_event(event_spec: EventSpec) -> str:
486
475
  [
487
476
  ":".join(
488
477
  (
489
- name._var_name,
478
+ name._js_expr,
490
479
  (
491
480
  wrap(
492
- json.dumps(val._var_name).strip('"').replace("`", "\\`"),
481
+ json.dumps(val._js_expr).strip('"').replace("`", "\\`"),
493
482
  "`",
494
483
  )
495
484
  if val._var_is_string
@@ -511,7 +500,38 @@ def format_event(event_spec: EventSpec) -> str:
511
500
 
512
501
 
513
502
  if TYPE_CHECKING:
514
- from reflex.ivars import ImmutableVar
503
+ from reflex.vars import Var
504
+
505
+
506
+ def format_event_chain(
507
+ event_chain: EventChain | Var[EventChain],
508
+ event_arg: Var | None = None,
509
+ ) -> str:
510
+ """DEPRECATED: format an event chain as a javascript invocation.
511
+
512
+ Use str(rx.Var.create(event_chain)) instead.
513
+
514
+ Args:
515
+ event_chain: The event chain to format.
516
+ event_arg: this argument is ignored.
517
+
518
+ Returns:
519
+ Compiled javascript code to queue the given event chain on the frontend.
520
+ """
521
+ deprecate(
522
+ feature_name="format_event_chain",
523
+ reason="Use str(rx.Var.create(event_chain)) instead",
524
+ deprecation_version="0.6.0",
525
+ removal_version="0.7.0",
526
+ )
527
+
528
+ from reflex.vars import Var
529
+ from reflex.vars.function import ArgsFunctionOperation
530
+
531
+ result = Var.create(event_chain)
532
+ if isinstance(result, ArgsFunctionOperation):
533
+ result = result._return_expr
534
+ return str(result)
515
535
 
516
536
 
517
537
  def format_queue_events(
@@ -523,7 +543,7 @@ def format_queue_events(
523
543
  | None
524
544
  ) = None,
525
545
  args_spec: Optional[ArgsSpec] = None,
526
- ) -> ImmutableVar[EventChain]:
546
+ ) -> Var[EventChain]:
527
547
  """Format a list of event handler / event spec as a javascript callback.
528
548
 
529
549
  The resulting code can be passed to interfaces that expect a callback
@@ -549,10 +569,10 @@ def format_queue_events(
549
569
  call_event_fn,
550
570
  call_event_handler,
551
571
  )
552
- from reflex.ivars import FunctionVar, ImmutableVar
572
+ from reflex.vars import FunctionVar, Var
553
573
 
554
574
  if not events:
555
- return ImmutableVar("(() => null)").to(FunctionVar, EventChain) # type: ignore
575
+ return Var("(() => null)").to(FunctionVar, EventChain) # type: ignore
556
576
 
557
577
  # If no spec is provided, the function will take no arguments.
558
578
  def _default_args_spec():
@@ -577,7 +597,7 @@ def format_queue_events(
577
597
  specs = [call_event_handler(spec, args_spec or _default_args_spec)]
578
598
  elif isinstance(spec, type(lambda: None)):
579
599
  specs = call_event_fn(spec, args_spec or _default_args_spec) # type: ignore
580
- if isinstance(specs, ImmutableVar):
600
+ if isinstance(specs, Var):
581
601
  raise ValueError(
582
602
  f"Invalid event spec: {specs}. Expected a list of EventSpecs."
583
603
  )
@@ -585,7 +605,7 @@ def format_queue_events(
585
605
 
586
606
  # Return the final code snippet, expecting queueEvents, processEvent, and socket to be in scope.
587
607
  # Typically this snippet will _only_ run from within an rx.call_script eval context.
588
- return ImmutableVar(
608
+ return Var(
589
609
  f"{arg_def} => {{queueEvents([{','.join(payloads)}], {constants.CompileVars.SOCKET}); "
590
610
  f"processEvent({constants.CompileVars.SOCKET})}}",
591
611
  ).to(FunctionVar, EventChain) # type: ignore
@@ -727,7 +747,7 @@ def collect_form_dict_names(form_dict: dict[str, Any]) -> dict[str, Any]:
727
747
  return collapsed
728
748
 
729
749
 
730
- def format_array_ref(refs: str, idx: ImmutableVar | None) -> str:
750
+ def format_array_ref(refs: str, idx: Var | None) -> str:
731
751
  """Format a ref accessed by array.
732
752
 
733
753
  Args:
@@ -756,7 +776,7 @@ def format_data_editor_column(col: str | dict):
756
776
  Returns:
757
777
  The formatted column.
758
778
  """
759
- from reflex.ivars import ImmutableVar
779
+ from reflex.vars import Var
760
780
 
761
781
  if isinstance(col, str):
762
782
  return {"title": col, "id": col.lower(), "type": "str"}
@@ -770,7 +790,7 @@ def format_data_editor_column(col: str | dict):
770
790
  col["overlayIcon"] = None
771
791
  return col
772
792
 
773
- if isinstance(col, ImmutableVar):
793
+ if isinstance(col, Var):
774
794
  return col
775
795
 
776
796
  raise ValueError(
@@ -787,9 +807,9 @@ def format_data_editor_cell(cell: Any):
787
807
  Returns:
788
808
  The formatted cell.
789
809
  """
790
- from reflex.ivars.base import ImmutableVar
810
+ from reflex.vars.base import Var
791
811
 
792
812
  return {
793
- "kind": ImmutableVar.create("GridCellKind.Text"),
813
+ "kind": Var(_js_expr="GridCellKind.Text"),
794
814
  "data": cell,
795
815
  }
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
- all_imports[lib].extend(fields)
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
- class ImportVar(Base):
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]
@@ -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
- class Template(Base):
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
- class CpuInfo(Base):
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
- return {
1281
- tp["name"]: Template.parse_obj(tp)
1282
- for tp in templates_data
1283
- if not tp["hidden"] and tp["code_url"] is not None
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):
@@ -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.ivars.base": ["ImmutableVar"],
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
- [repr(arg) for arg in args]
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, ImmutableVar):
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, ImmutableVar]]"
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
- + (" # type: ignore" if mod in pyright_ignore_imports else "")
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("")
@@ -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]) -> str:
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
- from reflex.utils import format
238
-
239
- return format.json_dumps(value)
240
+ return value
240
241
 
241
242
 
242
243
  @serializer
243
- def serialize_base(value: Base) -> str:
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
- from reflex.ivars import LiteralObjectVar
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]) -> str:
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
- from reflex.ivars import LiteralArrayVar
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]) -> str:
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
- from reflex.ivars import LiteralObjectVar
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
@@ -120,7 +121,7 @@ def _prepare_event(event: str, **kwargs) -> dict:
120
121
  return {}
121
122
 
122
123
  if UTC is None:
123
- # for python 3.8, 3.9 & 3.10
124
+ # for python 3.10
124
125
  stamp = datetime.utcnow().isoformat()
125
126
  else:
126
127
  # for python 3.11 & 3.12
@@ -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": dict(cpuinfo) if cpuinfo else {},
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[[ImmutableVar], list[ImmutableVar]]
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 _issubclass(type_, StateVar) or serializers.has_serializer(type_)
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.ivars.base import is_computed_var
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.ivars import ImmutableVar
598
+ from reflex.vars import Var
594
599
 
595
600
  if (
596
601
  is_literal(expected_type)
597
- and not isinstance(value, ImmutableVar) # validating vars is not supported yet.
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
  ):
@@ -627,7 +632,7 @@ def validate_parameter_literals(func):
627
632
  annotations = {param[0]: param[1].annotation for param in func_params}
628
633
 
629
634
  # validate args
630
- for param, arg in zip(annotations, args):
635
+ for param, arg in zip(annotations, args, strict=False):
631
636
  if annotations[param] is inspect.Parameter.empty:
632
637
  continue
633
638
  validate_literal(param, arg, annotations[param], func.__name__)
@@ -1,8 +1,12 @@
1
- """Experimental Immutable-Based Var System."""
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