reflex 0.7.13a2__py3-none-any.whl → 0.7.14a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

Files changed (256) hide show
  1. reflex/.templates/apps/blank/code/blank.py +0 -2
  2. reflex/app.py +64 -69
  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 +49 -41
  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 +14 -15
  53. reflex/components/el/elements/forms.pyi +15 -32
  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.pyi +0 -7
  79. reflex/components/radix/primitives/base.py +1 -3
  80. reflex/components/radix/primitives/base.pyi +0 -2
  81. reflex/components/radix/primitives/drawer.pyi +0 -11
  82. reflex/components/radix/primitives/form.py +4 -8
  83. reflex/components/radix/primitives/form.pyi +0 -12
  84. reflex/components/radix/primitives/progress.py +1 -1
  85. reflex/components/radix/primitives/progress.pyi +0 -5
  86. reflex/components/radix/primitives/slider.py +1 -1
  87. reflex/components/radix/primitives/slider.pyi +0 -5
  88. reflex/components/radix/themes/base.pyi +0 -8
  89. reflex/components/radix/themes/color_mode.pyi +0 -3
  90. reflex/components/radix/themes/components/alert_dialog.py +4 -2
  91. reflex/components/radix/themes/components/alert_dialog.pyi +4 -9
  92. reflex/components/radix/themes/components/aspect_ratio.py +1 -2
  93. reflex/components/radix/themes/components/aspect_ratio.pyi +1 -3
  94. reflex/components/radix/themes/components/avatar.py +5 -2
  95. reflex/components/radix/themes/components/avatar.pyi +1 -3
  96. reflex/components/radix/themes/components/badge.py +5 -2
  97. reflex/components/radix/themes/components/badge.pyi +1 -3
  98. reflex/components/radix/themes/components/button.py +2 -3
  99. reflex/components/radix/themes/components/button.pyi +1 -3
  100. reflex/components/radix/themes/components/callout.py +1 -2
  101. reflex/components/radix/themes/components/callout.pyi +1 -7
  102. reflex/components/radix/themes/components/card.py +1 -2
  103. reflex/components/radix/themes/components/card.pyi +1 -3
  104. reflex/components/radix/themes/components/checkbox.py +7 -4
  105. reflex/components/radix/themes/components/checkbox.pyi +1 -5
  106. reflex/components/radix/themes/components/checkbox_cards.py +1 -2
  107. reflex/components/radix/themes/components/checkbox_cards.pyi +1 -4
  108. reflex/components/radix/themes/components/checkbox_group.py +1 -2
  109. reflex/components/radix/themes/components/checkbox_group.pyi +1 -4
  110. reflex/components/radix/themes/components/context_menu.py +1 -1
  111. reflex/components/radix/themes/components/context_menu.pyi +1 -14
  112. reflex/components/radix/themes/components/data_list.py +1 -2
  113. reflex/components/radix/themes/components/data_list.pyi +1 -6
  114. reflex/components/radix/themes/components/dialog.py +4 -2
  115. reflex/components/radix/themes/components/dialog.pyi +4 -9
  116. reflex/components/radix/themes/components/dropdown_menu.py +5 -2
  117. reflex/components/radix/themes/components/dropdown_menu.pyi +4 -10
  118. reflex/components/radix/themes/components/hover_card.py +4 -2
  119. reflex/components/radix/themes/components/hover_card.pyi +4 -6
  120. reflex/components/radix/themes/components/icon_button.py +7 -8
  121. reflex/components/radix/themes/components/icon_button.pyi +1 -3
  122. reflex/components/radix/themes/components/inset.py +1 -2
  123. reflex/components/radix/themes/components/inset.pyi +1 -3
  124. reflex/components/radix/themes/components/popover.py +4 -2
  125. reflex/components/radix/themes/components/popover.pyi +4 -6
  126. reflex/components/radix/themes/components/progress.py +1 -2
  127. reflex/components/radix/themes/components/progress.pyi +1 -3
  128. reflex/components/radix/themes/components/radio.py +1 -2
  129. reflex/components/radix/themes/components/radio.pyi +1 -3
  130. reflex/components/radix/themes/components/radio_cards.py +1 -2
  131. reflex/components/radix/themes/components/radio_cards.pyi +1 -4
  132. reflex/components/radix/themes/components/radio_group.py +7 -5
  133. reflex/components/radix/themes/components/radio_group.pyi +1 -6
  134. reflex/components/radix/themes/components/scroll_area.py +1 -2
  135. reflex/components/radix/themes/components/scroll_area.pyi +1 -3
  136. reflex/components/radix/themes/components/segmented_control.py +1 -2
  137. reflex/components/radix/themes/components/segmented_control.pyi +1 -4
  138. reflex/components/radix/themes/components/select.py +5 -2
  139. reflex/components/radix/themes/components/select.pyi +1 -11
  140. reflex/components/radix/themes/components/separator.py +1 -2
  141. reflex/components/radix/themes/components/separator.pyi +1 -3
  142. reflex/components/radix/themes/components/skeleton.py +1 -2
  143. reflex/components/radix/themes/components/skeleton.pyi +1 -3
  144. reflex/components/radix/themes/components/slider.py +1 -2
  145. reflex/components/radix/themes/components/slider.pyi +1 -3
  146. reflex/components/radix/themes/components/spinner.py +1 -2
  147. reflex/components/radix/themes/components/spinner.pyi +1 -3
  148. reflex/components/radix/themes/components/switch.py +1 -2
  149. reflex/components/radix/themes/components/switch.pyi +1 -3
  150. reflex/components/radix/themes/components/table.py +1 -2
  151. reflex/components/radix/themes/components/table.pyi +1 -9
  152. reflex/components/radix/themes/components/tabs.py +1 -2
  153. reflex/components/radix/themes/components/tabs.pyi +1 -7
  154. reflex/components/radix/themes/components/text_area.py +5 -2
  155. reflex/components/radix/themes/components/text_area.pyi +2 -4
  156. reflex/components/radix/themes/components/text_field.py +5 -2
  157. reflex/components/radix/themes/components/text_field.pyi +1 -5
  158. reflex/components/radix/themes/components/tooltip.py +1 -2
  159. reflex/components/radix/themes/components/tooltip.pyi +1 -3
  160. reflex/components/radix/themes/layout/base.py +5 -2
  161. reflex/components/radix/themes/layout/base.pyi +5 -3
  162. reflex/components/radix/themes/layout/box.py +1 -2
  163. reflex/components/radix/themes/layout/box.pyi +1 -3
  164. reflex/components/radix/themes/layout/center.pyi +0 -1
  165. reflex/components/radix/themes/layout/container.py +1 -2
  166. reflex/components/radix/themes/layout/container.pyi +1 -3
  167. reflex/components/radix/themes/layout/flex.py +6 -2
  168. reflex/components/radix/themes/layout/flex.pyi +1 -3
  169. reflex/components/radix/themes/layout/grid.py +6 -2
  170. reflex/components/radix/themes/layout/grid.pyi +1 -3
  171. reflex/components/radix/themes/layout/list.py +2 -1
  172. reflex/components/radix/themes/layout/list.pyi +0 -5
  173. reflex/components/radix/themes/layout/section.py +1 -2
  174. reflex/components/radix/themes/layout/section.pyi +1 -3
  175. reflex/components/radix/themes/layout/spacer.pyi +0 -1
  176. reflex/components/radix/themes/layout/stack.py +1 -1
  177. reflex/components/radix/themes/layout/stack.pyi +0 -3
  178. reflex/components/radix/themes/typography/blockquote.py +1 -1
  179. reflex/components/radix/themes/typography/blockquote.pyi +1 -3
  180. reflex/components/radix/themes/typography/code.py +5 -1
  181. reflex/components/radix/themes/typography/code.pyi +1 -3
  182. reflex/components/radix/themes/typography/heading.py +1 -1
  183. reflex/components/radix/themes/typography/heading.pyi +1 -3
  184. reflex/components/radix/themes/typography/link.py +3 -2
  185. reflex/components/radix/themes/typography/link.pyi +1 -3
  186. reflex/components/radix/themes/typography/text.py +1 -1
  187. reflex/components/radix/themes/typography/text.pyi +1 -9
  188. reflex/components/react_player/audio.py +0 -2
  189. reflex/components/react_player/audio.pyi +0 -3
  190. reflex/components/react_player/react_player.pyi +0 -1
  191. reflex/components/react_player/video.py +0 -2
  192. reflex/components/react_player/video.pyi +0 -3
  193. reflex/components/recharts/__init__.py +1 -1
  194. reflex/components/recharts/__init__.pyi +1 -1
  195. reflex/components/recharts/cartesian.py +20 -25
  196. reflex/components/recharts/cartesian.pyi +20 -37
  197. reflex/components/recharts/charts.py +2 -1
  198. reflex/components/recharts/charts.pyi +0 -12
  199. reflex/components/recharts/general.pyi +0 -6
  200. reflex/components/recharts/polar.py +5 -4
  201. reflex/components/recharts/polar.pyi +4 -10
  202. reflex/components/recharts/recharts.py +12 -10
  203. reflex/components/recharts/recharts.pyi +10 -11
  204. reflex/components/sonner/toast.py +2 -2
  205. reflex/components/sonner/toast.pyi +0 -2
  206. reflex/components/suneditor/editor.py +2 -1
  207. reflex/components/suneditor/editor.pyi +0 -1
  208. reflex/components/tags/iter_tag.py +4 -2
  209. reflex/config.py +47 -35
  210. reflex/constants/base.py +3 -3
  211. reflex/constants/compiler.py +8 -6
  212. reflex/constants/installer.py +24 -15
  213. reflex/custom_components/custom_components.py +1 -2
  214. reflex/event.py +58 -60
  215. reflex/experimental/__init__.py +2 -2
  216. reflex/experimental/client_state.py +9 -4
  217. reflex/experimental/layout.pyi +0 -5
  218. reflex/istate/manager.py +15 -19
  219. reflex/istate/proxy.py +19 -12
  220. reflex/model.py +6 -4
  221. reflex/plugins/base.py +8 -0
  222. reflex/plugins/tailwind_v3.py +8 -0
  223. reflex/plugins/tailwind_v4.py +8 -0
  224. reflex/reflex.py +9 -11
  225. reflex/route.py +7 -9
  226. reflex/state.py +66 -70
  227. reflex/style.py +3 -1
  228. reflex/testing.py +46 -29
  229. reflex/utils/build.py +2 -1
  230. reflex/utils/console.py +9 -17
  231. reflex/utils/exec.py +9 -11
  232. reflex/utils/format.py +21 -24
  233. reflex/utils/imports.py +4 -3
  234. reflex/utils/lazy_loader.py +3 -3
  235. reflex/utils/misc.py +2 -1
  236. reflex/utils/net.py +2 -2
  237. reflex/utils/path_ops.py +2 -1
  238. reflex/utils/prerequisites.py +67 -38
  239. reflex/utils/processes.py +4 -6
  240. reflex/utils/pyi_generator.py +46 -41
  241. reflex/utils/redir.py +1 -1
  242. reflex/utils/serializers.py +4 -4
  243. reflex/utils/telemetry.py +20 -2
  244. reflex/utils/types.py +16 -13
  245. reflex/vars/base.py +96 -109
  246. reflex/vars/datetime.py +2 -1
  247. reflex/vars/dep_tracking.py +19 -28
  248. reflex/vars/number.py +6 -7
  249. reflex/vars/object.py +5 -6
  250. reflex/vars/sequence.py +11 -11
  251. {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/METADATA +1 -1
  252. reflex-0.7.14a2.dist-info/RECORD +407 -0
  253. reflex-0.7.13a2.dist-info/RECORD +0 -407
  254. {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/WHEEL +0 -0
  255. {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/entry_points.txt +0 -0
  256. {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/licenses/LICENSE +0 -0
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__}()"
@@ -253,3 +253,11 @@ class Plugin(PluginBase):
253
253
  str(Path(Dirs.STYLES) / (PageNames.STYLESHEET_ROOT + Ext.CSS)),
254
254
  add_tailwind_to_css_file,
255
255
  )
256
+
257
+ def __repr__(self):
258
+ """Return a string representation of the plugin.
259
+
260
+ Returns:
261
+ A string representation of the plugin.
262
+ """
263
+ return "TailwindV3Plugin()"
@@ -256,3 +256,11 @@ class Plugin(PluginBase):
256
256
  str(Path(Dirs.STYLES) / (PageNames.STYLESHEET_ROOT + Ext.CSS)),
257
257
  add_tailwind_to_css_file,
258
258
  )
259
+
260
+ def __repr__(self):
261
+ """Return a string representation of the plugin.
262
+
263
+ Returns:
264
+ A string representation of the plugin.
265
+ """
266
+ return "TailwindV4Plugin()"
reflex/reflex.py CHANGED
@@ -36,7 +36,6 @@ def set_loglevel(ctx: click.Context, self: click.Parameter, value: str | None):
36
36
  @click.version_option(constants.Reflex.VERSION, message="%(version)s")
37
37
  def cli():
38
38
  """Reflex CLI to create, run, and deploy apps."""
39
- pass
40
39
 
41
40
 
42
41
  loglevel_option = click.option(
@@ -202,6 +201,9 @@ def _run(
202
201
  # Get the app module.
203
202
  app_task = prerequisites.compile_or_validate_app
204
203
  args = (frontend,)
204
+ kwargs = {
205
+ "check_if_schema_up_to_date": True,
206
+ }
205
207
 
206
208
  # Granian fails if the app is already imported.
207
209
  if should_use_granian():
@@ -210,16 +212,15 @@ def _run(
210
212
  compile_future = concurrent.futures.ProcessPoolExecutor(max_workers=1).submit(
211
213
  app_task,
212
214
  *args,
215
+ **kwargs,
213
216
  )
214
217
  validation_result = compile_future.result()
215
218
  else:
216
- validation_result = app_task(*args)
219
+ validation_result = app_task(*args, **kwargs)
220
+
217
221
  if not validation_result:
218
222
  raise click.exceptions.Exit(1)
219
223
 
220
- # Warn if schema is not up to date.
221
- prerequisites.check_schema_up_to_date()
222
-
223
224
  # Get the frontend and backend commands, based on the environment.
224
225
  setup_frontend = frontend_cmd = backend_cmd = None
225
226
  if env == constants.Env.DEV:
@@ -235,7 +236,8 @@ def _run(
235
236
  exec.run_backend_prod,
236
237
  )
237
238
  if not setup_frontend or not frontend_cmd or not backend_cmd:
238
- raise ValueError(f"Invalid env: {env}. Must be DEV or PROD.")
239
+ msg = f"Invalid env: {env}. Must be DEV or PROD."
240
+ raise ValueError(msg)
239
241
 
240
242
  # Post a telemetry event.
241
243
  telemetry.send(f"run-{env.value}")
@@ -481,13 +483,11 @@ def logout():
481
483
  @click.group
482
484
  def db_cli():
483
485
  """Subcommands for managing the database schema."""
484
- pass
485
486
 
486
487
 
487
488
  @click.group
488
489
  def script_cli():
489
490
  """Subcommands for running helper scripts."""
490
- pass
491
491
 
492
492
 
493
493
  def _skip_compile():
@@ -531,9 +531,7 @@ def migrate():
531
531
  from reflex import model
532
532
  from reflex.utils import prerequisites
533
533
 
534
- # TODO see if we can use `get_app()` instead (no compile). Would _skip_compile still be needed then?
535
- _skip_compile()
536
- prerequisites.get_compiled_app()
534
+ prerequisites.get_app()
537
535
  if not prerequisites.check_db_initialized():
538
536
  return
539
537
  model.Model.migrate()
reflex/route.py CHANGED
@@ -18,11 +18,13 @@ def verify_route_validity(route: str) -> None:
18
18
  """
19
19
  pattern = catchall_in_route(route)
20
20
  if pattern and not route.endswith(pattern):
21
- raise ValueError(f"Catch-all must be the last part of the URL: {route}")
21
+ msg = f"Catch-all must be the last part of the URL: {route}"
22
+ raise ValueError(msg)
22
23
  if route == "api" or route.startswith("api/"):
23
- raise ValueError(
24
+ msg = (
24
25
  f"Cannot have a route prefixed with 'api/': {route} (conflicts with NextJS)"
25
26
  )
27
+ raise ValueError(msg)
26
28
 
27
29
 
28
30
  def get_route_args(route: str) -> dict[str, str]:
@@ -48,9 +50,8 @@ def get_route_args(route: str) -> dict[str, str]:
48
50
  """
49
51
  arg_name = match.groups()[0]
50
52
  if arg_name in args:
51
- raise ValueError(
52
- f"Arg name [{arg_name}] is used more than once in this URL"
53
- )
53
+ msg = f"Arg name [{arg_name}] is used more than once in this URL"
54
+ raise ValueError(msg)
54
55
  args[arg_name] = type_
55
56
 
56
57
  # Regex to check for route args.
@@ -136,7 +137,4 @@ def replace_brackets_with_keywords(input_string: str) -> str:
136
137
  r"\[\[.+?\]\]", constants.RouteRegex.DOUBLE_SEGMENT, output_string
137
138
  )
138
139
  # Replace [<slug>] with __SINGLE_SEGMENT__
139
- output_string = re.sub(
140
- r"\[.+?\]", constants.RouteRegex.SINGLE_SEGMENT, output_string
141
- )
142
- return output_string
140
+ return re.sub(r"\[.+?\]", constants.RouteRegex.SINGLE_SEGMENT, output_string)