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/testing.py CHANGED
@@ -155,9 +155,8 @@ class AppHarness:
155
155
  app_name = f"{func_name}_{slug_suffix}"
156
156
  app_name = re.sub(r"[^a-zA-Z0-9_]", "_", app_name)
157
157
  elif isinstance(app_source, str):
158
- raise ValueError(
159
- "app_name must be provided when app_source is a string."
160
- )
158
+ msg = "app_name must be provided when app_source is a string."
159
+ raise ValueError(msg)
161
160
  else:
162
161
  app_name = app_source.__name__
163
162
 
@@ -285,7 +284,8 @@ class AppHarness:
285
284
  self.app_instance._state_manager, StateManagerRedis
286
285
  ):
287
286
  if self.app_instance._state is None:
288
- raise RuntimeError("State is not set.")
287
+ msg = "State is not set."
288
+ raise RuntimeError(msg)
289
289
  # Create our own redis connection for testing.
290
290
  self.state_manager = StateManagerRedis.create(self.app_instance._state)
291
291
  else:
@@ -299,7 +299,8 @@ class AppHarness:
299
299
 
300
300
  def _get_backend_shutdown_handler(self):
301
301
  if self.backend is None:
302
- raise RuntimeError("Backend was not initialized.")
302
+ msg = "Backend was not initialized."
303
+ raise RuntimeError(msg)
303
304
 
304
305
  original_shutdown = self.backend.shutdown
305
306
 
@@ -330,7 +331,8 @@ class AppHarness:
330
331
 
331
332
  def _start_backend(self, port: int = 0):
332
333
  if self.app_asgi is None:
333
- raise RuntimeError("App was not initialized.")
334
+ msg = "App was not initialized."
335
+ raise RuntimeError(msg)
334
336
  self.backend = uvicorn.Server(
335
337
  uvicorn.Config(
336
338
  app=self.app_asgi,
@@ -366,7 +368,8 @@ class AppHarness:
366
368
  state=self.app_instance._state,
367
369
  )
368
370
  if not isinstance(self.app_instance.state_manager, StateManagerRedis):
369
- raise RuntimeError("Failed to reset state manager.")
371
+ msg = "Failed to reset state manager."
372
+ raise RuntimeError(msg)
370
373
 
371
374
  def _start_frontend(self):
372
375
  # Set up the frontend.
@@ -406,7 +409,8 @@ class AppHarness:
406
409
  config.deploy_url = self.frontend_url
407
410
  break
408
411
  if self.frontend_url is None:
409
- raise RuntimeError("Frontend did not start")
412
+ msg = "Frontend did not start"
413
+ raise RuntimeError(msg)
410
414
 
411
415
  def consume_frontend_output():
412
416
  while True:
@@ -578,20 +582,23 @@ class AppHarness:
578
582
  TimeoutError: when server or sockets are not ready
579
583
  """
580
584
  if self.backend is None:
581
- raise RuntimeError("Backend is not running.")
585
+ msg = "Backend is not running."
586
+ raise RuntimeError(msg)
582
587
  backend = self.backend
583
588
  # check for servers to be initialized
584
589
  if not self._poll_for(
585
590
  target=lambda: getattr(backend, "servers", False),
586
591
  timeout=timeout,
587
592
  ):
588
- raise TimeoutError("Backend servers are not initialized.")
593
+ msg = "Backend servers are not initialized."
594
+ raise TimeoutError(msg)
589
595
  # check for sockets to be listening
590
596
  if not self._poll_for(
591
597
  target=lambda: getattr(backend.servers[0], "sockets", False),
592
598
  timeout=timeout,
593
599
  ):
594
- raise TimeoutError("Backend is not listening.")
600
+ msg = "Backend is not listening."
601
+ raise TimeoutError(msg)
595
602
  return backend.servers[0].sockets[0]
596
603
 
597
604
  def frontend(
@@ -619,12 +626,14 @@ class AppHarness:
619
626
  RuntimeError: when selenium is not importable or frontend is not running
620
627
  """
621
628
  if not has_selenium:
622
- raise RuntimeError(
629
+ msg = (
623
630
  "Frontend functionality requires `selenium` to be installed, "
624
631
  "and it could not be imported."
625
632
  )
633
+ raise RuntimeError(msg)
626
634
  if self.frontend_url is None:
627
- raise RuntimeError("Frontend is not running.")
635
+ msg = "Frontend is not running."
636
+ raise RuntimeError(msg)
628
637
  want_headless = False
629
638
  if environment.APP_HARNESS_HEADLESS.get():
630
639
  want_headless = True
@@ -650,7 +659,8 @@ class AppHarness:
650
659
  if want_headless:
651
660
  driver_options.add_argument("headless")
652
661
  if driver_options is None:
653
- raise RuntimeError(f"Could not determine options for {driver_clz}")
662
+ msg = f"Could not determine options for {driver_clz}"
663
+ raise RuntimeError(msg)
654
664
  if args := environment.APP_HARNESS_DRIVER_ARGS.get():
655
665
  for arg in args.split(","):
656
666
  driver_options.add_argument(arg)
@@ -680,7 +690,8 @@ class AppHarness:
680
690
  RuntimeError: when the app hasn't started running
681
691
  """
682
692
  if self.state_manager is None:
683
- raise RuntimeError("state_manager is not set.")
693
+ msg = "state_manager is not set."
694
+ raise RuntimeError(msg)
684
695
  try:
685
696
  return await self.state_manager.get_state(token)
686
697
  finally:
@@ -698,7 +709,8 @@ class AppHarness:
698
709
  RuntimeError: when the app hasn't started running
699
710
  """
700
711
  if self.state_manager is None:
701
- raise RuntimeError("state_manager is not set.")
712
+ msg = "state_manager is not set."
713
+ raise RuntimeError(msg)
702
714
  state = await self.get_state(token)
703
715
  for key, value in kwargs.items():
704
716
  setattr(state, key, value)
@@ -722,9 +734,11 @@ class AppHarness:
722
734
  RuntimeError: when the app hasn't started running
723
735
  """
724
736
  if self.state_manager is None:
725
- raise RuntimeError("state_manager is not set.")
737
+ msg = "state_manager is not set."
738
+ raise RuntimeError(msg)
726
739
  if self.app_instance is None:
727
- raise RuntimeError("App is not running.")
740
+ msg = "App is not running."
741
+ raise RuntimeError(msg)
728
742
  app_state_manager = self.app_instance.state_manager
729
743
  if isinstance(self.state_manager, StateManagerRedis):
730
744
  # Temporarily replace the app's state manager with our own, since
@@ -761,9 +775,8 @@ class AppHarness:
761
775
  target=lambda: element.text != exp_not_equal,
762
776
  timeout=timeout,
763
777
  ):
764
- raise TimeoutError(
765
- f"{element} content remains {exp_not_equal!r} while polling.",
766
- )
778
+ msg = f"{element} content remains {exp_not_equal!r} while polling."
779
+ raise TimeoutError(msg)
767
780
  return element.text
768
781
 
769
782
  def poll_for_value(
@@ -792,9 +805,8 @@ class AppHarness:
792
805
  target=lambda: element.get_attribute("value") not in exp_not_equal,
793
806
  timeout=timeout,
794
807
  ):
795
- raise TimeoutError(
796
- f"{element} content remains {exp_not_equal!r} while polling.",
797
- )
808
+ msg = f"{element} content remains {exp_not_equal!r} while polling."
809
+ raise TimeoutError(msg)
798
810
  return element.get_attribute("value")
799
811
 
800
812
  def poll_for_clients(self, timeout: TimeoutType = None) -> dict[str, BaseState]:
@@ -812,15 +824,18 @@ class AppHarness:
812
824
  ValueError: when the state_manager is not a memory state manager
813
825
  """
814
826
  if self.app_instance is None:
815
- raise RuntimeError("App is not running.")
827
+ msg = "App is not running."
828
+ raise RuntimeError(msg)
816
829
  state_manager = self.app_instance.state_manager
817
830
  if not isinstance(state_manager, (StateManagerMemory, StateManagerDisk)):
818
- raise ValueError("Only works with memory or disk state manager")
831
+ msg = "Only works with memory or disk state manager"
832
+ raise ValueError(msg)
819
833
  if not self._poll_for(
820
834
  target=lambda: state_manager.states,
821
835
  timeout=timeout,
822
836
  ):
823
- raise TimeoutError("No states were observed while polling.")
837
+ msg = "No states were observed while polling."
838
+ raise TimeoutError(msg)
824
839
  return state_manager.states
825
840
 
826
841
 
@@ -962,11 +977,13 @@ class AppHarnessProd(AppHarness):
962
977
  def _wait_frontend(self):
963
978
  self._poll_for(lambda: self.frontend_server is not None)
964
979
  if self.frontend_server is None or not self.frontend_server.socket.fileno():
965
- raise RuntimeError("Frontend did not start")
980
+ msg = "Frontend did not start"
981
+ raise RuntimeError(msg)
966
982
 
967
983
  def _start_backend(self):
968
984
  if self.app_asgi is None:
969
- raise RuntimeError("App was not initialized.")
985
+ msg = "App was not initialized."
986
+ raise RuntimeError(msg)
970
987
  environment.REFLEX_SKIP_COMPILE.set(True)
971
988
  self.backend = uvicorn.Server(
972
989
  uvicorn.Config(
reflex/utils/build.py CHANGED
@@ -132,7 +132,7 @@ def _zip(
132
132
  def zip_app(
133
133
  frontend: bool = True,
134
134
  backend: bool = True,
135
- zip_dest_dir: str | Path = Path.cwd(),
135
+ zip_dest_dir: str | Path | None = None,
136
136
  upload_db_file: bool = False,
137
137
  ):
138
138
  """Zip up the app.
@@ -143,6 +143,7 @@ def zip_app(
143
143
  zip_dest_dir: The directory to export the zip file to.
144
144
  upload_db_file: Whether to upload the database file.
145
145
  """
146
+ zip_dest_dir = zip_dest_dir or Path.cwd()
146
147
  zip_dest_dir = Path(zip_dest_dir)
147
148
  files_to_exclude = {
148
149
  constants.ComponentName.FRONTEND.zip(),
reflex/utils/console.py CHANGED
@@ -59,9 +59,8 @@ def set_log_level(log_level: LogLevel | None):
59
59
  if log_level is None:
60
60
  return
61
61
  if not isinstance(log_level, LogLevel):
62
- raise TypeError(
63
- f"log_level must be a LogLevel enum value, got {log_level} of type {type(log_level)} instead."
64
- )
62
+ msg = f"log_level must be a LogLevel enum value, got {log_level} of type {type(log_level)} instead."
63
+ raise TypeError(msg)
65
64
  global _LOG_LEVEL
66
65
  if log_level != _LOG_LEVEL:
67
66
  # Set the loglevel persistenly for subprocesses.
@@ -89,8 +88,7 @@ def print(msg: str, dedupe: bool = False, **kwargs):
89
88
  if dedupe:
90
89
  if msg in _EMITTED_PRINTS:
91
90
  return
92
- else:
93
- _EMITTED_PRINTS.add(msg)
91
+ _EMITTED_PRINTS.add(msg)
94
92
  _console.print(msg, **kwargs)
95
93
 
96
94
 
@@ -107,8 +105,7 @@ def debug(msg: str, dedupe: bool = False, **kwargs):
107
105
  if dedupe:
108
106
  if msg_ in _EMITTED_DEBUG:
109
107
  return
110
- else:
111
- _EMITTED_DEBUG.add(msg_)
108
+ _EMITTED_DEBUG.add(msg_)
112
109
  if progress := kwargs.pop("progress", None):
113
110
  progress.console.print(msg_, **kwargs)
114
111
  else:
@@ -127,8 +124,7 @@ def info(msg: str, dedupe: bool = False, **kwargs):
127
124
  if dedupe:
128
125
  if msg in _EMITTED_INFO:
129
126
  return
130
- else:
131
- _EMITTED_INFO.add(msg)
127
+ _EMITTED_INFO.add(msg)
132
128
  print(f"[cyan]Info: {msg}[/cyan]", **kwargs)
133
129
 
134
130
 
@@ -144,8 +140,7 @@ def success(msg: str, dedupe: bool = False, **kwargs):
144
140
  if dedupe:
145
141
  if msg in _EMITTED_SUCCESS:
146
142
  return
147
- else:
148
- _EMITTED_SUCCESS.add(msg)
143
+ _EMITTED_SUCCESS.add(msg)
149
144
  print(f"[green]Success: {msg}[/green]", **kwargs)
150
145
 
151
146
 
@@ -161,8 +156,7 @@ def log(msg: str, dedupe: bool = False, **kwargs):
161
156
  if dedupe:
162
157
  if msg in _EMITTED_LOGS:
163
158
  return
164
- else:
165
- _EMITTED_LOGS.add(msg)
159
+ _EMITTED_LOGS.add(msg)
166
160
  _console.log(msg, **kwargs)
167
161
 
168
162
 
@@ -188,8 +182,7 @@ def warn(msg: str, dedupe: bool = False, **kwargs):
188
182
  if dedupe:
189
183
  if msg in _EMIITED_WARNINGS:
190
184
  return
191
- else:
192
- _EMIITED_WARNINGS.add(msg)
185
+ _EMIITED_WARNINGS.add(msg)
193
186
  print(f"[orange1]Warning: {msg}[/orange1]", **kwargs)
194
187
 
195
188
 
@@ -271,8 +264,7 @@ def error(msg: str, dedupe: bool = False, **kwargs):
271
264
  if dedupe:
272
265
  if msg in _EMITTED_ERRORS:
273
266
  return
274
- else:
275
- _EMITTED_ERRORS.add(msg)
267
+ _EMITTED_ERRORS.add(msg)
276
268
  print(f"[red]{msg}[/red]", **kwargs)
277
269
 
278
270
 
reflex/utils/exec.py CHANGED
@@ -244,14 +244,12 @@ def get_app_file() -> Path:
244
244
  sys.path.insert(0, current_working_dir)
245
245
  module_spec = importlib.util.find_spec(get_app_module())
246
246
  if module_spec is None:
247
- raise ImportError(
248
- f"Module {get_app_module()} not found. Make sure the module is installed."
249
- )
247
+ msg = f"Module {get_app_module()} not found. Make sure the module is installed."
248
+ raise ImportError(msg)
250
249
  file_name = module_spec.origin
251
250
  if file_name is None:
252
- raise ImportError(
253
- f"Module {get_app_module()} not found. Make sure the module is installed."
254
- )
251
+ msg = f"Module {get_app_module()} not found. Make sure the module is installed."
252
+ raise ImportError(msg)
255
253
  return Path(file_name).resolve()
256
254
 
257
255
 
@@ -300,13 +298,12 @@ def get_reload_paths() -> Sequence[Path]:
300
298
  The reload paths for the backend.
301
299
  """
302
300
  config = get_config()
303
- reload_paths = [Path(config.app_name).parent]
304
- if config.app_module is not None and config.app_module.__file__:
305
- module_path = Path(config.app_module.__file__).resolve().parent
301
+ reload_paths = [Path.cwd()]
302
+ if (spec := importlib.util.find_spec(config.module)) is not None and spec.origin:
303
+ module_path = Path(spec.origin).resolve().parent
306
304
 
307
305
  while module_path.parent.name and any(
308
- sibling_file.name == "__init__.py"
309
- for sibling_file in module_path.parent.iterdir()
306
+ sibling_file.name == "__init__.py" for sibling_file in module_path.iterdir()
310
307
  ):
311
308
  # go up a level to find dir without `__init__.py`
312
309
  module_path = module_path.parent
@@ -383,6 +380,7 @@ HOTRELOAD_IGNORE_EXTENSIONS = (
383
380
  "json",
384
381
  "sh",
385
382
  "bash",
383
+ "log",
386
384
  )
387
385
 
388
386
  HOTRELOAD_IGNORE_PATTERNS = (
reflex/utils/format.py CHANGED
@@ -73,7 +73,8 @@ def get_close_char(open: str, close: str | None = None) -> str:
73
73
  if close is not None:
74
74
  return close
75
75
  if open not in WRAP_MAP:
76
- raise ValueError(f"Invalid wrap open: {open}, must be one of {WRAP_MAP.keys()}")
76
+ msg = f"Invalid wrap open: {open}, must be one of {WRAP_MAP.keys()}"
77
+ raise ValueError(msg)
77
78
  return WRAP_MAP[open]
78
79
 
79
80
 
@@ -187,8 +188,7 @@ def to_camel_case(text: str, treat_hyphens_as_underscores: bool = True) -> str:
187
188
  # Capitalize the first letter of each word except the first one
188
189
  if len(words) == 1:
189
190
  return words[0]
190
- converted_word = words[0] + "".join([w.capitalize() for w in words[1:]])
191
- return converted_word
191
+ return words[0] + "".join([w.capitalize() for w in words[1:]])
192
192
 
193
193
 
194
194
  def to_title_case(text: str, sep: str = "") -> str:
@@ -264,17 +264,13 @@ def _escape_js_string(string: str) -> str:
264
264
  if segment.startswith("${") and segment.endswith("}"):
265
265
  # Return the `${}` segment unchanged
266
266
  return segment
267
- else:
268
- # Escape backticks in the segment
269
- segment = segment.replace(r"\`", "`")
270
- segment = segment.replace("`", r"\`")
271
- return segment
267
+ # Escape backticks in the segment
268
+ return segment.replace(r"\`", "`").replace("`", r"\`")
272
269
 
273
270
  # Split the string into parts, keeping the `${}` segments
274
271
  parts = re.split(r"(\$\{.*?\})", string)
275
272
  escaped_parts = [escape_outside_segments(part) for part in parts]
276
- escaped_string = "".join(escaped_parts)
277
- return escaped_string
273
+ return "".join(escaped_parts)
278
274
 
279
275
 
280
276
  def _wrap_js_string(string: str) -> str:
@@ -287,8 +283,7 @@ def _wrap_js_string(string: str) -> str:
287
283
  The wrapped string.
288
284
  """
289
285
  string = wrap(string, "`")
290
- string = wrap(string, "{")
291
- return string
286
+ return wrap(string, "{")
292
287
 
293
288
 
294
289
  def format_string(string: str) -> str:
@@ -402,13 +397,13 @@ def format_prop(
402
397
  return str(Var.create(prop))
403
398
 
404
399
  # Handle other types.
405
- elif isinstance(prop, str):
400
+ if isinstance(prop, str):
406
401
  if is_wrapped(prop, "{"):
407
402
  return prop
408
403
  return json_dumps(prop)
409
404
 
410
405
  # For dictionaries, convert any properties to strings.
411
- elif isinstance(prop, dict):
406
+ if isinstance(prop, dict):
412
407
  prop = serializers.serialize_dict(prop) # pyright: ignore [reportAttributeAccessIssue]
413
408
 
414
409
  else:
@@ -417,11 +412,13 @@ def format_prop(
417
412
  except exceptions.InvalidStylePropError:
418
413
  raise
419
414
  except TypeError as e:
420
- raise TypeError(f"Could not format prop: {prop} of type {type(prop)}") from e
415
+ msg = f"Could not format prop: {prop} of type {type(prop)}"
416
+ raise TypeError(msg) from e
421
417
 
422
418
  # Wrap the variable in braces.
423
419
  if not isinstance(prop, str):
424
- raise ValueError(f"Invalid prop: {prop}. Expected a string.")
420
+ msg = f"Invalid prop: {prop}. Expected a string."
421
+ raise ValueError(msg)
425
422
  return wrap(prop, "{", check_first=False)
426
423
 
427
424
 
@@ -591,9 +588,8 @@ def format_queue_events(
591
588
  elif isinstance(spec, type(lambda: None)):
592
589
  specs = call_event_fn(spec, args_spec or _default_args_spec) # pyright: ignore [reportAssignmentType, reportArgumentType]
593
590
  if isinstance(specs, Var):
594
- raise ValueError(
595
- f"Invalid event spec: {specs}. Expected a list of EventSpecs."
596
- )
591
+ msg = f"Invalid event spec: {specs}. Expected a list of EventSpecs."
592
+ raise ValueError(msg)
597
593
  payloads.extend(format_event(s) for s in specs)
598
594
 
599
595
  # Return the final code snippet, expecting queueEvents, processEvent, and socket to be in scope.
@@ -662,12 +658,14 @@ def format_library_name(library_fullname: str | dict[str, Any]) -> str:
662
658
  # If input is a dictionary, extract the 'name' key
663
659
  if isinstance(library_fullname, dict):
664
660
  if "name" not in library_fullname:
665
- raise KeyError("Dictionary input must contain a 'name' key")
661
+ msg = "Dictionary input must contain a 'name' key"
662
+ raise KeyError(msg)
666
663
  library_fullname = library_fullname["name"]
667
664
 
668
665
  # Process the library name as a string
669
666
  if not isinstance(library_fullname, str):
670
- raise TypeError("Library name must be a string")
667
+ msg = "Library name must be a string"
668
+ raise TypeError(msg)
671
669
 
672
670
  if library_fullname.startswith("https://"):
673
671
  return library_fullname
@@ -764,9 +762,8 @@ def format_data_editor_column(col: str | dict):
764
762
  if isinstance(col, Var):
765
763
  return col
766
764
 
767
- raise ValueError(
768
- f"unexpected type ({(type(col).__name__)}: {col}) for column header in data_editor"
769
- )
765
+ msg = f"unexpected type ({(type(col).__name__)}: {col}) for column header in data_editor"
766
+ raise ValueError(msg)
770
767
 
771
768
 
772
769
  def format_data_editor_cell(cell: Any):
reflex/utils/imports.py CHANGED
@@ -127,10 +127,11 @@ class ImportVar:
127
127
  """
128
128
  if self.alias:
129
129
  return (
130
- self.alias if self.is_default else " as ".join([self.tag, self.alias]) # pyright: ignore [reportCallIssue,reportArgumentType]
130
+ self.alias
131
+ if self.is_default
132
+ else (self.tag + " as " + self.alias if self.tag else self.alias)
131
133
  )
132
- else:
133
- return self.tag or ""
134
+ return self.tag or ""
134
135
 
135
136
 
136
137
  ImportTypes = str | ImportVar | list[str | ImportVar] | list[ImportVar]
@@ -65,7 +65,7 @@ def attach(
65
65
  def __getattr__(name: str): # noqa: N807
66
66
  if name in submodules:
67
67
  return importlib.import_module(f"{package_name}.{name}")
68
- elif name in attr_to_modules:
68
+ if name in attr_to_modules:
69
69
  submod_path = f"{package_name}.{attr_to_modules[name]}"
70
70
  submod = importlib.import_module(submod_path)
71
71
  attr = getattr(submod, name)
@@ -78,8 +78,8 @@ def attach(
78
78
  pkg.__dict__[name] = attr
79
79
 
80
80
  return attr
81
- else:
82
- raise AttributeError(f"No {package_name} attribute {name}")
81
+ msg = f"No {package_name} attribute {name}"
82
+ raise AttributeError(msg)
83
83
 
84
84
  def __dir__(): # noqa: N807
85
85
  return __all__
reflex/utils/misc.py CHANGED
@@ -20,5 +20,6 @@ async def run_in_thread(func: Callable) -> Any:
20
20
  Any: The return value of the function.
21
21
  """
22
22
  if asyncio.coroutines.iscoroutinefunction(func):
23
- raise ValueError("func must be a non-async function")
23
+ msg = "func must be a non-async function"
24
+ raise ValueError(msg)
24
25
  return await asyncio.get_event_loop().run_in_executor(None, func)
reflex/utils/net.py CHANGED
@@ -19,7 +19,7 @@ def _httpx_verify_kwarg() -> bool:
19
19
  Returns:
20
20
  True if SSL verification is enabled, False otherwise
21
21
  """
22
- from ..config import environment
22
+ from reflex.config import environment
23
23
 
24
24
  return not environment.SSL_NO_VERIFY.get()
25
25
 
@@ -131,7 +131,7 @@ def _httpx_local_address_kwarg() -> str:
131
131
  Returns:
132
132
  The local address to bind to
133
133
  """
134
- from ..config import environment
134
+ from reflex.config import environment
135
135
 
136
136
  return environment.REFLEX_HTTP_CLIENT_BIND_ADDRESS.get() or (
137
137
  "::" if _should_use_ipv6() else "0.0.0.0"
reflex/utils/path_ops.py CHANGED
@@ -300,7 +300,8 @@ def update_directory_tree(src: Path, dest: Path):
300
300
  ValueError: If the source is not a directory
301
301
  """
302
302
  if not src.is_dir():
303
- raise ValueError(f"Source {src} is not a directory")
303
+ msg = f"Source {src} is not a directory"
304
+ raise ValueError(msg)
304
305
 
305
306
  # Ensure the destination directory exists
306
307
  dest.mkdir(parents=True, exist_ok=True)