reflex 0.7.13a1__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.

Files changed (258) hide show
  1. reflex/.templates/apps/blank/code/blank.py +0 -2
  2. reflex/app.py +79 -72
  3. reflex/app_mixins/lifespan.py +2 -3
  4. reflex/app_mixins/middleware.py +1 -0
  5. reflex/app_mixins/mixin.py +0 -1
  6. reflex/assets.py +6 -3
  7. reflex/base.py +3 -2
  8. reflex/compiler/compiler.py +77 -64
  9. reflex/compiler/utils.py +8 -6
  10. reflex/components/base/app_wrap.pyi +0 -1
  11. reflex/components/base/bare.py +5 -7
  12. reflex/components/base/body.pyi +0 -1
  13. reflex/components/base/document.pyi +0 -5
  14. reflex/components/base/error_boundary.pyi +0 -1
  15. reflex/components/base/fragment.pyi +0 -1
  16. reflex/components/base/head.pyi +0 -2
  17. reflex/components/base/link.pyi +0 -2
  18. reflex/components/base/meta.py +2 -1
  19. reflex/components/base/meta.pyi +0 -4
  20. reflex/components/base/script.py +2 -1
  21. reflex/components/base/script.pyi +0 -1
  22. reflex/components/base/strict_mode.pyi +0 -1
  23. reflex/components/component.py +38 -40
  24. reflex/components/core/auto_scroll.pyi +0 -1
  25. reflex/components/core/banner.pyi +0 -6
  26. reflex/components/core/breakpoints.py +9 -11
  27. reflex/components/core/client_side_routing.pyi +0 -2
  28. reflex/components/core/clipboard.pyi +0 -1
  29. reflex/components/core/colors.py +10 -7
  30. reflex/components/core/cond.py +4 -2
  31. reflex/components/core/debounce.py +5 -3
  32. reflex/components/core/debounce.pyi +0 -1
  33. reflex/components/core/foreach.py +8 -6
  34. reflex/components/core/html.py +3 -3
  35. reflex/components/core/html.pyi +0 -1
  36. reflex/components/core/match.py +19 -17
  37. reflex/components/core/sticky.pyi +0 -4
  38. reflex/components/core/upload.pyi +0 -5
  39. reflex/components/datadisplay/code.py +1 -2
  40. reflex/components/datadisplay/code.pyi +0 -2
  41. reflex/components/datadisplay/dataeditor.py +7 -10
  42. reflex/components/datadisplay/dataeditor.pyi +0 -1
  43. reflex/components/datadisplay/logo.py +3 -4
  44. reflex/components/datadisplay/shiki_code_block.py +8 -11
  45. reflex/components/datadisplay/shiki_code_block.pyi +0 -3
  46. reflex/components/dynamic.py +2 -3
  47. reflex/components/el/__init__.pyi +2 -0
  48. reflex/components/el/element.pyi +0 -1
  49. reflex/components/el/elements/__init__.py +1 -0
  50. reflex/components/el/elements/__init__.pyi +3 -0
  51. reflex/components/el/elements/base.pyi +0 -1
  52. reflex/components/el/elements/forms.py +3 -4
  53. reflex/components/el/elements/forms.pyi +1 -18
  54. reflex/components/el/elements/inline.pyi +0 -28
  55. reflex/components/el/elements/media.py +26 -0
  56. reflex/components/el/elements/media.pyi +259 -25
  57. reflex/components/el/elements/metadata.py +0 -1
  58. reflex/components/el/elements/metadata.pyi +0 -6
  59. reflex/components/el/elements/other.pyi +0 -7
  60. reflex/components/el/elements/scripts.pyi +0 -3
  61. reflex/components/el/elements/sectioning.pyi +0 -15
  62. reflex/components/el/elements/tables.pyi +0 -10
  63. reflex/components/el/elements/typography.pyi +0 -15
  64. reflex/components/gridjs/datatable.py +10 -13
  65. reflex/components/gridjs/datatable.pyi +0 -2
  66. reflex/components/lucide/icon.py +10 -9
  67. reflex/components/lucide/icon.pyi +0 -3
  68. reflex/components/markdown/markdown.py +6 -8
  69. reflex/components/markdown/markdown.pyi +0 -1
  70. reflex/components/moment/moment.pyi +0 -1
  71. reflex/components/next/base.py +0 -2
  72. reflex/components/next/base.pyi +0 -3
  73. reflex/components/next/image.pyi +0 -1
  74. reflex/components/next/link.pyi +0 -1
  75. reflex/components/next/video.pyi +0 -1
  76. reflex/components/plotly/plotly.pyi +0 -9
  77. reflex/components/props.py +4 -3
  78. reflex/components/radix/primitives/accordion.py +1 -1
  79. reflex/components/radix/primitives/accordion.pyi +0 -7
  80. reflex/components/radix/primitives/base.py +1 -3
  81. reflex/components/radix/primitives/base.pyi +0 -2
  82. reflex/components/radix/primitives/drawer.py +1 -1
  83. reflex/components/radix/primitives/drawer.pyi +0 -11
  84. reflex/components/radix/primitives/form.py +5 -9
  85. reflex/components/radix/primitives/form.pyi +0 -12
  86. reflex/components/radix/primitives/progress.py +1 -1
  87. reflex/components/radix/primitives/progress.pyi +0 -5
  88. reflex/components/radix/primitives/slider.py +1 -1
  89. reflex/components/radix/primitives/slider.pyi +0 -5
  90. reflex/components/radix/themes/base.pyi +0 -8
  91. reflex/components/radix/themes/color_mode.pyi +0 -3
  92. reflex/components/radix/themes/components/alert_dialog.py +4 -2
  93. reflex/components/radix/themes/components/alert_dialog.pyi +4 -9
  94. reflex/components/radix/themes/components/aspect_ratio.py +1 -2
  95. reflex/components/radix/themes/components/aspect_ratio.pyi +1 -3
  96. reflex/components/radix/themes/components/avatar.py +5 -2
  97. reflex/components/radix/themes/components/avatar.pyi +1 -3
  98. reflex/components/radix/themes/components/badge.py +5 -2
  99. reflex/components/radix/themes/components/badge.pyi +1 -3
  100. reflex/components/radix/themes/components/button.py +2 -3
  101. reflex/components/radix/themes/components/button.pyi +1 -3
  102. reflex/components/radix/themes/components/callout.py +1 -2
  103. reflex/components/radix/themes/components/callout.pyi +1 -7
  104. reflex/components/radix/themes/components/card.py +1 -2
  105. reflex/components/radix/themes/components/card.pyi +1 -3
  106. reflex/components/radix/themes/components/checkbox.py +7 -4
  107. reflex/components/radix/themes/components/checkbox.pyi +1 -5
  108. reflex/components/radix/themes/components/checkbox_cards.py +1 -2
  109. reflex/components/radix/themes/components/checkbox_cards.pyi +1 -4
  110. reflex/components/radix/themes/components/checkbox_group.py +1 -2
  111. reflex/components/radix/themes/components/checkbox_group.pyi +1 -4
  112. reflex/components/radix/themes/components/context_menu.py +1 -1
  113. reflex/components/radix/themes/components/context_menu.pyi +1 -14
  114. reflex/components/radix/themes/components/data_list.py +1 -2
  115. reflex/components/radix/themes/components/data_list.pyi +1 -6
  116. reflex/components/radix/themes/components/dialog.py +4 -2
  117. reflex/components/radix/themes/components/dialog.pyi +4 -9
  118. reflex/components/radix/themes/components/dropdown_menu.py +5 -2
  119. reflex/components/radix/themes/components/dropdown_menu.pyi +4 -10
  120. reflex/components/radix/themes/components/hover_card.py +4 -2
  121. reflex/components/radix/themes/components/hover_card.pyi +4 -6
  122. reflex/components/radix/themes/components/icon_button.py +7 -8
  123. reflex/components/radix/themes/components/icon_button.pyi +1 -3
  124. reflex/components/radix/themes/components/inset.py +1 -2
  125. reflex/components/radix/themes/components/inset.pyi +1 -3
  126. reflex/components/radix/themes/components/popover.py +4 -2
  127. reflex/components/radix/themes/components/popover.pyi +4 -6
  128. reflex/components/radix/themes/components/progress.py +1 -2
  129. reflex/components/radix/themes/components/progress.pyi +1 -3
  130. reflex/components/radix/themes/components/radio.py +1 -2
  131. reflex/components/radix/themes/components/radio.pyi +1 -3
  132. reflex/components/radix/themes/components/radio_cards.py +1 -2
  133. reflex/components/radix/themes/components/radio_cards.pyi +1 -4
  134. reflex/components/radix/themes/components/radio_group.py +7 -5
  135. reflex/components/radix/themes/components/radio_group.pyi +1 -6
  136. reflex/components/radix/themes/components/scroll_area.py +1 -2
  137. reflex/components/radix/themes/components/scroll_area.pyi +1 -3
  138. reflex/components/radix/themes/components/segmented_control.py +1 -2
  139. reflex/components/radix/themes/components/segmented_control.pyi +1 -4
  140. reflex/components/radix/themes/components/select.py +5 -2
  141. reflex/components/radix/themes/components/select.pyi +1 -11
  142. reflex/components/radix/themes/components/separator.py +1 -2
  143. reflex/components/radix/themes/components/separator.pyi +1 -3
  144. reflex/components/radix/themes/components/skeleton.py +1 -2
  145. reflex/components/radix/themes/components/skeleton.pyi +1 -3
  146. reflex/components/radix/themes/components/slider.py +1 -2
  147. reflex/components/radix/themes/components/slider.pyi +1 -3
  148. reflex/components/radix/themes/components/spinner.py +1 -2
  149. reflex/components/radix/themes/components/spinner.pyi +1 -3
  150. reflex/components/radix/themes/components/switch.py +1 -2
  151. reflex/components/radix/themes/components/switch.pyi +1 -3
  152. reflex/components/radix/themes/components/table.py +1 -2
  153. reflex/components/radix/themes/components/table.pyi +1 -9
  154. reflex/components/radix/themes/components/tabs.py +1 -2
  155. reflex/components/radix/themes/components/tabs.pyi +1 -7
  156. reflex/components/radix/themes/components/text_area.py +5 -2
  157. reflex/components/radix/themes/components/text_area.pyi +1 -3
  158. reflex/components/radix/themes/components/text_field.py +5 -2
  159. reflex/components/radix/themes/components/text_field.pyi +1 -5
  160. reflex/components/radix/themes/components/tooltip.py +1 -2
  161. reflex/components/radix/themes/components/tooltip.pyi +1 -3
  162. reflex/components/radix/themes/layout/base.py +5 -2
  163. reflex/components/radix/themes/layout/base.pyi +5 -3
  164. reflex/components/radix/themes/layout/box.py +1 -2
  165. reflex/components/radix/themes/layout/box.pyi +1 -3
  166. reflex/components/radix/themes/layout/center.pyi +0 -1
  167. reflex/components/radix/themes/layout/container.py +1 -2
  168. reflex/components/radix/themes/layout/container.pyi +1 -3
  169. reflex/components/radix/themes/layout/flex.py +6 -2
  170. reflex/components/radix/themes/layout/flex.pyi +1 -3
  171. reflex/components/radix/themes/layout/grid.py +6 -2
  172. reflex/components/radix/themes/layout/grid.pyi +1 -3
  173. reflex/components/radix/themes/layout/list.py +2 -1
  174. reflex/components/radix/themes/layout/list.pyi +0 -5
  175. reflex/components/radix/themes/layout/section.py +1 -2
  176. reflex/components/radix/themes/layout/section.pyi +1 -3
  177. reflex/components/radix/themes/layout/spacer.pyi +0 -1
  178. reflex/components/radix/themes/layout/stack.py +1 -1
  179. reflex/components/radix/themes/layout/stack.pyi +0 -3
  180. reflex/components/radix/themes/typography/blockquote.py +1 -1
  181. reflex/components/radix/themes/typography/blockquote.pyi +1 -3
  182. reflex/components/radix/themes/typography/code.py +5 -1
  183. reflex/components/radix/themes/typography/code.pyi +1 -3
  184. reflex/components/radix/themes/typography/heading.py +1 -1
  185. reflex/components/radix/themes/typography/heading.pyi +1 -3
  186. reflex/components/radix/themes/typography/link.py +3 -2
  187. reflex/components/radix/themes/typography/link.pyi +1 -3
  188. reflex/components/radix/themes/typography/text.py +1 -1
  189. reflex/components/radix/themes/typography/text.pyi +1 -9
  190. reflex/components/react_player/audio.py +0 -2
  191. reflex/components/react_player/audio.pyi +0 -3
  192. reflex/components/react_player/react_player.pyi +0 -1
  193. reflex/components/react_player/video.py +0 -2
  194. reflex/components/react_player/video.pyi +0 -3
  195. reflex/components/recharts/__init__.py +1 -1
  196. reflex/components/recharts/__init__.pyi +1 -1
  197. reflex/components/recharts/cartesian.py +20 -25
  198. reflex/components/recharts/cartesian.pyi +20 -37
  199. reflex/components/recharts/charts.py +2 -1
  200. reflex/components/recharts/charts.pyi +0 -12
  201. reflex/components/recharts/general.pyi +0 -6
  202. reflex/components/recharts/polar.py +5 -4
  203. reflex/components/recharts/polar.pyi +4 -10
  204. reflex/components/recharts/recharts.py +12 -10
  205. reflex/components/recharts/recharts.pyi +10 -11
  206. reflex/components/sonner/toast.py +2 -2
  207. reflex/components/sonner/toast.pyi +0 -2
  208. reflex/components/suneditor/editor.py +2 -1
  209. reflex/components/suneditor/editor.pyi +0 -1
  210. reflex/components/tags/iter_tag.py +4 -2
  211. reflex/config.py +47 -35
  212. reflex/constants/base.py +3 -3
  213. reflex/constants/compiler.py +8 -6
  214. reflex/constants/installer.py +24 -15
  215. reflex/custom_components/custom_components.py +1 -2
  216. reflex/event.py +58 -60
  217. reflex/experimental/__init__.py +2 -2
  218. reflex/experimental/client_state.py +9 -4
  219. reflex/experimental/layout.pyi +0 -5
  220. reflex/istate/manager.py +15 -19
  221. reflex/istate/proxy.py +19 -12
  222. reflex/model.py +6 -4
  223. reflex/plugins/base.py +8 -0
  224. reflex/plugins/tailwind_v3.py +8 -0
  225. reflex/plugins/tailwind_v4.py +9 -0
  226. reflex/reflex.py +9 -11
  227. reflex/route.py +7 -9
  228. reflex/state.py +66 -70
  229. reflex/style.py +3 -1
  230. reflex/testing.py +46 -29
  231. reflex/utils/build.py +2 -1
  232. reflex/utils/console.py +9 -17
  233. reflex/utils/exec.py +9 -11
  234. reflex/utils/format.py +21 -24
  235. reflex/utils/imports.py +4 -3
  236. reflex/utils/lazy_loader.py +3 -3
  237. reflex/utils/misc.py +2 -1
  238. reflex/utils/net.py +2 -2
  239. reflex/utils/path_ops.py +2 -1
  240. reflex/utils/prerequisites.py +67 -38
  241. reflex/utils/processes.py +4 -6
  242. reflex/utils/pyi_generator.py +46 -41
  243. reflex/utils/redir.py +1 -1
  244. reflex/utils/serializers.py +4 -4
  245. reflex/utils/telemetry.py +42 -4
  246. reflex/utils/types.py +16 -13
  247. reflex/vars/base.py +96 -109
  248. reflex/vars/datetime.py +2 -1
  249. reflex/vars/dep_tracking.py +19 -28
  250. reflex/vars/number.py +6 -7
  251. reflex/vars/object.py +5 -6
  252. reflex/vars/sequence.py +11 -11
  253. {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/METADATA +1 -1
  254. reflex-0.7.14a1.dist-info/RECORD +407 -0
  255. reflex-0.7.13a1.dist-info/RECORD +0 -407
  256. {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/WHEEL +0 -0
  257. {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/entry_points.txt +0 -0
  258. {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/licenses/LICENSE +0 -0
reflex/event.py CHANGED
@@ -228,9 +228,8 @@ class EventHandler(EventActionsMixin):
228
228
  ),
229
229
  Unset,
230
230
  ):
231
- raise EventHandlerTypeError(
232
- f"Event handler {self.fn.__name__} received repeated argument {repeated_arg}."
233
- )
231
+ msg = f"Event handler {self.fn.__name__} received repeated argument {repeated_arg}."
232
+ raise EventHandlerTypeError(msg)
234
233
 
235
234
  if not isinstance(
236
235
  extra_arg := next(
@@ -238,9 +237,10 @@ class EventHandler(EventActionsMixin):
238
237
  ),
239
238
  Unset,
240
239
  ):
241
- raise EventHandlerTypeError(
240
+ msg = (
242
241
  f"Event handler {self.fn.__name__} received extra argument {extra_arg}."
243
242
  )
243
+ raise EventHandlerTypeError(msg)
244
244
 
245
245
  fn_args = fn_args[: len(args)] + list(kwargs)
246
246
 
@@ -257,9 +257,8 @@ class EventHandler(EventActionsMixin):
257
257
  try:
258
258
  values.append(LiteralVar.create(arg))
259
259
  except TypeError as e:
260
- raise EventHandlerTypeError(
261
- f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
262
- ) from e
260
+ msg = f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
261
+ raise EventHandlerTypeError(msg) from e
263
262
  payload = tuple(zip(fn_args, values, strict=False))
264
263
 
265
264
  # Return the event spec.
@@ -353,9 +352,8 @@ class EventSpec(EventActionsMixin):
353
352
  for arg in args:
354
353
  values.append(LiteralVar.create(value=arg)) # noqa: PERF401, RUF100
355
354
  except TypeError as e:
356
- raise EventHandlerTypeError(
357
- f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
358
- ) from e
355
+ msg = f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
356
+ raise EventHandlerTypeError(msg) from e
359
357
  new_payload = tuple(zip(fn_args, values, strict=False))
360
358
  return self.with_args(self.args + new_payload)
361
359
 
@@ -408,7 +406,8 @@ class CallableEventSpec(EventSpec):
408
406
  from reflex.utils.exceptions import EventHandlerTypeError
409
407
 
410
408
  if self.fn is None:
411
- raise EventHandlerTypeError("CallableEventSpec has no associated function.")
409
+ msg = "CallableEventSpec has no associated function."
410
+ raise EventHandlerTypeError(msg)
412
411
  return self.fn(*args, **kwargs)
413
412
 
414
413
 
@@ -453,7 +452,7 @@ class EventChain(EventActionsMixin):
453
452
  if isinstance(value, Var):
454
453
  if isinstance(value, EventChainVar):
455
454
  return value
456
- elif isinstance(value, EventVar):
455
+ if isinstance(value, EventVar):
457
456
  value = [value]
458
457
  elif safe_issubclass(value._var_type, (EventChain, EventSpec)):
459
458
  return cls.create(
@@ -463,9 +462,8 @@ class EventChain(EventActionsMixin):
463
462
  **event_chain_kwargs,
464
463
  )
465
464
  else:
466
- raise ValueError(
467
- f"Invalid event chain: {value!s} of type {value._var_type}"
468
- )
465
+ msg = f"Invalid event chain: {value!s} of type {value._var_type}"
466
+ raise ValueError(msg)
469
467
  elif isinstance(value, EventChain):
470
468
  # Trust that the caller knows what they're doing passing an EventChain directly
471
469
  return value
@@ -485,15 +483,17 @@ class EventChain(EventActionsMixin):
485
483
  # Call the lambda to get the event chain.
486
484
  result = call_event_fn(v, args_spec, key=key)
487
485
  if isinstance(result, Var):
488
- raise ValueError(
486
+ msg = (
489
487
  f"Invalid event chain: {v}. Cannot use a Var-returning "
490
488
  "lambda inside an EventChain list."
491
489
  )
490
+ raise ValueError(msg)
492
491
  events.extend(result)
493
492
  elif isinstance(v, EventVar):
494
493
  events.append(v)
495
494
  else:
496
- raise ValueError(f"Invalid event: {v}")
495
+ msg = f"Invalid event: {v}"
496
+ raise ValueError(msg)
497
497
 
498
498
  # If the input is a callable, create an event chain.
499
499
  elif isinstance(value, Callable):
@@ -507,7 +507,8 @@ class EventChain(EventActionsMixin):
507
507
 
508
508
  # Otherwise, raise an error.
509
509
  else:
510
- raise ValueError(f"Invalid event chain: {value}")
510
+ msg = f"Invalid event chain: {value}"
511
+ raise ValueError(msg)
511
512
 
512
513
  # Add args to the event specs if necessary.
513
514
  events = [
@@ -783,9 +784,11 @@ class FileUpload:
783
784
  on_upload_progress, self.on_upload_progress_args_spec
784
785
  )
785
786
  else:
786
- raise ValueError(f"{on_upload_progress} is not a valid event handler.")
787
+ msg = f"{on_upload_progress} is not a valid event handler."
788
+ raise ValueError(msg)
787
789
  if isinstance(events, Var):
788
- raise ValueError(f"{on_upload_progress} cannot return a var {events}.")
790
+ msg = f"{on_upload_progress} cannot return a var {events}."
791
+ raise ValueError(msg)
789
792
  on_upload_progress_chain = EventChain(
790
793
  events=[*events],
791
794
  args_spec=self.on_upload_progress_args_spec,
@@ -1081,7 +1084,8 @@ def download(
1081
1084
 
1082
1085
  if isinstance(url, str):
1083
1086
  if not url.startswith("/"):
1084
- raise ValueError("The URL argument should start with a /")
1087
+ msg = "The URL argument should start with a /"
1088
+ raise ValueError(msg)
1085
1089
 
1086
1090
  # if filename is not provided, infer it from url
1087
1091
  if filename is None:
@@ -1092,7 +1096,8 @@ def download(
1092
1096
 
1093
1097
  if data is not None:
1094
1098
  if url is not None:
1095
- raise ValueError("Cannot provide both URL and data to download.")
1099
+ msg = "Cannot provide both URL and data to download."
1100
+ raise ValueError(msg)
1096
1101
 
1097
1102
  if isinstance(data, str):
1098
1103
  # Caller provided a plain text string to download.
@@ -1115,9 +1120,8 @@ def download(
1115
1120
  b64_data = b64encode(data).decode("utf-8")
1116
1121
  url = "data:application/octet-stream;base64," + b64_data
1117
1122
  else:
1118
- raise ValueError(
1119
- f"Invalid data type {type(data)} for download. Use `str` or `bytes`."
1120
- )
1123
+ msg = f"Invalid data type {type(data)} for download. Use `str` or `bytes`."
1124
+ raise ValueError(msg)
1121
1125
 
1122
1126
  return server_side(
1123
1127
  "_download",
@@ -1323,23 +1327,21 @@ def _check_event_args_subclass_of_callback(
1323
1327
  except TypeError as te:
1324
1328
  callback_name_context = f" of {callback_name}" if callback_name else ""
1325
1329
  key_context = f" for {key}" if key else ""
1326
- raise TypeError(
1327
- f"Could not compare types {args_types_without_vars[i]} and {callback_param_name_to_type[arg]} for argument {arg}{callback_name_context}{key_context}."
1328
- ) from te
1330
+ msg = f"Could not compare types {args_types_without_vars[i]} and {callback_param_name_to_type[arg]} for argument {arg}{callback_name_context}{key_context}."
1331
+ raise TypeError(msg) from te
1329
1332
 
1330
1333
  if compare_result:
1331
1334
  type_match_found[arg] = True
1332
1335
  continue
1333
- else:
1334
- type_match_found[arg] = False
1335
- as_annotated_in = (
1336
- f" as annotated in {callback_name}" if callback_name else ""
1337
- )
1338
- delayed_exceptions.append(
1339
- EventHandlerArgTypeMismatchError(
1340
- f"Event handler {key} expects {args_types_without_vars[i]} for argument {arg} but got {callback_param_name_to_type[arg]}{as_annotated_in} instead."
1341
- )
1336
+ type_match_found[arg] = False
1337
+ as_annotated_in = (
1338
+ f" as annotated in {callback_name}" if callback_name else ""
1339
+ )
1340
+ delayed_exceptions.append(
1341
+ EventHandlerArgTypeMismatchError(
1342
+ f"Event handler {key} expects {args_types_without_vars[i]} for argument {arg} but got {callback_param_name_to_type[arg]}{as_annotated_in} instead."
1342
1343
  )
1344
+ )
1343
1345
 
1344
1346
  if all(type_match_found.values()):
1345
1347
  delayed_exceptions.clear()
@@ -1495,8 +1497,7 @@ def resolve_annotation(annotations: dict[str, Any], arg_name: str, spec: ArgsSpe
1495
1497
  if annotation is None:
1496
1498
  if not isinstance(spec, types.LambdaType):
1497
1499
  raise MissingAnnotationError(var_name=arg_name)
1498
- else:
1499
- return dict[str, dict]
1500
+ return dict[str, dict]
1500
1501
  return annotation
1501
1502
 
1502
1503
 
@@ -1570,12 +1571,13 @@ def check_fn_match_arg_spec(
1570
1571
  number_of_event_args = len(parsed_event_args)
1571
1572
 
1572
1573
  if number_of_user_args - number_of_user_default_args > number_of_event_args:
1573
- raise EventFnArgMismatchError(
1574
+ msg = (
1574
1575
  f"Event {key} only provides {number_of_event_args} arguments, but "
1575
1576
  f"{func_name or user_func} requires at least {number_of_user_args - number_of_user_default_args} "
1576
1577
  "arguments to be passed to the event handler.\n"
1577
1578
  "See https://reflex.dev/docs/events/event-arguments/"
1578
1579
  )
1580
+ raise EventFnArgMismatchError(msg)
1579
1581
 
1580
1582
 
1581
1583
  def call_event_fn(
@@ -1630,9 +1632,8 @@ def call_event_fn(
1630
1632
 
1631
1633
  # Make sure the event spec is valid.
1632
1634
  if not isinstance(e, EventSpec):
1633
- raise EventHandlerValueError(
1634
- f"Lambda {fn} returned an invalid event spec: {e}."
1635
- )
1635
+ msg = f"Lambda {fn} returned an invalid event spec: {e}."
1636
+ raise EventHandlerValueError(msg)
1636
1637
 
1637
1638
  # Add the event spec to the chain.
1638
1639
  events.append(e)
@@ -1696,7 +1697,8 @@ def fix_events(
1696
1697
  if isinstance(e, EventHandler):
1697
1698
  e = e()
1698
1699
  if not isinstance(e, EventSpec):
1699
- raise ValueError(f"Unexpected event type, {type(e)}.")
1700
+ msg = f"Unexpected event type, {type(e)}."
1701
+ raise ValueError(msg)
1700
1702
  name = format.format_event_handler(e.handler)
1701
1703
  payload = {k._js_expr: v._decode() for k, v in e.args}
1702
1704
 
@@ -1749,9 +1751,8 @@ class EventVar(ObjectVar, python_types=(EventSpec, EventHandler)):
1749
1751
  Raises:
1750
1752
  TypeError: EventVar cannot be converted to a boolean.
1751
1753
  """
1752
- raise TypeError(
1753
- f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
1754
- )
1754
+ msg = f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
1755
+ raise TypeError(msg)
1755
1756
 
1756
1757
 
1757
1758
  @dataclasses.dataclass(
@@ -1798,9 +1799,8 @@ class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
1798
1799
  try:
1799
1800
  value = call_event_handler(value, no_args)
1800
1801
  except EventFnArgMismatchError:
1801
- raise EventFnArgMismatchError(
1802
- f"Event handler {value.fn.__qualname__} used inside of a rx.cond() must not take any arguments."
1803
- ) from None
1802
+ msg = f"Event handler {value.fn.__qualname__} used inside of a rx.cond() must not take any arguments."
1803
+ raise EventFnArgMismatchError(msg) from None
1804
1804
 
1805
1805
  return cls(
1806
1806
  _js_expr="",
@@ -1835,9 +1835,8 @@ class EventChainVar(BuilderFunctionVar, python_types=EventChain):
1835
1835
  Raises:
1836
1836
  TypeError: EventChainVar cannot be converted to a boolean.
1837
1837
  """
1838
- raise TypeError(
1839
- f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
1840
- )
1838
+ msg = f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
1839
+ raise TypeError(msg)
1841
1840
 
1842
1841
 
1843
1842
  @dataclasses.dataclass(
@@ -1906,9 +1905,8 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
1906
1905
  invocation = value.invocation
1907
1906
 
1908
1907
  if invocation is not None and not isinstance(invocation, FunctionVar):
1909
- raise ValueError(
1910
- f"EventChain invocation must be a FunctionVar, got {invocation!s} of type {invocation._var_type!s}."
1911
- )
1908
+ msg = f"EventChain invocation must be a FunctionVar, got {invocation!s} of type {invocation._var_type!s}."
1909
+ raise ValueError(msg)
1912
1910
 
1913
1911
  return cls(
1914
1912
  _js_expr="",
@@ -2142,12 +2140,12 @@ class EventNamespace:
2142
2140
  if not inspect.iscoroutinefunction(
2143
2141
  func
2144
2142
  ) and not inspect.isasyncgenfunction(func):
2145
- raise TypeError(
2146
- "Background task must be async function or generator."
2147
- )
2143
+ msg = "Background task must be async function or generator."
2144
+ raise TypeError(msg)
2148
2145
  setattr(func, BACKGROUND_TASK_MARKER, True)
2149
2146
  if getattr(func, "__name__", "").startswith("_"):
2150
- raise ValueError("Event handlers cannot be private.")
2147
+ msg = "Event handlers cannot be private."
2148
+ raise ValueError(msg)
2151
2149
 
2152
2150
  qualname: str | None = getattr(func, "__qualname__", None)
2153
2151
 
@@ -6,9 +6,9 @@ from reflex.components.datadisplay.shiki_code_block import code_block as code_bl
6
6
  from reflex.components.props import PropsBase
7
7
  from reflex.components.radix.themes.components.progress import progress as progress
8
8
  from reflex.components.sonner.toast import toast as toast
9
+ from reflex.utils.console import warn
10
+ from reflex.utils.misc import run_in_thread
9
11
 
10
- from ..utils.console import warn
11
- from ..utils.misc import run_in_thread
12
12
  from . import hooks as hooks
13
13
  from .client_state import ClientStateVar as ClientStateVar
14
14
  from .layout import layout as layout
@@ -111,7 +111,8 @@ class ClientStateVar(Var):
111
111
  var_name = get_unique_variable_name()
112
112
  id_name = "id_" + get_unique_variable_name()
113
113
  if not isinstance(var_name, str):
114
- raise ValueError("var_name must be a string.")
114
+ msg = "var_name must be a string."
115
+ raise ValueError(msg)
115
116
  if default is NoValue:
116
117
  default_var = Var(_js_expr="")
117
118
  elif not isinstance(default, Var):
@@ -158,7 +159,9 @@ class ClientStateVar(Var):
158
159
  hooks[f"{_client_state_ref(var_name)} ??= {var_name!s}"] = None
159
160
  hooks[f"{_client_state_ref_dict(var_name)} ??= {{}}"] = None
160
161
  hooks[f"{_client_state_ref_dict(setter_name)} ??= {{}}"] = None
161
- hooks[f"{_client_state_ref_dict(var_name)}[{id_name}] = {var_name}"] = None
162
+ hooks[
163
+ f"{_client_state_ref_dict(var_name)}[{id_name}] = {_client_state_ref(var_name)}"
164
+ ] = None
162
165
  hooks[
163
166
  f"{_client_state_ref_dict(setter_name)}[{id_name}] = {setter_name}"
164
167
  ] = None
@@ -269,7 +272,8 @@ class ClientStateVar(Var):
269
272
  ValueError: If the ClientStateVar is not global.
270
273
  """
271
274
  if not self._global_ref:
272
- raise ValueError("ClientStateVar must be global to retrieve the value.")
275
+ msg = "ClientStateVar must be global to retrieve the value."
276
+ raise ValueError(msg)
273
277
  return run_script(_client_state_ref(self._getter_name), callback=callback)
274
278
 
275
279
  def push(self, value: Any) -> EventSpec:
@@ -287,6 +291,7 @@ class ClientStateVar(Var):
287
291
  ValueError: If the ClientStateVar is not global.
288
292
  """
289
293
  if not self._global_ref:
290
- raise ValueError("ClientStateVar must be global to push the value.")
294
+ msg = "ClientStateVar must be global to push the value."
295
+ raise ValueError(msg)
291
296
  value = Var.create(value)
292
297
  return run_script(f"{_client_state_ref(self._setter_name)}({value})")
@@ -237,7 +237,6 @@ class Sidebar(Box, MemoizationLeaf):
237
237
  Returns:
238
238
  The sidebar component.
239
239
  """
240
- ...
241
240
 
242
241
  def add_style(self) -> dict[str, Any] | None: ...
243
242
  def add_hooks(self) -> list[Var]: ...
@@ -309,7 +308,6 @@ class DrawerSidebar(DrawerRoot):
309
308
  Returns:
310
309
  The drawer sidebar component.
311
310
  """
312
- ...
313
311
 
314
312
  sidebar_trigger_style = {
315
313
  "position": "fixed",
@@ -362,7 +360,6 @@ class SidebarTrigger(Fragment):
362
360
  Returns:
363
361
  The sidebar trigger component.
364
362
  """
365
- ...
366
363
 
367
364
  class Layout(Box):
368
365
  @overload
@@ -587,7 +584,6 @@ class Layout(Box):
587
584
  Returns:
588
585
  The layout component.
589
586
  """
590
- ...
591
587
 
592
588
  class LayoutNamespace(ComponentNamespace):
593
589
  drawer_sidebar = staticmethod(DrawerSidebar.create)
@@ -814,6 +810,5 @@ class LayoutNamespace(ComponentNamespace):
814
810
  Returns:
815
811
  The layout component.
816
812
  """
817
- ...
818
813
 
819
814
  layout = LayoutNamespace()
reflex/istate/manager.py CHANGED
@@ -66,9 +66,8 @@ class StateManager(ABC):
66
66
  lock_expiration=config.redis_lock_expiration,
67
67
  lock_warning_threshold=config.redis_lock_warning_threshold,
68
68
  )
69
- raise InvalidStateManagerModeError(
70
- f"Expected one of: DISK, MEMORY, REDIS, got {config.state_manager_mode}"
71
- )
69
+ msg = f"Expected one of: DISK, MEMORY, REDIS, got {config.state_manager_mode}"
70
+ raise InvalidStateManagerModeError(msg)
72
71
 
73
72
  @abstractmethod
74
73
  async def get_state(self, token: str) -> BaseState:
@@ -80,7 +79,6 @@ class StateManager(ABC):
80
79
  Returns:
81
80
  The state for the token.
82
81
  """
83
- pass
84
82
 
85
83
  @abstractmethod
86
84
  async def set_state(self, token: str, state: BaseState):
@@ -90,7 +88,6 @@ class StateManager(ABC):
90
88
  token: The token to set the state for.
91
89
  state: The state to set.
92
90
  """
93
- pass
94
91
 
95
92
  @abstractmethod
96
93
  @contextlib.asynccontextmanager
@@ -145,7 +142,6 @@ class StateManagerMemory(StateManager):
145
142
  token: The token to set the state for.
146
143
  state: The state to set.
147
144
  """
148
- pass
149
145
 
150
146
  @override
151
147
  @contextlib.asynccontextmanager
@@ -269,6 +265,7 @@ class StateManagerDisk(StateManager):
269
265
  return BaseState._deserialize(fp=file)
270
266
  except Exception:
271
267
  pass
268
+ return None
272
269
 
273
270
  async def populate_substates(
274
271
  self, client_token: str, state: BaseState, root_state: BaseState
@@ -449,9 +446,8 @@ class StateManagerRedis(StateManager):
449
446
  InvalidLockWarningThresholdError: If the lock warning threshold is invalid.
450
447
  """
451
448
  if self.lock_warning_threshold >= (lock_expiration := self.lock_expiration):
452
- raise InvalidLockWarningThresholdError(
453
- f"The lock warning threshold({self.lock_warning_threshold}) must be less than the lock expiration time({lock_expiration})."
454
- )
449
+ msg = f"The lock warning threshold({self.lock_warning_threshold}) must be less than the lock expiration time({lock_expiration})."
450
+ raise InvalidLockWarningThresholdError(msg)
455
451
 
456
452
  def _get_required_state_classes(
457
453
  self,
@@ -557,9 +553,8 @@ class StateManagerRedis(StateManager):
557
553
  # Get the State class associated with the given path.
558
554
  state_cls = self.state.get_class_substate(state_path)
559
555
  else:
560
- raise RuntimeError(
561
- f"StateManagerRedis requires token to be specified in the form of {{token}}_{{state_full_name}}, but got {token}"
562
- )
556
+ msg = f"StateManagerRedis requires token to be specified in the form of {{token}}_{{state_full_name}}, but got {token}"
557
+ raise RuntimeError(msg)
563
558
 
564
559
  # Determine which states we already have.
565
560
  flat_state_tree: dict[str, BaseState] = (
@@ -601,11 +596,12 @@ class StateManagerRedis(StateManager):
601
596
  )
602
597
  parent_state = flat_state_tree.get(parent_state_name)
603
598
  if parent_state is None:
604
- raise RuntimeError(
599
+ msg = (
605
600
  f"Parent state for {state.get_full_name()} was not found "
606
601
  "in the state tree, but should have already been fetched. "
607
- "This is a bug",
602
+ "This is a bug"
608
603
  )
604
+ raise RuntimeError(msg)
609
605
  parent_state.substates[state_name] = state
610
606
  state.parent_state = parent_state
611
607
 
@@ -638,12 +634,13 @@ class StateManagerRedis(StateManager):
638
634
  lock_id is not None
639
635
  and await self.redis.get(self._lock_key(token)) != lock_id
640
636
  ):
641
- raise LockExpiredError(
637
+ msg = (
642
638
  f"Lock expired for token {token} while processing. Consider increasing "
643
639
  f"`app.state_manager.lock_expiration` (currently {self.lock_expiration}) "
644
640
  "or use `@rx.event(background=True)` decorator for long-running tasks."
645
641
  )
646
- elif lock_id is not None:
642
+ raise LockExpiredError(msg)
643
+ if lock_id is not None:
647
644
  time_taken = self.lock_expiration / 1000 - (
648
645
  await self.redis.ttl(self._lock_key(token))
649
646
  )
@@ -657,9 +654,8 @@ class StateManagerRedis(StateManager):
657
654
  client_token, substate_name = _split_substate_key(token)
658
655
  # If the substate name on the token doesn't match the instance name, it cannot have a parent.
659
656
  if state.parent_state is not None and state.get_full_name() != substate_name:
660
- raise RuntimeError(
661
- f"Cannot `set_state` with mismatching token {token} and substate {state.get_full_name()}."
662
- )
657
+ msg = f"Cannot `set_state` with mismatching token {token} and substate {state.get_full_name()}."
658
+ raise RuntimeError(msg)
663
659
 
664
660
  # Recursively set_state on all known substates.
665
661
  tasks = [
reflex/istate/proxy.py CHANGED
@@ -122,9 +122,8 @@ class StateProxy(wrapt.ObjectProxy):
122
122
  self._self_actx_lock.locked()
123
123
  and current_task == self._self_actx_lock_holder
124
124
  ):
125
- raise ImmutableStateError(
126
- "The state is already mutable. Do not nest `async with self` blocks."
127
- )
125
+ msg = "The state is already mutable. Do not nest `async with self` blocks."
126
+ raise ImmutableStateError(msg)
128
127
 
129
128
  from reflex.state import _substate_key
130
129
 
@@ -173,7 +172,8 @@ class StateProxy(wrapt.ObjectProxy):
173
172
  Raises:
174
173
  TypeError: always, because only async contextmanager protocol is supported.
175
174
  """
176
- raise TypeError("Background task must use `async with self` to modify state.")
175
+ msg = "Background task must use `async with self` to modify state."
176
+ raise TypeError(msg)
177
177
 
178
178
  def __exit__(self, *exc_info: Any) -> None:
179
179
  """Exit the regular context manager protocol.
@@ -181,7 +181,6 @@ class StateProxy(wrapt.ObjectProxy):
181
181
  Args:
182
182
  exc_info: The exception info tuple.
183
183
  """
184
- pass
185
184
 
186
185
  def __getattr__(self, name: str) -> Any:
187
186
  """Get the attribute from the underlying state instance.
@@ -196,10 +195,11 @@ class StateProxy(wrapt.ObjectProxy):
196
195
  ImmutableStateError: If the state is not in mutable mode.
197
196
  """
198
197
  if name in ["substates", "parent_state"] and not self._is_mutable():
199
- raise ImmutableStateError(
198
+ msg = (
200
199
  "Background task StateProxy is immutable outside of a context "
201
200
  "manager. Use `async with self` to modify state."
202
201
  )
202
+ raise ImmutableStateError(msg)
203
203
 
204
204
  value = super().__getattr__(name)
205
205
  if not name.startswith("_self_") and isinstance(value, MutableProxy):
@@ -243,10 +243,11 @@ class StateProxy(wrapt.ObjectProxy):
243
243
  super().__setattr__(name, value)
244
244
  return
245
245
 
246
- raise ImmutableStateError(
246
+ msg = (
247
247
  "Background task StateProxy is immutable outside of a context "
248
248
  "manager. Use `async with self` to modify state."
249
249
  )
250
+ raise ImmutableStateError(msg)
250
251
 
251
252
  def get_substate(self, path: Sequence[str]) -> BaseState:
252
253
  """Only allow substate access with lock held.
@@ -261,10 +262,11 @@ class StateProxy(wrapt.ObjectProxy):
261
262
  ImmutableStateError: If the state is not in mutable mode.
262
263
  """
263
264
  if not self._is_mutable():
264
- raise ImmutableStateError(
265
+ msg = (
265
266
  "Background task StateProxy is immutable outside of a context "
266
267
  "manager. Use `async with self` to modify state."
267
268
  )
269
+ raise ImmutableStateError(msg)
268
270
  return self.__wrapped__.get_substate(path)
269
271
 
270
272
  async def get_state(self, state_cls: type[BaseState]) -> BaseState:
@@ -280,10 +282,11 @@ class StateProxy(wrapt.ObjectProxy):
280
282
  ImmutableStateError: If the state is not in mutable mode.
281
283
  """
282
284
  if not self._is_mutable():
283
- raise ImmutableStateError(
285
+ msg = (
284
286
  "Background task StateProxy is immutable outside of a context "
285
287
  "manager. Use `async with self` to modify state."
286
288
  )
289
+ raise ImmutableStateError(msg)
287
290
  return type(self)(
288
291
  await self.__wrapped__.get_state(state_cls), parent_state_proxy=self
289
292
  )
@@ -323,7 +326,8 @@ class ReadOnlyStateProxy(StateProxy):
323
326
  # Special case attributes of the proxy itself, not applied to the wrapped object.
324
327
  super().__setattr__(name, value)
325
328
  return
326
- raise NotImplementedError("This is a read-only state proxy.")
329
+ msg = "This is a read-only state proxy."
330
+ raise NotImplementedError(msg)
327
331
 
328
332
  def mark_dirty(self):
329
333
  """Mark the state as dirty.
@@ -331,7 +335,8 @@ class ReadOnlyStateProxy(StateProxy):
331
335
  Raises:
332
336
  NotImplementedError: Always raised when trying to mark the proxied state as dirty.
333
337
  """
334
- raise NotImplementedError("This is a read-only state proxy.")
338
+ msg = "This is a read-only state proxy."
339
+ raise NotImplementedError(msg)
335
340
 
336
341
 
337
342
  class MutableProxy(wrapt.ObjectProxy):
@@ -460,6 +465,7 @@ class MutableProxy(wrapt.ObjectProxy):
460
465
  self._self_state._mark_dirty()
461
466
  if wrapped is not None:
462
467
  return wrapped(*args, **(kwargs or {}))
468
+ return None
463
469
 
464
470
  @classmethod
465
471
  def _is_mutable_type(cls, value: Any) -> bool:
@@ -748,10 +754,11 @@ class ImmutableMutableProxy(MutableProxy):
748
754
  ImmutableStateError: if the StateProxy is not mutable.
749
755
  """
750
756
  if not self._self_state._is_mutable():
751
- raise ImmutableStateError(
757
+ msg = (
752
758
  "Background task StateProxy is immutable outside of a context "
753
759
  "manager. Use `async with self` to modify state."
754
760
  )
761
+ raise ImmutableStateError(msg)
755
762
  return super()._mark_dirty(
756
763
  wrapped=wrapped, instance=instance, args=args, kwargs=kwargs
757
764
  )
reflex/model.py CHANGED
@@ -83,7 +83,8 @@ def get_engine(url: str | None = None) -> sqlalchemy.engine.Engine:
83
83
  conf = get_config()
84
84
  url = url or conf.db_url
85
85
  if url is None:
86
- raise ValueError("No database url configured")
86
+ msg = "No database url configured"
87
+ raise ValueError(msg)
87
88
 
88
89
  global _ENGINE
89
90
  if url in _ENGINE:
@@ -125,7 +126,8 @@ def get_async_engine(url: str | None) -> sqlalchemy.ext.asyncio.AsyncEngine:
125
126
  f"db_url `{_safe_db_url_for_logging(conf.db_url)}`."
126
127
  )
127
128
  if url is None:
128
- raise ValueError("No async database url configured")
129
+ msg = "No async database url configured"
130
+ raise ValueError(msg)
129
131
 
130
132
  global _ASYNC_ENGINE
131
133
  if url in _ASYNC_ENGINE:
@@ -271,7 +273,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
271
273
  """
272
274
  if hasattr(value, "dict"):
273
275
  return value.dict()
274
- elif isinstance(value, list):
276
+ if isinstance(value, list):
275
277
  return [cls._dict_recursive(item) for item in value]
276
278
  return value
277
279
 
@@ -481,7 +483,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
481
483
  None - indicating the process was skipped.
482
484
  """
483
485
  if not environment.ALEMBIC_CONFIG.get().exists():
484
- return
486
+ return None
485
487
 
486
488
  with cls.get_db_engine().connect() as connection:
487
489
  cls._alembic_upgrade(connection=connection)
reflex/plugins/base.py CHANGED
@@ -99,3 +99,11 @@ class Plugin:
99
99
  Args:
100
100
  context: The context for the plugin.
101
101
  """
102
+
103
+ def __repr__(self):
104
+ """Return a string representation of the plugin.
105
+
106
+ Returns:
107
+ A string representation of the plugin.
108
+ """
109
+ return f"{self.__class__.__name__}()"