reflex 0.7.1a3__py3-none-any.whl → 0.7.2a1__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 (226) hide show
  1. reflex/.templates/jinja/web/utils/context.js.jinja2 +8 -8
  2. reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +3 -3
  3. reflex/admin.py +1 -2
  4. reflex/app.py +53 -50
  5. reflex/app_mixins/lifespan.py +2 -2
  6. reflex/app_mixins/middleware.py +1 -2
  7. reflex/assets.py +1 -2
  8. reflex/base.py +2 -2
  9. reflex/compiler/compiler.py +51 -16
  10. reflex/compiler/utils.py +4 -13
  11. reflex/components/base/app_wrap.pyi +7 -7
  12. reflex/components/base/bare.py +3 -3
  13. reflex/components/base/body.pyi +7 -7
  14. reflex/components/base/document.py +1 -3
  15. reflex/components/base/document.pyi +32 -32
  16. reflex/components/base/error_boundary.py +2 -4
  17. reflex/components/base/error_boundary.pyi +11 -13
  18. reflex/components/base/fragment.pyi +7 -7
  19. reflex/components/base/head.pyi +13 -13
  20. reflex/components/base/link.pyi +22 -22
  21. reflex/components/base/meta.py +5 -7
  22. reflex/components/base/meta.pyi +40 -40
  23. reflex/components/base/script.pyi +11 -14
  24. reflex/components/base/strict_mode.pyi +7 -7
  25. reflex/components/component.py +188 -113
  26. reflex/components/core/auto_scroll.py +8 -1
  27. reflex/components/core/auto_scroll.pyi +183 -210
  28. reflex/components/core/banner.py +2 -4
  29. reflex/components/core/banner.pyi +390 -444
  30. reflex/components/core/breakpoints.py +5 -5
  31. reflex/components/core/client_side_routing.pyi +14 -14
  32. reflex/components/core/clipboard.py +4 -4
  33. reflex/components/core/clipboard.pyi +12 -14
  34. reflex/components/core/cond.py +17 -25
  35. reflex/components/core/debounce.py +3 -3
  36. reflex/components/core/debounce.pyi +14 -14
  37. reflex/components/core/foreach.py +7 -2
  38. reflex/components/core/html.py +1 -3
  39. reflex/components/core/html.pyi +184 -213
  40. reflex/components/core/match.py +15 -19
  41. reflex/components/core/sticky.pyi +930 -1078
  42. reflex/components/core/upload.py +4 -4
  43. reflex/components/core/upload.pyi +62 -62
  44. reflex/components/datadisplay/code.py +6 -6
  45. reflex/components/datadisplay/code.pyi +1159 -1165
  46. reflex/components/datadisplay/dataeditor.py +49 -49
  47. reflex/components/datadisplay/dataeditor.pyi +95 -123
  48. reflex/components/datadisplay/logo.py +1 -3
  49. reflex/components/datadisplay/shiki_code_block.py +8 -10
  50. reflex/components/datadisplay/shiki_code_block.pyi +1678 -1720
  51. reflex/components/el/element.pyi +7 -7
  52. reflex/components/el/elements/base.pyi +183 -210
  53. reflex/components/el/elements/forms.py +23 -23
  54. reflex/components/el/elements/forms.pyi +2571 -2933
  55. reflex/components/el/elements/inline.py +4 -4
  56. reflex/components/el/elements/inline.pyi +5191 -5953
  57. reflex/components/el/elements/media.py +47 -47
  58. reflex/components/el/elements/media.pyi +4802 -5500
  59. reflex/components/el/elements/metadata.py +1 -3
  60. reflex/components/el/elements/metadata.pyi +782 -896
  61. reflex/components/el/elements/other.pyi +1278 -1467
  62. reflex/components/el/elements/scripts.pyi +580 -667
  63. reflex/components/el/elements/sectioning.pyi +2761 -3166
  64. reflex/components/el/elements/tables.pyi +1840 -2119
  65. reflex/components/el/elements/typography.pyi +2772 -3179
  66. reflex/components/gridjs/datatable.py +7 -7
  67. reflex/components/gridjs/datatable.pyi +19 -19
  68. reflex/components/lucide/icon.pyi +21 -21
  69. reflex/components/markdown/markdown.py +2 -2
  70. reflex/components/markdown/markdown.pyi +9 -9
  71. reflex/components/moment/moment.py +11 -12
  72. reflex/components/moment/moment.pyi +44 -47
  73. reflex/components/next/base.pyi +7 -7
  74. reflex/components/next/image.py +3 -3
  75. reflex/components/next/image.pyi +19 -21
  76. reflex/components/next/link.pyi +9 -9
  77. reflex/components/next/video.py +1 -3
  78. reflex/components/next/video.pyi +9 -9
  79. reflex/components/plotly/plotly.py +22 -45
  80. reflex/components/plotly/plotly.pyi +164 -164
  81. reflex/components/radix/primitives/accordion.py +14 -14
  82. reflex/components/radix/primitives/accordion.pyi +439 -487
  83. reflex/components/radix/primitives/base.py +1 -3
  84. reflex/components/radix/primitives/base.pyi +15 -15
  85. reflex/components/radix/primitives/drawer.py +3 -3
  86. reflex/components/radix/primitives/drawer.pyi +110 -116
  87. reflex/components/radix/primitives/form.py +1 -1
  88. reflex/components/radix/primitives/form.pyi +668 -752
  89. reflex/components/radix/primitives/progress.py +6 -6
  90. reflex/components/radix/primitives/progress.pyi +225 -243
  91. reflex/components/radix/primitives/slider.py +6 -6
  92. reflex/components/radix/primitives/slider.pyi +52 -55
  93. reflex/components/radix/themes/base.py +3 -6
  94. reflex/components/radix/themes/base.pyi +197 -303
  95. reflex/components/radix/themes/color_mode.py +5 -5
  96. reflex/components/radix/themes/color_mode.pyi +366 -436
  97. reflex/components/radix/themes/components/alert_dialog.pyi +229 -262
  98. reflex/components/radix/themes/components/aspect_ratio.py +1 -3
  99. reflex/components/radix/themes/components/aspect_ratio.pyi +8 -8
  100. reflex/components/radix/themes/components/avatar.pyi +79 -94
  101. reflex/components/radix/themes/components/badge.pyi +252 -295
  102. reflex/components/radix/themes/components/button.pyi +269 -314
  103. reflex/components/radix/themes/components/callout.py +2 -2
  104. reflex/components/radix/themes/components/callout.pyi +1116 -1290
  105. reflex/components/radix/themes/components/card.pyi +194 -229
  106. reflex/components/radix/themes/components/checkbox.pyi +243 -278
  107. reflex/components/radix/themes/components/checkbox_cards.py +3 -7
  108. reflex/components/radix/themes/components/checkbox_cards.pyi +101 -135
  109. reflex/components/radix/themes/components/checkbox_group.py +2 -2
  110. reflex/components/radix/themes/components/checkbox_group.pyi +83 -96
  111. reflex/components/radix/themes/components/context_menu.py +18 -15
  112. reflex/components/radix/themes/components/context_menu.pyi +408 -458
  113. reflex/components/radix/themes/components/data_list.pyi +122 -147
  114. reflex/components/radix/themes/components/dialog.pyi +231 -264
  115. reflex/components/radix/themes/components/dropdown_menu.py +16 -13
  116. reflex/components/radix/themes/components/dropdown_menu.pyi +223 -246
  117. reflex/components/radix/themes/components/hover_card.py +2 -2
  118. reflex/components/radix/themes/components/hover_card.pyi +237 -282
  119. reflex/components/radix/themes/components/icon_button.pyi +269 -314
  120. reflex/components/radix/themes/components/inset.py +8 -8
  121. reflex/components/radix/themes/components/inset.pyi +232 -292
  122. reflex/components/radix/themes/components/popover.py +2 -2
  123. reflex/components/radix/themes/components/popover.pyi +229 -271
  124. reflex/components/radix/themes/components/progress.pyi +80 -96
  125. reflex/components/radix/themes/components/radio.pyi +73 -86
  126. reflex/components/radix/themes/components/radio_cards.py +4 -8
  127. reflex/components/radix/themes/components/radio_cards.pyi +117 -154
  128. reflex/components/radix/themes/components/radio_group.py +3 -3
  129. reflex/components/radix/themes/components/radio_group.pyi +250 -291
  130. reflex/components/radix/themes/components/scroll_area.pyi +14 -20
  131. reflex/components/radix/themes/components/segmented_control.py +6 -6
  132. reflex/components/radix/themes/components/segmented_control.pyi +89 -108
  133. reflex/components/radix/themes/components/select.py +7 -7
  134. reflex/components/radix/themes/components/select.pyi +376 -444
  135. reflex/components/radix/themes/components/separator.pyi +79 -93
  136. reflex/components/radix/themes/components/skeleton.pyi +32 -26
  137. reflex/components/radix/themes/components/slider.py +8 -8
  138. reflex/components/radix/themes/components/slider.pyi +99 -122
  139. reflex/components/radix/themes/components/spinner.pyi +12 -19
  140. reflex/components/radix/themes/components/switch.pyi +84 -99
  141. reflex/components/radix/themes/components/table.py +9 -9
  142. reflex/components/radix/themes/components/table.pyi +1440 -1794
  143. reflex/components/radix/themes/components/tabs.py +4 -4
  144. reflex/components/radix/themes/components/tabs.pyi +120 -132
  145. reflex/components/radix/themes/components/text_area.pyi +281 -331
  146. reflex/components/radix/themes/components/text_field.py +2 -2
  147. reflex/components/radix/themes/components/text_field.pyi +639 -734
  148. reflex/components/radix/themes/components/tooltip.py +6 -6
  149. reflex/components/radix/themes/components/tooltip.pyi +34 -43
  150. reflex/components/radix/themes/layout/base.pyi +85 -182
  151. reflex/components/radix/themes/layout/box.pyi +183 -210
  152. reflex/components/radix/themes/layout/center.pyi +225 -286
  153. reflex/components/radix/themes/layout/container.pyi +191 -224
  154. reflex/components/radix/themes/layout/flex.py +2 -2
  155. reflex/components/radix/themes/layout/flex.pyi +225 -286
  156. reflex/components/radix/themes/layout/grid.py +2 -2
  157. reflex/components/radix/themes/layout/grid.pyi +245 -315
  158. reflex/components/radix/themes/layout/list.py +2 -2
  159. reflex/components/radix/themes/layout/list.pyi +712 -815
  160. reflex/components/radix/themes/layout/section.pyi +187 -221
  161. reflex/components/radix/themes/layout/spacer.pyi +225 -286
  162. reflex/components/radix/themes/layout/stack.pyi +625 -768
  163. reflex/components/radix/themes/typography/blockquote.pyi +257 -299
  164. reflex/components/radix/themes/typography/code.pyi +259 -304
  165. reflex/components/radix/themes/typography/heading.pyi +272 -324
  166. reflex/components/radix/themes/typography/link.pyi +302 -358
  167. reflex/components/radix/themes/typography/text.pyi +1669 -1945
  168. reflex/components/react_player/audio.pyi +20 -22
  169. reflex/components/react_player/react_player.pyi +19 -19
  170. reflex/components/react_player/video.pyi +20 -22
  171. reflex/components/recharts/cartesian.py +100 -97
  172. reflex/components/recharts/cartesian.pyi +891 -1007
  173. reflex/components/recharts/charts.py +42 -42
  174. reflex/components/recharts/charts.pyi +212 -249
  175. reflex/components/recharts/general.py +22 -21
  176. reflex/components/recharts/general.pyi +198 -223
  177. reflex/components/recharts/polar.py +42 -45
  178. reflex/components/recharts/polar.pyi +254 -288
  179. reflex/components/recharts/recharts.pyi +13 -13
  180. reflex/components/sonner/toast.py +20 -20
  181. reflex/components/sonner/toast.pyi +58 -61
  182. reflex/components/suneditor/editor.py +9 -9
  183. reflex/components/suneditor/editor.pyi +78 -83
  184. reflex/components/tags/cond_tag.py +2 -2
  185. reflex/components/tags/iter_tag.py +10 -14
  186. reflex/components/tags/match_tag.py +2 -2
  187. reflex/components/tags/tag.py +10 -10
  188. reflex/config.py +36 -35
  189. reflex/constants/__init__.py +56 -53
  190. reflex/custom_components/custom_components.py +6 -7
  191. reflex/event.py +38 -42
  192. reflex/experimental/client_state.py +2 -4
  193. reflex/experimental/layout.py +2 -2
  194. reflex/experimental/layout.pyi +579 -663
  195. reflex/istate/data.py +4 -5
  196. reflex/middleware/hydrate_middleware.py +2 -2
  197. reflex/middleware/middleware.py +2 -2
  198. reflex/model.py +3 -5
  199. reflex/page.py +2 -2
  200. reflex/reflex.py +9 -10
  201. reflex/state.py +77 -49
  202. reflex/style.py +9 -3
  203. reflex/testing.py +21 -24
  204. reflex/utils/console.py +1 -1
  205. reflex/utils/decorator.py +26 -1
  206. reflex/utils/exec.py +6 -11
  207. reflex/utils/export.py +2 -3
  208. reflex/utils/format.py +4 -4
  209. reflex/utils/imports.py +12 -12
  210. reflex/utils/prerequisites.py +35 -84
  211. reflex/utils/processes.py +5 -5
  212. reflex/utils/pyi_generator.py +33 -22
  213. reflex/utils/serializers.py +60 -15
  214. reflex/utils/types.py +237 -56
  215. reflex/vars/base.py +122 -72
  216. reflex/vars/datetime.py +2 -2
  217. reflex/vars/function.py +52 -55
  218. reflex/vars/number.py +59 -5
  219. reflex/vars/object.py +57 -26
  220. reflex/vars/sequence.py +983 -958
  221. {reflex-0.7.1a3.dist-info → reflex-0.7.2a1.dist-info}/METADATA +3 -6
  222. reflex-0.7.2a1.dist-info/RECORD +405 -0
  223. {reflex-0.7.1a3.dist-info → reflex-0.7.2a1.dist-info}/WHEEL +1 -1
  224. reflex-0.7.1a3.dist-info/RECORD +0 -405
  225. {reflex-0.7.1a3.dist-info → reflex-0.7.2a1.dist-info}/LICENSE +0 -0
  226. {reflex-0.7.1a3.dist-info → reflex-0.7.2a1.dist-info}/entry_points.txt +0 -0
@@ -78,9 +78,9 @@ export function UploadFilesProvider({ children }) {
78
78
  return newFilesById
79
79
  })
80
80
  return (
81
- <UploadFilesContext.Provider value={[filesById, setFilesById]}>
81
+ <UploadFilesContext value={[filesById, setFilesById]}>
82
82
  {children}
83
- </UploadFilesContext.Provider>
83
+ </UploadFilesContext>
84
84
  )
85
85
  }
86
86
 
@@ -92,9 +92,9 @@ export function EventLoopProvider({ children }) {
92
92
  clientStorage,
93
93
  )
94
94
  return (
95
- <EventLoopContext.Provider value={[addEvents, connectErrors]}>
95
+ <EventLoopContext value={[addEvents, connectErrors]}>
96
96
  {children}
97
- </EventLoopContext.Provider>
97
+ </EventLoopContext>
98
98
  )
99
99
  }
100
100
 
@@ -112,13 +112,13 @@ export function StateProvider({ children }) {
112
112
 
113
113
  return (
114
114
  {% for state_name in initial_state %}
115
- <StateContexts.{{state_name|var_name}}.Provider value={ {{state_name|var_name}} }>
115
+ <StateContexts.{{state_name|var_name}} value={ {{state_name|var_name}} }>
116
116
  {% endfor %}
117
- <DispatchContext.Provider value={dispatchers}>
117
+ <DispatchContext value={dispatchers}>
118
118
  {children}
119
- </DispatchContext.Provider>
119
+ </DispatchContext>
120
120
  {% for state_name in initial_state|reverse %}
121
- </StateContexts.{{state_name|var_name}}.Provider>
121
+ </StateContexts.{{state_name|var_name}}>
122
122
  {% endfor %}
123
123
  )
124
124
  }
@@ -36,17 +36,17 @@ export default function RadixThemesColorModeProvider({ children }) {
36
36
  const allowedModes = ["light", "dark", "system"];
37
37
  if (!allowedModes.includes(mode)) {
38
38
  console.error(
39
- `Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`
39
+ `Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`,
40
40
  );
41
41
  mode = defaultColorMode;
42
42
  }
43
43
  setTheme(mode);
44
44
  };
45
45
  return (
46
- <ColorModeContext.Provider
46
+ <ColorModeContext
47
47
  value={{ rawColorMode, resolvedColorMode, toggleColorMode, setColorMode }}
48
48
  >
49
49
  {children}
50
- </ColorModeContext.Provider>
50
+ </ColorModeContext>
51
51
  );
52
52
  }
reflex/admin.py CHANGED
@@ -1,7 +1,6 @@
1
1
  """The Reflex Admin Dashboard."""
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from typing import Optional
5
4
 
6
5
  from starlette_admin.base import BaseAdmin as Admin
7
6
 
@@ -12,4 +11,4 @@ class AdminDash:
12
11
 
13
12
  models: list = field(default_factory=list)
14
13
  view_overrides: dict = field(default_factory=dict)
15
- admin: Optional[Admin] = None
14
+ admin: Admin | None = None
reflex/app.py CHANGED
@@ -25,12 +25,8 @@ from typing import (
25
25
  Callable,
26
26
  Coroutine,
27
27
  Dict,
28
- List,
29
28
  MutableMapping,
30
- Optional,
31
- Set,
32
29
  Type,
33
- Union,
34
30
  get_args,
35
31
  get_type_hints,
36
32
  )
@@ -167,7 +163,7 @@ def default_backend_exception_handler(exception: Exception) -> EventSpec:
167
163
  )
168
164
 
169
165
 
170
- def extra_overlay_function() -> Optional[Component]:
166
+ def extra_overlay_function() -> Component | None:
171
167
  """Extra overlay function to add to the overlay component.
172
168
 
173
169
  Returns:
@@ -250,16 +246,16 @@ class UploadFile(StarletteUploadFile):
250
246
 
251
247
  file: BinaryIO
252
248
 
253
- path: Optional[Path] = dataclasses.field(default=None)
249
+ path: Path | None = dataclasses.field(default=None)
254
250
 
255
- _deprecated_filename: Optional[str] = dataclasses.field(default=None)
251
+ _deprecated_filename: str | None = dataclasses.field(default=None)
256
252
 
257
- size: Optional[int] = dataclasses.field(default=None)
253
+ size: int | None = dataclasses.field(default=None)
258
254
 
259
255
  headers: Headers = dataclasses.field(default_factory=Headers)
260
256
 
261
257
  @property
262
- def name(self) -> Optional[str]:
258
+ def name(self) -> str | None:
263
259
  """Get the name of the uploaded file.
264
260
 
265
261
  Returns:
@@ -269,7 +265,7 @@ class UploadFile(StarletteUploadFile):
269
265
  return self.path.name
270
266
 
271
267
  @property
272
- def filename(self) -> Optional[str]:
268
+ def filename(self) -> str | None:
273
269
  """Get the filename of the uploaded file.
274
270
 
275
271
  Returns:
@@ -290,13 +286,13 @@ class UploadFile(StarletteUploadFile):
290
286
  class UnevaluatedPage:
291
287
  """An uncompiled page."""
292
288
 
293
- component: Union[Component, ComponentCallable]
289
+ component: Component | ComponentCallable
294
290
  route: str
295
- title: Union[Var, str, None]
296
- description: Union[Var, str, None]
291
+ title: Var | str | None
292
+ description: Var | str | None
297
293
  image: str
298
- on_load: Union[EventType[()], None]
299
- meta: List[Dict[str, str]]
294
+ on_load: EventType[()] | None
295
+ meta: list[dict[str, str]]
300
296
 
301
297
 
302
298
  @dataclasses.dataclass()
@@ -322,7 +318,7 @@ class App(MiddlewareMixin, LifespanMixin):
322
318
  """
323
319
 
324
320
  # The global [theme](https://reflex.dev/docs/styling/theming/#theme) for the entire app.
325
- theme: Optional[Component] = dataclasses.field(
321
+ theme: Component | None = dataclasses.field(
326
322
  default_factory=lambda: themes.theme(accent_color="blue")
327
323
  )
328
324
 
@@ -330,18 +326,18 @@ class App(MiddlewareMixin, LifespanMixin):
330
326
  style: ComponentStyle = dataclasses.field(default_factory=dict)
331
327
 
332
328
  # A list of URLs to [stylesheets](https://reflex.dev/docs/styling/custom-stylesheets/) to include in the app.
333
- stylesheets: List[str] = dataclasses.field(default_factory=list)
329
+ stylesheets: list[str] = dataclasses.field(default_factory=list)
334
330
 
335
331
  # A component that is present on every page (defaults to the Connection Error banner).
336
- overlay_component: Optional[Union[Component, ComponentCallable]] = (
337
- dataclasses.field(default=None)
332
+ overlay_component: Component | ComponentCallable | None = dataclasses.field(
333
+ default=None
338
334
  )
339
335
 
340
336
  # Error boundary component to wrap the app with.
341
- error_boundary: Optional[ComponentCallable] = dataclasses.field(default=None)
337
+ error_boundary: ComponentCallable | None = dataclasses.field(default=None)
342
338
 
343
339
  # App wraps to be applied to the whole app. Expected to be a dictionary of (order, name) to a function that takes whether the state is enabled and optionally returns a component.
344
- app_wraps: Dict[tuple[int, str], Callable[[bool], Optional[Component]]] = (
340
+ app_wraps: dict[tuple[int, str], Callable[[bool], Component | None]] = (
345
341
  dataclasses.field(
346
342
  default_factory=lambda: {
347
343
  (55, "ErrorBoundary"): (
@@ -356,24 +352,24 @@ class App(MiddlewareMixin, LifespanMixin):
356
352
  )
357
353
 
358
354
  # Components to add to the head of every page.
359
- head_components: List[Component] = dataclasses.field(default_factory=list)
355
+ head_components: list[Component] = dataclasses.field(default_factory=list)
360
356
 
361
357
  # The Socket.IO AsyncServer instance.
362
- sio: Optional[AsyncServer] = None
358
+ sio: AsyncServer | None = None
363
359
 
364
360
  # The language to add to the html root tag of every page.
365
- html_lang: Optional[str] = None
361
+ html_lang: str | None = None
366
362
 
367
363
  # Attributes to add to the html root tag of every page.
368
- html_custom_attrs: Optional[Dict[str, str]] = None
364
+ html_custom_attrs: dict[str, str] | None = None
369
365
 
370
366
  # A map from a route to an unevaluated page.
371
- _unevaluated_pages: Dict[str, UnevaluatedPage] = dataclasses.field(
367
+ _unevaluated_pages: dict[str, UnevaluatedPage] = dataclasses.field(
372
368
  default_factory=dict
373
369
  )
374
370
 
375
371
  # A map from a page route to the component to render. Users should use `add_page`.
376
- _pages: Dict[str, Component] = dataclasses.field(default_factory=dict)
372
+ _pages: dict[str, Component] = dataclasses.field(default_factory=dict)
377
373
 
378
374
  # A mapping of pages which created states as they were being evaluated.
379
375
  _stateful_pages: Dict[str, None] = dataclasses.field(default_factory=dict)
@@ -382,24 +378,24 @@ class App(MiddlewareMixin, LifespanMixin):
382
378
  _api: FastAPI | None = None
383
379
 
384
380
  # The state class to use for the app.
385
- _state: Optional[Type[BaseState]] = None
381
+ _state: Type[BaseState] | None = None
386
382
 
387
383
  # Class to manage many client states.
388
- _state_manager: Optional[StateManager] = None
384
+ _state_manager: StateManager | None = None
389
385
 
390
386
  # Mapping from a route to event handlers to trigger when the page loads.
391
- _load_events: Dict[str, List[IndividualEventType[()]]] = dataclasses.field(
387
+ _load_events: dict[str, list[IndividualEventType[()]]] = dataclasses.field(
392
388
  default_factory=dict
393
389
  )
394
390
 
395
391
  # Admin dashboard to view and manage the database.
396
- admin_dash: Optional[AdminDash] = None
392
+ admin_dash: AdminDash | None = None
397
393
 
398
394
  # The async server name space.
399
- _event_namespace: Optional[EventNamespace] = None
395
+ _event_namespace: EventNamespace | None = None
400
396
 
401
397
  # Background tasks that are currently running.
402
- _background_tasks: Set[asyncio.Task] = dataclasses.field(default_factory=set)
398
+ _background_tasks: set[asyncio.Task] = dataclasses.field(default_factory=set)
403
399
 
404
400
  # Frontend Error Handler Function
405
401
  frontend_exception_handler: Callable[[Exception], None] = (
@@ -408,7 +404,7 @@ class App(MiddlewareMixin, LifespanMixin):
408
404
 
409
405
  # Backend Error Handler Function
410
406
  backend_exception_handler: Callable[
411
- [Exception], Union[EventSpec, List[EventSpec], None]
407
+ [Exception], EventSpec | list[EventSpec] | None
412
408
  ] = default_backend_exception_handler
413
409
 
414
410
  # Put the toast provider in the app wrap.
@@ -895,7 +891,7 @@ class App(MiddlewareMixin, LifespanMixin):
895
891
 
896
892
  admin.mount_to(self.api)
897
893
 
898
- def _get_frontend_packages(self, imports: Dict[str, set[ImportVar]]):
894
+ def _get_frontend_packages(self, imports: dict[str, set[ImportVar]]):
899
895
  """Gets the frontend packages to be installed and filters out the unnecessary ones.
900
896
 
901
897
  Args:
@@ -986,12 +982,15 @@ class App(MiddlewareMixin, LifespanMixin):
986
982
 
987
983
  def _setup_sticky_badge(self):
988
984
  """Add the sticky badge to the app."""
989
- for k, component in self._pages.items():
990
- # Would be nice to share single sticky_badge across all pages, but
991
- # it bungles the StatefulComponent compile step.
985
+ from reflex.components.component import memo
986
+
987
+ @memo
988
+ def memoized_badge():
992
989
  sticky_badge = sticky()
993
990
  sticky_badge._add_style_recursive({})
994
- self._pages[k] = Fragment.create(sticky_badge, component)
991
+ return sticky_badge
992
+
993
+ self.app_wraps[(0, "StickyBadge")] = lambda _: memoized_badge()
995
994
 
996
995
  def _apply_decorated_pages(self):
997
996
  """Add @rx.page decorated pages to the app.
@@ -1006,9 +1005,7 @@ class App(MiddlewareMixin, LifespanMixin):
1006
1005
  for render, kwargs in DECORATED_PAGES[get_config().app_name]:
1007
1006
  self.add_page(render, **kwargs)
1008
1007
 
1009
- def _validate_var_dependencies(
1010
- self, state: Optional[Type[BaseState]] = None
1011
- ) -> None:
1008
+ def _validate_var_dependencies(self, state: Type[BaseState] | None = None) -> None:
1012
1009
  """Validate the dependencies of the vars in the app.
1013
1010
 
1014
1011
  Args:
@@ -1080,7 +1077,7 @@ class App(MiddlewareMixin, LifespanMixin):
1080
1077
  self.style = evaluate_style_namespaces(self.style)
1081
1078
 
1082
1079
  # Add the app wrappers.
1083
- app_wrappers: Dict[tuple[int, str], Component] = {
1080
+ app_wrappers: dict[tuple[int, str], Component] = {
1084
1081
  # Default app wrap component renders {children}
1085
1082
  (0, "AppWrap"): AppWrap.create()
1086
1083
  }
@@ -1103,6 +1100,9 @@ class App(MiddlewareMixin, LifespanMixin):
1103
1100
  console.debug(f"Evaluating page: {route}")
1104
1101
  self._compile_page(route, save_page=should_compile)
1105
1102
 
1103
+ # Save the pages which created new states at eval time.
1104
+ self._write_stateful_pages_marker()
1105
+
1106
1106
  # Add the optional endpoints (_upload)
1107
1107
  self._add_optional_endpoints()
1108
1108
 
@@ -1145,6 +1145,8 @@ class App(MiddlewareMixin, LifespanMixin):
1145
1145
  )[:10]
1146
1146
  )
1147
1147
  )
1148
+ # Save the pages which created new states at eval time.
1149
+ self._write_stateful_pages_marker()
1148
1150
 
1149
1151
  # Add the optional endpoints (_upload)
1150
1152
  self._add_optional_endpoints()
@@ -1366,7 +1368,8 @@ class App(MiddlewareMixin, LifespanMixin):
1366
1368
  for output_path, code in compile_results:
1367
1369
  compiler_utils.write_page(output_path, code)
1368
1370
 
1369
- # Write list of routes that create dynamic states for backend to use.
1371
+ def _write_stateful_pages_marker(self):
1372
+ """Write list of routes that create dynamic states for the backend to use later."""
1370
1373
  if self._state is not None:
1371
1374
  stateful_pages_marker = (
1372
1375
  prerequisites.get_backend_dir() / constants.Dirs.STATEFUL_PAGES
@@ -1541,8 +1544,8 @@ class App(MiddlewareMixin, LifespanMixin):
1541
1544
 
1542
1545
  valid = bool(
1543
1546
  return_type == EventSpec
1544
- or return_type == Optional[EventSpec]
1545
- or return_type == List[EventSpec]
1547
+ or return_type == EventSpec | None
1548
+ or return_type == list[EventSpec]
1546
1549
  or return_type == inspect.Signature.empty
1547
1550
  or return_type is None
1548
1551
  )
@@ -1550,7 +1553,7 @@ class App(MiddlewareMixin, LifespanMixin):
1550
1553
  if not valid:
1551
1554
  raise ValueError(
1552
1555
  f"Provided custom {handler_domain} exception handler `{_fn_name}` has the wrong return type."
1553
- f"Expected `Union[EventSpec, List[EventSpec], None]` but got `{return_type}`"
1556
+ f"Expected `EventSpec | list[EventSpec] | None` but got `{return_type}`"
1554
1557
  )
1555
1558
 
1556
1559
 
@@ -1690,7 +1693,7 @@ def upload(app: App):
1690
1693
  The upload function.
1691
1694
  """
1692
1695
 
1693
- async def upload_file(request: Request, files: List[FastAPIUploadFile]):
1696
+ async def upload_file(request: Request, files: list[FastAPIUploadFile]):
1694
1697
  """Upload a file.
1695
1698
 
1696
1699
  Args:
@@ -1730,7 +1733,7 @@ def upload(app: App):
1730
1733
  # get handler function
1731
1734
  func = getattr(type(current_state), handler.split(".")[-1])
1732
1735
 
1733
- # check if there exists any handler args with annotation, List[UploadFile]
1736
+ # check if there exists any handler args with annotation, list[UploadFile]
1734
1737
  if isinstance(func, EventHandler):
1735
1738
  if func.is_background:
1736
1739
  raise UploadTypeError(
@@ -1750,7 +1753,7 @@ def upload(app: App):
1750
1753
  if not handler_upload_param:
1751
1754
  raise UploadValueError(
1752
1755
  f"`{handler}` handler should have a parameter annotated as "
1753
- "List[rx.UploadFile]"
1756
+ "list[rx.UploadFile]"
1754
1757
  )
1755
1758
 
1756
1759
  # Make a copy of the files as they are closed after the request.
@@ -7,7 +7,7 @@ import contextlib
7
7
  import dataclasses
8
8
  import functools
9
9
  import inspect
10
- from typing import Callable, Coroutine, Set, Union
10
+ from typing import Callable, Coroutine
11
11
 
12
12
  from fastapi import FastAPI
13
13
 
@@ -22,7 +22,7 @@ class LifespanMixin(AppMixin):
22
22
  """A Mixin that allow tasks to run during the whole app lifespan."""
23
23
 
24
24
  # Lifespan tasks that are planned to run.
25
- lifespan_tasks: Set[Union[asyncio.Task, Callable]] = dataclasses.field(
25
+ lifespan_tasks: set[asyncio.Task | Callable] = dataclasses.field(
26
26
  default_factory=set
27
27
  )
28
28
 
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import dataclasses
7
- from typing import List
8
7
 
9
8
  from reflex.event import Event
10
9
  from reflex.middleware import HydrateMiddleware, Middleware
@@ -18,7 +17,7 @@ class MiddlewareMixin(AppMixin):
18
17
  """Middleware Mixin that allow to add middleware to the app."""
19
18
 
20
19
  # Middleware to add to the app. Users should use `add_middleware`. PRIVATE.
21
- middleware: List[Middleware] = dataclasses.field(default_factory=list)
20
+ middleware: list[Middleware] = dataclasses.field(default_factory=list)
22
21
 
23
22
  def _init_mixin(self):
24
23
  self.middleware.append(HydrateMiddleware())
reflex/assets.py CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  import inspect
4
4
  from pathlib import Path
5
- from typing import Optional
6
5
 
7
6
  from reflex import constants
8
7
  from reflex.config import EnvironmentVariables
@@ -11,7 +10,7 @@ from reflex.config import EnvironmentVariables
11
10
  def asset(
12
11
  path: str,
13
12
  shared: bool = False,
14
- subfolder: Optional[str] = None,
13
+ subfolder: str | None = None,
15
14
  _stack_level: int = 1,
16
15
  ) -> str:
17
16
  """Add an asset to the app, either shared as a symlink or local.
reflex/base.py CHANGED
@@ -3,14 +3,14 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
- from typing import TYPE_CHECKING, Any, List, Type
6
+ from typing import TYPE_CHECKING, Any, Type
7
7
 
8
8
  import pydantic.v1.main as pydantic_main
9
9
  from pydantic.v1 import BaseModel
10
10
  from pydantic.v1.fields import ModelField
11
11
 
12
12
 
13
- def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None:
13
+ def validate_field_name(bases: list[Type["BaseModel"]], field_name: str) -> None:
14
14
  """Ensure that the field's name does not shadow an existing attribute of the model.
15
15
 
16
16
  Args:
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from datetime import datetime
6
6
  from pathlib import Path
7
- from typing import TYPE_CHECKING, Dict, Iterable, Optional, Sequence, Tuple, Type, Union
7
+ from typing import TYPE_CHECKING, Iterable, Sequence, Type
8
8
 
9
9
  from reflex import constants
10
10
  from reflex.compiler import templates, utils
@@ -94,7 +94,7 @@ def _compile_theme(theme: str) -> str:
94
94
  return templates.THEME.render(theme=theme)
95
95
 
96
96
 
97
- def _compile_contexts(state: Optional[Type[BaseState]], theme: Component | None) -> str:
97
+ def _compile_contexts(state: Type[BaseState] | None, theme: Component | None) -> str:
98
98
  """Compile the initial state and contexts.
99
99
 
100
100
  Args:
@@ -219,7 +219,7 @@ def _compile_component(component: Component | StatefulComponent) -> str:
219
219
 
220
220
  def _compile_components(
221
221
  components: set[CustomComponent],
222
- ) -> tuple[str, Dict[str, list[ImportVar]]]:
222
+ ) -> tuple[str, dict[str, list[ImportVar]]]:
223
223
  """Compile the components.
224
224
 
225
225
  Args:
@@ -352,8 +352,8 @@ def _compile_tailwind(
352
352
 
353
353
  def compile_document_root(
354
354
  head_components: list[Component],
355
- html_lang: Optional[str] = None,
356
- html_custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
355
+ html_lang: str | None = None,
356
+ html_custom_attrs: dict[str, Var | str] | None = None,
357
357
  ) -> tuple[str, str]:
358
358
  """Compile the document root.
359
359
 
@@ -415,7 +415,7 @@ def compile_theme(style: ComponentStyle) -> tuple[str, str]:
415
415
 
416
416
 
417
417
  def compile_contexts(
418
- state: Optional[Type[BaseState]],
418
+ state: Type[BaseState] | None,
419
419
  theme: Component | None,
420
420
  ) -> tuple[str, str]:
421
421
  """Compile the initial state / context.
@@ -456,7 +456,7 @@ def compile_page(
456
456
 
457
457
  def compile_components(
458
458
  components: set[CustomComponent],
459
- ) -> tuple[str, str, Dict[str, list[ImportVar]]]:
459
+ ) -> tuple[str, str, dict[str, list[ImportVar]]]:
460
460
  """Compile the custom components.
461
461
 
462
462
  Args:
@@ -577,14 +577,49 @@ def into_component(component: Component | ComponentCallable) -> Component:
577
577
 
578
578
  Raises:
579
579
  TypeError: If the component is not a Component.
580
+
581
+ # noqa: DAR401
580
582
  """
581
583
  if (converted := _into_component_once(component)) is not None:
582
584
  return converted
583
- if (
584
- callable(component)
585
- and (converted := _into_component_once(component())) is not None
586
- ):
587
- return converted
585
+ try:
586
+ if (
587
+ callable(component)
588
+ and (converted := _into_component_once(component())) is not None
589
+ ):
590
+ return converted
591
+ except KeyError as e:
592
+ key = e.args[0] if e.args else None
593
+ if key is not None and isinstance(key, Var):
594
+ raise TypeError(
595
+ "Cannot access a primitive map with a Var. Consider calling rx.Var.create() on the map."
596
+ ).with_traceback(e.__traceback__) from None
597
+ raise
598
+ except TypeError as e:
599
+ message = e.args[0] if e.args else None
600
+ if message and isinstance(message, str):
601
+ if message.endswith("has no len()") and (
602
+ "ArrayCastedVar" in message
603
+ or "ObjectCastedVar" in message
604
+ or "StringCastedVar" in message
605
+ ):
606
+ raise TypeError(
607
+ "Cannot pass a Var to a built-in function. Consider using .length() for accessing the length of an iterable Var."
608
+ ).with_traceback(e.__traceback__) from None
609
+ if message.endswith(
610
+ "indices must be integers or slices, not NumberCastedVar"
611
+ ) or message.endswith(
612
+ "indices must be integers or slices, not BooleanCastedVar"
613
+ ):
614
+ raise TypeError(
615
+ "Cannot index into a primitive sequence with a Var. Consider calling rx.Var.create() on the sequence."
616
+ ).with_traceback(e.__traceback__) from None
617
+ if "CastedVar" in str(e):
618
+ raise TypeError(
619
+ "Cannot pass a Var to a built-in function. Consider moving the operation to the backend, using existing Var operations, or defining a custom Var operation."
620
+ ).with_traceback(e.__traceback__) from None
621
+ raise
622
+
588
623
  raise TypeError(f"Expected a Component, got {type(component)}")
589
624
 
590
625
 
@@ -594,7 +629,7 @@ def compile_unevaluated_page(
594
629
  state: Type[BaseState] | None = None,
595
630
  style: ComponentStyle | None = None,
596
631
  theme: Component | None = None,
597
- ) -> Tuple[Component, bool]:
632
+ ) -> tuple[Component, bool]:
598
633
  """Compiles an uncompiled page into a component and adds meta information.
599
634
 
600
635
  Args:
@@ -679,9 +714,9 @@ class ExecutorSafeFunctions:
679
714
 
680
715
  """
681
716
 
682
- COMPONENTS: Dict[str, BaseComponent] = {}
683
- UNCOMPILED_PAGES: Dict[str, UnevaluatedPage] = {}
684
- STATE: Optional[Type[BaseState]] = None
717
+ COMPONENTS: dict[str, BaseComponent] = {}
718
+ UNCOMPILED_PAGES: dict[str, UnevaluatedPage] = {}
719
+ STATE: Type[BaseState] | None = None
685
720
 
686
721
  @classmethod
687
722
  def compile_page(cls, route: str) -> tuple[str, str]:
reflex/compiler/utils.py CHANGED
@@ -7,7 +7,7 @@ import concurrent.futures
7
7
  import traceback
8
8
  from datetime import datetime
9
9
  from pathlib import Path
10
- from typing import Any, Callable, Dict, Optional, Type, Union
10
+ from typing import Any, Callable, Type
11
11
  from urllib.parse import urlparse
12
12
 
13
13
  from pydantic.v1.fields import ModelField
@@ -187,16 +187,7 @@ def compile_state(state: Type[BaseState]) -> dict:
187
187
  Returns:
188
188
  A dictionary of the compiled state.
189
189
  """
190
- try:
191
- initial_state = state(_reflex_internal_init=True).dict(initial=True)
192
- except Exception as e:
193
- log_path = save_error(e)
194
- console.warn(
195
- f"Failed to compile initial state with computed vars. Error log saved to {log_path}"
196
- )
197
- initial_state = state(_reflex_internal_init=True).dict(
198
- initial=True, include_computed=False
199
- )
190
+ initial_state = state(_reflex_internal_init=True).dict(initial=True)
200
191
  try:
201
192
  _ = asyncio.get_running_loop()
202
193
  except RuntimeError:
@@ -345,8 +336,8 @@ def compile_custom_component(
345
336
 
346
337
  def create_document_root(
347
338
  head_components: list[Component] | None = None,
348
- html_lang: Optional[str] = None,
349
- html_custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
339
+ html_lang: str | None = None,
340
+ html_custom_attrs: dict[str, Var | str] | None = None,
350
341
  ) -> Component:
351
342
  """Create the document root.
352
343
 
@@ -3,7 +3,7 @@
3
3
  # ------------------- DO NOT EDIT ----------------------
4
4
  # This file was generated by `reflex/utils/pyi_generator.py`!
5
5
  # ------------------------------------------------------
6
- from typing import Any, Dict, Optional, Union, overload
6
+ from typing import Any, Optional, overload
7
7
 
8
8
  from reflex.components.base.fragment import Fragment
9
9
  from reflex.event import EventType
@@ -16,12 +16,12 @@ class AppWrap(Fragment):
16
16
  def create( # type: ignore
17
17
  cls,
18
18
  *children,
19
- style: Optional[Style] = None,
20
- key: Optional[Any] = None,
21
- id: Optional[Any] = None,
22
- class_name: Optional[Any] = None,
23
- autofocus: Optional[bool] = None,
24
- custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
19
+ style: Style | None = None,
20
+ key: Any | None = None,
21
+ id: Any | None = None,
22
+ class_name: Any | None = None,
23
+ autofocus: bool | None = None,
24
+ custom_attrs: dict[str, Var | Any] | None = None,
25
25
  on_blur: Optional[EventType[()]] = None,
26
26
  on_click: Optional[EventType[()]] = None,
27
27
  on_context_menu: Optional[EventType[()]] = None,
@@ -70,13 +70,13 @@ class Bare(Component):
70
70
  if isinstance(contents, Var):
71
71
  if isinstance(contents, LiteralStringVar):
72
72
  validate_str(contents._var_value)
73
- return cls(contents=contents)
73
+ return cls._unsafe_create(children=[], contents=contents)
74
74
  else:
75
75
  if isinstance(contents, str):
76
76
  validate_str(contents)
77
- contents = str(contents) if contents is not None else ""
77
+ contents = Var.create(contents if contents is not None else "")
78
78
 
79
- return cls(contents=contents)
79
+ return cls._unsafe_create(children=[], contents=contents)
80
80
 
81
81
  def _get_all_hooks_internal(self) -> dict[str, VarData | None]:
82
82
  """Include the hooks for the component.