reflex 0.7.1a4__py3-none-any.whl → 0.7.2a2__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 (227) 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/.templates/web/utils/state.js +18 -18
  4. reflex/admin.py +1 -2
  5. reflex/app.py +46 -49
  6. reflex/app_mixins/lifespan.py +2 -2
  7. reflex/app_mixins/middleware.py +1 -2
  8. reflex/assets.py +1 -2
  9. reflex/base.py +2 -2
  10. reflex/compiler/compiler.py +51 -16
  11. reflex/compiler/utils.py +4 -13
  12. reflex/components/base/app_wrap.pyi +7 -7
  13. reflex/components/base/bare.py +3 -3
  14. reflex/components/base/body.pyi +7 -7
  15. reflex/components/base/document.py +1 -3
  16. reflex/components/base/document.pyi +32 -32
  17. reflex/components/base/error_boundary.py +2 -4
  18. reflex/components/base/error_boundary.pyi +11 -13
  19. reflex/components/base/fragment.pyi +7 -7
  20. reflex/components/base/head.pyi +13 -13
  21. reflex/components/base/link.pyi +22 -22
  22. reflex/components/base/meta.py +5 -7
  23. reflex/components/base/meta.pyi +40 -40
  24. reflex/components/base/script.pyi +11 -14
  25. reflex/components/base/strict_mode.pyi +7 -7
  26. reflex/components/component.py +188 -113
  27. reflex/components/core/auto_scroll.py +8 -1
  28. reflex/components/core/auto_scroll.pyi +183 -210
  29. reflex/components/core/banner.py +2 -4
  30. reflex/components/core/banner.pyi +390 -444
  31. reflex/components/core/breakpoints.py +5 -5
  32. reflex/components/core/client_side_routing.pyi +14 -14
  33. reflex/components/core/clipboard.py +4 -4
  34. reflex/components/core/clipboard.pyi +12 -14
  35. reflex/components/core/cond.py +17 -25
  36. reflex/components/core/debounce.py +3 -3
  37. reflex/components/core/debounce.pyi +14 -14
  38. reflex/components/core/foreach.py +7 -2
  39. reflex/components/core/html.py +1 -3
  40. reflex/components/core/html.pyi +184 -213
  41. reflex/components/core/match.py +15 -19
  42. reflex/components/core/sticky.pyi +930 -1078
  43. reflex/components/core/upload.py +4 -4
  44. reflex/components/core/upload.pyi +62 -62
  45. reflex/components/datadisplay/code.py +6 -6
  46. reflex/components/datadisplay/code.pyi +1159 -1165
  47. reflex/components/datadisplay/dataeditor.py +49 -49
  48. reflex/components/datadisplay/dataeditor.pyi +95 -123
  49. reflex/components/datadisplay/logo.py +1 -3
  50. reflex/components/datadisplay/shiki_code_block.py +8 -10
  51. reflex/components/datadisplay/shiki_code_block.pyi +1678 -1720
  52. reflex/components/el/element.pyi +7 -7
  53. reflex/components/el/elements/base.pyi +183 -210
  54. reflex/components/el/elements/forms.py +24 -24
  55. reflex/components/el/elements/forms.pyi +2572 -2934
  56. reflex/components/el/elements/inline.py +4 -4
  57. reflex/components/el/elements/inline.pyi +5191 -5953
  58. reflex/components/el/elements/media.py +47 -47
  59. reflex/components/el/elements/media.pyi +4802 -5500
  60. reflex/components/el/elements/metadata.py +1 -3
  61. reflex/components/el/elements/metadata.pyi +782 -896
  62. reflex/components/el/elements/other.pyi +1278 -1467
  63. reflex/components/el/elements/scripts.pyi +580 -667
  64. reflex/components/el/elements/sectioning.pyi +2761 -3166
  65. reflex/components/el/elements/tables.pyi +1840 -2119
  66. reflex/components/el/elements/typography.pyi +2772 -3179
  67. reflex/components/gridjs/datatable.py +7 -7
  68. reflex/components/gridjs/datatable.pyi +19 -19
  69. reflex/components/lucide/icon.pyi +21 -21
  70. reflex/components/markdown/markdown.py +2 -2
  71. reflex/components/markdown/markdown.pyi +9 -9
  72. reflex/components/moment/moment.py +11 -12
  73. reflex/components/moment/moment.pyi +44 -47
  74. reflex/components/next/base.pyi +7 -7
  75. reflex/components/next/image.py +3 -3
  76. reflex/components/next/image.pyi +19 -21
  77. reflex/components/next/link.pyi +9 -9
  78. reflex/components/next/video.py +1 -3
  79. reflex/components/next/video.pyi +9 -9
  80. reflex/components/plotly/plotly.py +22 -45
  81. reflex/components/plotly/plotly.pyi +164 -164
  82. reflex/components/radix/primitives/accordion.py +14 -14
  83. reflex/components/radix/primitives/accordion.pyi +439 -487
  84. reflex/components/radix/primitives/base.py +1 -3
  85. reflex/components/radix/primitives/base.pyi +15 -15
  86. reflex/components/radix/primitives/drawer.py +3 -3
  87. reflex/components/radix/primitives/drawer.pyi +110 -116
  88. reflex/components/radix/primitives/form.py +1 -1
  89. reflex/components/radix/primitives/form.pyi +668 -752
  90. reflex/components/radix/primitives/progress.py +6 -6
  91. reflex/components/radix/primitives/progress.pyi +225 -243
  92. reflex/components/radix/primitives/slider.py +6 -6
  93. reflex/components/radix/primitives/slider.pyi +52 -55
  94. reflex/components/radix/themes/base.py +3 -6
  95. reflex/components/radix/themes/base.pyi +197 -303
  96. reflex/components/radix/themes/color_mode.py +5 -5
  97. reflex/components/radix/themes/color_mode.pyi +366 -436
  98. reflex/components/radix/themes/components/alert_dialog.pyi +229 -262
  99. reflex/components/radix/themes/components/aspect_ratio.py +1 -3
  100. reflex/components/radix/themes/components/aspect_ratio.pyi +8 -8
  101. reflex/components/radix/themes/components/avatar.pyi +79 -94
  102. reflex/components/radix/themes/components/badge.pyi +252 -295
  103. reflex/components/radix/themes/components/button.pyi +269 -314
  104. reflex/components/radix/themes/components/callout.py +2 -2
  105. reflex/components/radix/themes/components/callout.pyi +1116 -1290
  106. reflex/components/radix/themes/components/card.pyi +194 -229
  107. reflex/components/radix/themes/components/checkbox.pyi +243 -278
  108. reflex/components/radix/themes/components/checkbox_cards.py +3 -7
  109. reflex/components/radix/themes/components/checkbox_cards.pyi +101 -135
  110. reflex/components/radix/themes/components/checkbox_group.py +2 -2
  111. reflex/components/radix/themes/components/checkbox_group.pyi +83 -96
  112. reflex/components/radix/themes/components/context_menu.py +18 -15
  113. reflex/components/radix/themes/components/context_menu.pyi +408 -458
  114. reflex/components/radix/themes/components/data_list.pyi +122 -147
  115. reflex/components/radix/themes/components/dialog.pyi +231 -264
  116. reflex/components/radix/themes/components/dropdown_menu.py +16 -13
  117. reflex/components/radix/themes/components/dropdown_menu.pyi +223 -246
  118. reflex/components/radix/themes/components/hover_card.py +2 -2
  119. reflex/components/radix/themes/components/hover_card.pyi +237 -282
  120. reflex/components/radix/themes/components/icon_button.pyi +269 -314
  121. reflex/components/radix/themes/components/inset.py +8 -8
  122. reflex/components/radix/themes/components/inset.pyi +232 -292
  123. reflex/components/radix/themes/components/popover.py +2 -2
  124. reflex/components/radix/themes/components/popover.pyi +229 -271
  125. reflex/components/radix/themes/components/progress.pyi +80 -96
  126. reflex/components/radix/themes/components/radio.pyi +73 -86
  127. reflex/components/radix/themes/components/radio_cards.py +4 -8
  128. reflex/components/radix/themes/components/radio_cards.pyi +117 -154
  129. reflex/components/radix/themes/components/radio_group.py +3 -3
  130. reflex/components/radix/themes/components/radio_group.pyi +250 -291
  131. reflex/components/radix/themes/components/scroll_area.pyi +14 -20
  132. reflex/components/radix/themes/components/segmented_control.py +6 -6
  133. reflex/components/radix/themes/components/segmented_control.pyi +89 -108
  134. reflex/components/radix/themes/components/select.py +7 -7
  135. reflex/components/radix/themes/components/select.pyi +376 -444
  136. reflex/components/radix/themes/components/separator.pyi +79 -93
  137. reflex/components/radix/themes/components/skeleton.pyi +32 -26
  138. reflex/components/radix/themes/components/slider.py +8 -8
  139. reflex/components/radix/themes/components/slider.pyi +99 -122
  140. reflex/components/radix/themes/components/spinner.pyi +12 -19
  141. reflex/components/radix/themes/components/switch.pyi +84 -99
  142. reflex/components/radix/themes/components/table.py +9 -9
  143. reflex/components/radix/themes/components/table.pyi +1440 -1794
  144. reflex/components/radix/themes/components/tabs.py +4 -4
  145. reflex/components/radix/themes/components/tabs.pyi +120 -132
  146. reflex/components/radix/themes/components/text_area.pyi +281 -331
  147. reflex/components/radix/themes/components/text_field.py +2 -2
  148. reflex/components/radix/themes/components/text_field.pyi +639 -734
  149. reflex/components/radix/themes/components/tooltip.py +6 -6
  150. reflex/components/radix/themes/components/tooltip.pyi +34 -43
  151. reflex/components/radix/themes/layout/base.pyi +85 -182
  152. reflex/components/radix/themes/layout/box.pyi +183 -210
  153. reflex/components/radix/themes/layout/center.pyi +225 -286
  154. reflex/components/radix/themes/layout/container.pyi +191 -224
  155. reflex/components/radix/themes/layout/flex.py +2 -2
  156. reflex/components/radix/themes/layout/flex.pyi +225 -286
  157. reflex/components/radix/themes/layout/grid.py +2 -2
  158. reflex/components/radix/themes/layout/grid.pyi +245 -315
  159. reflex/components/radix/themes/layout/list.py +2 -2
  160. reflex/components/radix/themes/layout/list.pyi +712 -815
  161. reflex/components/radix/themes/layout/section.pyi +187 -221
  162. reflex/components/radix/themes/layout/spacer.pyi +225 -286
  163. reflex/components/radix/themes/layout/stack.pyi +625 -768
  164. reflex/components/radix/themes/typography/blockquote.pyi +257 -299
  165. reflex/components/radix/themes/typography/code.pyi +259 -304
  166. reflex/components/radix/themes/typography/heading.pyi +272 -324
  167. reflex/components/radix/themes/typography/link.pyi +302 -358
  168. reflex/components/radix/themes/typography/text.pyi +1669 -1945
  169. reflex/components/react_player/audio.pyi +20 -22
  170. reflex/components/react_player/react_player.pyi +19 -19
  171. reflex/components/react_player/video.pyi +20 -22
  172. reflex/components/recharts/cartesian.py +100 -97
  173. reflex/components/recharts/cartesian.pyi +891 -1007
  174. reflex/components/recharts/charts.py +42 -42
  175. reflex/components/recharts/charts.pyi +212 -249
  176. reflex/components/recharts/general.py +22 -21
  177. reflex/components/recharts/general.pyi +198 -223
  178. reflex/components/recharts/polar.py +42 -45
  179. reflex/components/recharts/polar.pyi +254 -288
  180. reflex/components/recharts/recharts.pyi +13 -13
  181. reflex/components/sonner/toast.py +20 -20
  182. reflex/components/sonner/toast.pyi +58 -61
  183. reflex/components/suneditor/editor.py +9 -9
  184. reflex/components/suneditor/editor.pyi +78 -83
  185. reflex/components/tags/cond_tag.py +2 -2
  186. reflex/components/tags/iter_tag.py +10 -14
  187. reflex/components/tags/match_tag.py +2 -2
  188. reflex/components/tags/tag.py +10 -10
  189. reflex/config.py +36 -35
  190. reflex/constants/__init__.py +56 -53
  191. reflex/custom_components/custom_components.py +6 -7
  192. reflex/event.py +38 -42
  193. reflex/experimental/client_state.py +2 -4
  194. reflex/experimental/layout.py +2 -2
  195. reflex/experimental/layout.pyi +579 -663
  196. reflex/istate/data.py +4 -5
  197. reflex/middleware/hydrate_middleware.py +2 -2
  198. reflex/middleware/middleware.py +2 -2
  199. reflex/model.py +3 -5
  200. reflex/page.py +2 -2
  201. reflex/reflex.py +9 -10
  202. reflex/state.py +77 -49
  203. reflex/style.py +9 -3
  204. reflex/testing.py +21 -24
  205. reflex/utils/console.py +1 -1
  206. reflex/utils/decorator.py +26 -1
  207. reflex/utils/exec.py +6 -11
  208. reflex/utils/export.py +2 -3
  209. reflex/utils/format.py +4 -4
  210. reflex/utils/imports.py +12 -12
  211. reflex/utils/prerequisites.py +35 -84
  212. reflex/utils/processes.py +5 -5
  213. reflex/utils/pyi_generator.py +33 -22
  214. reflex/utils/serializers.py +60 -15
  215. reflex/utils/types.py +237 -56
  216. reflex/vars/base.py +122 -72
  217. reflex/vars/datetime.py +2 -2
  218. reflex/vars/function.py +52 -55
  219. reflex/vars/number.py +59 -5
  220. reflex/vars/object.py +57 -26
  221. reflex/vars/sequence.py +983 -958
  222. {reflex-0.7.1a4.dist-info → reflex-0.7.2a2.dist-info}/METADATA +3 -6
  223. reflex-0.7.2a2.dist-info/RECORD +405 -0
  224. {reflex-0.7.1a4.dist-info → reflex-0.7.2a2.dist-info}/WHEEL +1 -1
  225. reflex-0.7.1a4.dist-info/RECORD +0 -405
  226. {reflex-0.7.1a4.dist-info → reflex-0.7.2a2.dist-info}/LICENSE +0 -0
  227. {reflex-0.7.1a4.dist-info → reflex-0.7.2a2.dist-info}/entry_points.txt +0 -0
reflex/vars/function.py CHANGED
@@ -9,14 +9,11 @@ from typing import (
9
9
  Callable,
10
10
  Concatenate,
11
11
  Generic,
12
- Optional,
13
12
  ParamSpec,
14
13
  Protocol,
15
14
  Sequence,
16
- Tuple,
17
15
  Type,
18
16
  TypeVar,
19
- Union,
20
17
  overload,
21
18
  )
22
19
 
@@ -56,52 +53,52 @@ class FunctionVar(Var[CALLABLE_TYPE], default_type=ReflexCallable[Any, Any]):
56
53
  @overload
57
54
  def partial(
58
55
  self: FunctionVar[ReflexCallable[Concatenate[V1, P], R]],
59
- arg1: Union[V1, Var[V1]],
56
+ arg1: V1 | Var[V1],
60
57
  ) -> FunctionVar[ReflexCallable[P, R]]: ...
61
58
 
62
59
  @overload
63
60
  def partial(
64
61
  self: FunctionVar[ReflexCallable[Concatenate[V1, V2, P], R]],
65
- arg1: Union[V1, Var[V1]],
66
- arg2: Union[V2, Var[V2]],
62
+ arg1: V1 | Var[V1],
63
+ arg2: V2 | Var[V2],
67
64
  ) -> FunctionVar[ReflexCallable[P, R]]: ...
68
65
 
69
66
  @overload
70
67
  def partial(
71
68
  self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, P], R]],
72
- arg1: Union[V1, Var[V1]],
73
- arg2: Union[V2, Var[V2]],
74
- arg3: Union[V3, Var[V3]],
69
+ arg1: V1 | Var[V1],
70
+ arg2: V2 | Var[V2],
71
+ arg3: V3 | Var[V3],
75
72
  ) -> FunctionVar[ReflexCallable[P, R]]: ...
76
73
 
77
74
  @overload
78
75
  def partial(
79
76
  self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, V4, P], R]],
80
- arg1: Union[V1, Var[V1]],
81
- arg2: Union[V2, Var[V2]],
82
- arg3: Union[V3, Var[V3]],
83
- arg4: Union[V4, Var[V4]],
77
+ arg1: V1 | Var[V1],
78
+ arg2: V2 | Var[V2],
79
+ arg3: V3 | Var[V3],
80
+ arg4: V4 | Var[V4],
84
81
  ) -> FunctionVar[ReflexCallable[P, R]]: ...
85
82
 
86
83
  @overload
87
84
  def partial(
88
85
  self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, V4, V5, P], R]],
89
- arg1: Union[V1, Var[V1]],
90
- arg2: Union[V2, Var[V2]],
91
- arg3: Union[V3, Var[V3]],
92
- arg4: Union[V4, Var[V4]],
93
- arg5: Union[V5, Var[V5]],
86
+ arg1: V1 | Var[V1],
87
+ arg2: V2 | Var[V2],
88
+ arg3: V3 | Var[V3],
89
+ arg4: V4 | Var[V4],
90
+ arg5: V5 | Var[V5],
94
91
  ) -> FunctionVar[ReflexCallable[P, R]]: ...
95
92
 
96
93
  @overload
97
94
  def partial(
98
95
  self: FunctionVar[ReflexCallable[Concatenate[V1, V2, V3, V4, V5, V6, P], R]],
99
- arg1: Union[V1, Var[V1]],
100
- arg2: Union[V2, Var[V2]],
101
- arg3: Union[V3, Var[V3]],
102
- arg4: Union[V4, Var[V4]],
103
- arg5: Union[V5, Var[V5]],
104
- arg6: Union[V6, Var[V6]],
96
+ arg1: V1 | Var[V1],
97
+ arg2: V2 | Var[V2],
98
+ arg3: V3 | Var[V3],
99
+ arg4: V4 | Var[V4],
100
+ arg5: V5 | Var[V5],
101
+ arg6: V6 | Var[V6],
105
102
  ) -> FunctionVar[ReflexCallable[P, R]]: ...
106
103
 
107
104
  @overload
@@ -130,52 +127,52 @@ class FunctionVar(Var[CALLABLE_TYPE], default_type=ReflexCallable[Any, Any]):
130
127
 
131
128
  @overload
132
129
  def call(
133
- self: FunctionVar[ReflexCallable[[V1], R]], arg1: Union[V1, Var[V1]]
130
+ self: FunctionVar[ReflexCallable[[V1], R]], arg1: V1 | Var[V1]
134
131
  ) -> VarOperationCall[[V1], R]: ...
135
132
 
136
133
  @overload
137
134
  def call(
138
135
  self: FunctionVar[ReflexCallable[[V1, V2], R]],
139
- arg1: Union[V1, Var[V1]],
140
- arg2: Union[V2, Var[V2]],
136
+ arg1: V1 | Var[V1],
137
+ arg2: V2 | Var[V2],
141
138
  ) -> VarOperationCall[[V1, V2], R]: ...
142
139
 
143
140
  @overload
144
141
  def call(
145
142
  self: FunctionVar[ReflexCallable[[V1, V2, V3], R]],
146
- arg1: Union[V1, Var[V1]],
147
- arg2: Union[V2, Var[V2]],
148
- arg3: Union[V3, Var[V3]],
143
+ arg1: V1 | Var[V1],
144
+ arg2: V2 | Var[V2],
145
+ arg3: V3 | Var[V3],
149
146
  ) -> VarOperationCall[[V1, V2, V3], R]: ...
150
147
 
151
148
  @overload
152
149
  def call(
153
150
  self: FunctionVar[ReflexCallable[[V1, V2, V3, V4], R]],
154
- arg1: Union[V1, Var[V1]],
155
- arg2: Union[V2, Var[V2]],
156
- arg3: Union[V3, Var[V3]],
157
- arg4: Union[V4, Var[V4]],
151
+ arg1: V1 | Var[V1],
152
+ arg2: V2 | Var[V2],
153
+ arg3: V3 | Var[V3],
154
+ arg4: V4 | Var[V4],
158
155
  ) -> VarOperationCall[[V1, V2, V3, V4], R]: ...
159
156
 
160
157
  @overload
161
158
  def call(
162
159
  self: FunctionVar[ReflexCallable[[V1, V2, V3, V4, V5], R]],
163
- arg1: Union[V1, Var[V1]],
164
- arg2: Union[V2, Var[V2]],
165
- arg3: Union[V3, Var[V3]],
166
- arg4: Union[V4, Var[V4]],
167
- arg5: Union[V5, Var[V5]],
160
+ arg1: V1 | Var[V1],
161
+ arg2: V2 | Var[V2],
162
+ arg3: V3 | Var[V3],
163
+ arg4: V4 | Var[V4],
164
+ arg5: V5 | Var[V5],
168
165
  ) -> VarOperationCall[[V1, V2, V3, V4, V5], R]: ...
169
166
 
170
167
  @overload
171
168
  def call(
172
169
  self: FunctionVar[ReflexCallable[[V1, V2, V3, V4, V5, V6], R]],
173
- arg1: Union[V1, Var[V1]],
174
- arg2: Union[V2, Var[V2]],
175
- arg3: Union[V3, Var[V3]],
176
- arg4: Union[V4, Var[V4]],
177
- arg5: Union[V5, Var[V5]],
178
- arg6: Union[V6, Var[V6]],
170
+ arg1: V1 | Var[V1],
171
+ arg2: V2 | Var[V2],
172
+ arg3: V3 | Var[V3],
173
+ arg4: V4 | Var[V4],
174
+ arg5: V5 | Var[V5],
175
+ arg6: V6 | Var[V6],
179
176
  ) -> VarOperationCall[[V1, V2, V3, V4, V5, V6], R]: ...
180
177
 
181
178
  @overload
@@ -243,8 +240,8 @@ class FunctionStringVar(FunctionVar[CALLABLE_TYPE]):
243
240
  class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
244
241
  """Base class for immutable vars that are the result of a function call."""
245
242
 
246
- _func: Optional[FunctionVar[ReflexCallable[P, R]]] = dataclasses.field(default=None)
247
- _args: Tuple[Union[Var, Any], ...] = dataclasses.field(default_factory=tuple)
243
+ _func: FunctionVar[ReflexCallable[P, R]] | None = dataclasses.field(default=None)
244
+ _args: tuple[Var | Any, ...] = dataclasses.field(default_factory=tuple)
248
245
 
249
246
  @cached_property_no_lock
250
247
  def _cached_var_name(self) -> str:
@@ -306,8 +303,8 @@ class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
306
303
  class DestructuredArg:
307
304
  """Class for destructured arguments."""
308
305
 
309
- fields: Tuple[str, ...] = ()
310
- rest: Optional[str] = None
306
+ fields: tuple[str, ...] = ()
307
+ rest: str | None = None
311
308
 
312
309
  def to_javascript(self) -> str:
313
310
  """Convert the destructured argument to JavaScript.
@@ -328,8 +325,8 @@ class DestructuredArg:
328
325
  class FunctionArgs:
329
326
  """Class for function arguments."""
330
327
 
331
- args: Tuple[Union[str, DestructuredArg], ...] = ()
332
- rest: Optional[str] = None
328
+ args: tuple[str | DestructuredArg, ...] = ()
329
+ rest: str | None = None
333
330
 
334
331
 
335
332
  def format_args_function_operation(
@@ -368,7 +365,7 @@ class ArgsFunctionOperation(CachedVarOperation, FunctionVar):
368
365
  """Base class for immutable function defined via arguments and return expression."""
369
366
 
370
367
  _args: FunctionArgs = dataclasses.field(default_factory=FunctionArgs)
371
- _return_expr: Union[Var, Any] = dataclasses.field(default=None)
368
+ _return_expr: Var | Any = dataclasses.field(default=None)
372
369
  _explicit_return: bool = dataclasses.field(default=False)
373
370
 
374
371
  @cached_property_no_lock
@@ -385,7 +382,7 @@ class ArgsFunctionOperation(CachedVarOperation, FunctionVar):
385
382
  @classmethod
386
383
  def create(
387
384
  cls,
388
- args_names: Sequence[Union[str, DestructuredArg]],
385
+ args_names: Sequence[str | DestructuredArg],
389
386
  return_expr: Var | Any,
390
387
  rest: str | None = None,
391
388
  explicit_return: bool = False,
@@ -425,7 +422,7 @@ class ArgsFunctionOperationBuilder(CachedVarOperation, BuilderFunctionVar):
425
422
  """Base class for immutable function defined via arguments and return expression with the builder pattern."""
426
423
 
427
424
  _args: FunctionArgs = dataclasses.field(default_factory=FunctionArgs)
428
- _return_expr: Union[Var, Any] = dataclasses.field(default=None)
425
+ _return_expr: Var | Any = dataclasses.field(default=None)
429
426
  _explicit_return: bool = dataclasses.field(default=False)
430
427
 
431
428
  @cached_property_no_lock
@@ -442,7 +439,7 @@ class ArgsFunctionOperationBuilder(CachedVarOperation, BuilderFunctionVar):
442
439
  @classmethod
443
440
  def create(
444
441
  cls,
445
- args_names: Sequence[Union[str, DestructuredArg]],
442
+ args_names: Sequence[str | DestructuredArg],
446
443
  return_expr: Var | Any,
447
444
  rest: str | None = None,
448
445
  explicit_return: bool = False,
reflex/vars/number.py CHANGED
@@ -17,7 +17,11 @@ from typing import (
17
17
  )
18
18
 
19
19
  from reflex.constants.base import Dirs
20
- from reflex.utils.exceptions import PrimitiveUnserializableToJSONError, VarTypeError
20
+ from reflex.utils.exceptions import (
21
+ PrimitiveUnserializableToJSONError,
22
+ VarTypeError,
23
+ VarValueError,
24
+ )
21
25
  from reflex.utils.imports import ImportDict, ImportVar
22
26
 
23
27
  from .base import (
@@ -530,6 +534,56 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
530
534
  """
531
535
  return issubclass(self._var_type, int)
532
536
 
537
+ def __format__(self, format_spec: str) -> str:
538
+ """Format the number.
539
+
540
+ Args:
541
+ format_spec: The format specifier.
542
+
543
+ Returns:
544
+ The formatted number.
545
+
546
+ Raises:
547
+ VarValueError: If the format specifier is not supported.
548
+ """
549
+ if (
550
+ format_spec
551
+ and format_spec[-1] == "f"
552
+ and format_spec[0] == "."
553
+ and format_spec[1:-1].isdigit()
554
+ ):
555
+ how_many_decimals = int(format_spec[1:-1])
556
+ return (
557
+ f"{get_decimal_string_operation(self, Var.create(how_many_decimals))}"
558
+ )
559
+
560
+ if format_spec:
561
+ raise VarValueError(
562
+ (
563
+ "Unknown format code '{}' for object of type 'NumberVar'. It is only supported to use '.f' for float numbers."
564
+ "If possible, use computed variables instead: https://reflex.dev/docs/vars/computed-vars/"
565
+ ).format(format_spec)
566
+ )
567
+
568
+ return super().__format__(format_spec)
569
+
570
+
571
+ @var_operation
572
+ def get_decimal_string_operation(value: NumberVar, decimals: NumberVar):
573
+ """Get the decimal string of the number.
574
+
575
+ Args:
576
+ value: The number.
577
+ decimals: The number of decimals.
578
+
579
+ Returns:
580
+ The decimal string of the number.
581
+ """
582
+ return var_operation_return(
583
+ js_expression=f"({value}.toFixed({decimals}))",
584
+ var_type=str,
585
+ )
586
+
533
587
 
534
588
  def binary_number_operation(
535
589
  func: Callable[[NumberVar, NumberVar], str],
@@ -1073,8 +1127,8 @@ class LiteralBooleanVar(LiteralVar, BooleanVar):
1073
1127
  )
1074
1128
 
1075
1129
 
1076
- number_types = Union[NumberVar, int, float]
1077
- boolean_types = Union[BooleanVar, bool]
1130
+ number_types = NumberVar | int | float
1131
+ boolean_types = BooleanVar | bool
1078
1132
 
1079
1133
 
1080
1134
  _IS_TRUE_IMPORT: ImportDict = {
@@ -1106,7 +1160,7 @@ U = TypeVar("U")
1106
1160
  @var_operation
1107
1161
  def ternary_operation(
1108
1162
  condition: BooleanVar, if_true: Var[T], if_false: Var[U]
1109
- ) -> CustomVarOperationReturn[Union[T, U]]:
1163
+ ) -> CustomVarOperationReturn[T | U]:
1110
1164
  """Create a ternary operation.
1111
1165
 
1112
1166
  Args:
@@ -1120,7 +1174,7 @@ def ternary_operation(
1120
1174
  type_value: Union[Type[T], Type[U]] = unionize(
1121
1175
  if_true._var_type, if_false._var_type
1122
1176
  )
1123
- value: CustomVarOperationReturn[Union[T, U]] = var_operation_return(
1177
+ value: CustomVarOperationReturn[T | U] = var_operation_return(
1124
1178
  js_expression=f"({condition} ? {if_true} : {if_false})",
1125
1179
  var_type=type_value,
1126
1180
  )
reflex/vars/object.py CHANGED
@@ -2,19 +2,18 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import collections.abc
5
6
  import dataclasses
6
7
  import typing
7
8
  from inspect import isclass
8
9
  from typing import (
9
10
  Any,
10
- List,
11
11
  Mapping,
12
12
  NoReturn,
13
- Tuple,
14
13
  Type,
15
14
  TypeVar,
16
- Union,
17
15
  get_args,
16
+ get_type_hints,
18
17
  overload,
19
18
  )
20
19
 
@@ -27,6 +26,7 @@ from reflex.utils.types import (
27
26
  get_attribute_access_type,
28
27
  get_origin,
29
28
  safe_issubclass,
29
+ unionize,
30
30
  )
31
31
 
32
32
  from .base import (
@@ -52,6 +52,29 @@ ARRAY_INNER_TYPE = TypeVar("ARRAY_INNER_TYPE")
52
52
  OTHER_KEY_TYPE = TypeVar("OTHER_KEY_TYPE")
53
53
 
54
54
 
55
+ def _determine_value_type(var_type: GenericType):
56
+ origin_var_type = get_origin(var_type) or var_type
57
+
58
+ if origin_var_type in types.UnionTypes:
59
+ return unionize(
60
+ *[
61
+ _determine_value_type(arg)
62
+ for arg in get_args(var_type)
63
+ if arg is not type(None)
64
+ ]
65
+ )
66
+
67
+ if is_typeddict(origin_var_type) or dataclasses.is_dataclass(origin_var_type):
68
+ annotations = get_type_hints(origin_var_type)
69
+ return unionize(*annotations.values())
70
+
71
+ if origin_var_type in [dict, Mapping, collections.abc.Mapping]:
72
+ args = get_args(var_type)
73
+ return args[1] if args else Any
74
+
75
+ return Any
76
+
77
+
55
78
  class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
56
79
  """Base class for immutable object vars."""
57
80
 
@@ -69,21 +92,17 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
69
92
  ) -> Type[VALUE_TYPE]: ...
70
93
 
71
94
  @overload
72
- def _value_type(self) -> Type: ...
95
+ def _value_type(self) -> GenericType: ...
73
96
 
74
- def _value_type(self) -> Type:
97
+ def _value_type(self) -> GenericType:
75
98
  """Get the type of the values of the object.
76
99
 
77
100
  Returns:
78
101
  The type of the values of the object.
79
102
  """
80
- fixed_type = get_origin(self._var_type) or self._var_type
81
- if not isclass(fixed_type):
82
- return Any # pyright: ignore [reportReturnType]
83
- args = get_args(self._var_type) if issubclass(fixed_type, Mapping) else ()
84
- return args[1] if args else Any # pyright: ignore [reportReturnType]
103
+ return _determine_value_type(self._var_type)
85
104
 
86
- def keys(self) -> ArrayVar[List[str]]:
105
+ def keys(self) -> ArrayVar[list[str]]:
87
106
  """Get the keys of the object.
88
107
 
89
108
  Returns:
@@ -94,7 +113,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
94
113
  @overload
95
114
  def values(
96
115
  self: ObjectVar[Mapping[Any, VALUE_TYPE]],
97
- ) -> ArrayVar[List[VALUE_TYPE]]: ...
116
+ ) -> ArrayVar[list[VALUE_TYPE]]: ...
98
117
 
99
118
  @overload
100
119
  def values(self) -> ArrayVar: ...
@@ -110,7 +129,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
110
129
  @overload
111
130
  def entries(
112
131
  self: ObjectVar[Mapping[Any, VALUE_TYPE]],
113
- ) -> ArrayVar[List[Tuple[str, VALUE_TYPE]]]: ...
132
+ ) -> ArrayVar[list[tuple[str, VALUE_TYPE]]]: ...
114
133
 
115
134
  @overload
116
135
  def entries(self) -> ArrayVar: ...
@@ -266,8 +285,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
266
285
 
267
286
  var_type = self._var_type
268
287
 
269
- if types.is_optional(var_type):
270
- var_type = get_args(var_type)[0]
288
+ var_type = types.value_inside_optional(var_type)
271
289
 
272
290
  fixed_type = get_origin(var_type) or var_type
273
291
 
@@ -306,9 +324,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
306
324
  class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
307
325
  """Base class for immutable literal object vars."""
308
326
 
309
- _var_value: Mapping[Union[Var, Any], Union[Var, Any]] = dataclasses.field(
310
- default_factory=dict
311
- )
327
+ _var_value: Mapping[Var | Any, Var | Any] = dataclasses.field(default_factory=dict)
312
328
 
313
329
  def _key_type(self) -> Type:
314
330
  """Get the type of the keys of the object.
@@ -425,9 +441,14 @@ def object_keys_operation(value: ObjectVar):
425
441
  Returns:
426
442
  The keys of the object.
427
443
  """
444
+ if not types.is_optional(value._var_type):
445
+ return var_operation_return(
446
+ js_expression=f"Object.keys({value})",
447
+ var_type=list[str],
448
+ )
428
449
  return var_operation_return(
429
- js_expression=f"Object.keys({value})",
430
- var_type=List[str],
450
+ js_expression=f"((value) => value ?? undefined === undefined ? undefined : Object.keys(value))({value})",
451
+ var_type=(list[str] | None),
431
452
  )
432
453
 
433
454
 
@@ -441,9 +462,14 @@ def object_values_operation(value: ObjectVar):
441
462
  Returns:
442
463
  The values of the object.
443
464
  """
465
+ if not types.is_optional(value._var_type):
466
+ return var_operation_return(
467
+ js_expression=f"Object.values({value})",
468
+ var_type=list[value._value_type()],
469
+ )
444
470
  return var_operation_return(
445
- js_expression=f"Object.values({value})",
446
- var_type=List[value._value_type()],
471
+ js_expression=f"((value) => value ?? undefined === undefined ? undefined : Object.values(value))({value})",
472
+ var_type=(list[value._value_type()] | None),
447
473
  )
448
474
 
449
475
 
@@ -457,9 +483,14 @@ def object_entries_operation(value: ObjectVar):
457
483
  Returns:
458
484
  The entries of the object.
459
485
  """
486
+ if not types.is_optional(value._var_type):
487
+ return var_operation_return(
488
+ js_expression=f"Object.entries({value})",
489
+ var_type=list[tuple[str, value._value_type()]],
490
+ )
460
491
  return var_operation_return(
461
- js_expression=f"Object.entries({value})",
462
- var_type=List[Tuple[str, value._value_type()]],
492
+ js_expression=f"((value) => value ?? undefined === undefined ? undefined : Object.entries(value))({value})",
493
+ var_type=(list[tuple[str, value._value_type()]] | None),
463
494
  )
464
495
 
465
496
 
@@ -477,8 +508,8 @@ def object_merge_operation(lhs: ObjectVar, rhs: ObjectVar):
477
508
  return var_operation_return(
478
509
  js_expression=f"({{...{lhs}, ...{rhs}}})",
479
510
  var_type=Mapping[
480
- Union[lhs._key_type(), rhs._key_type()],
481
- Union[lhs._value_type(), rhs._value_type()],
511
+ lhs._key_type() | rhs._key_type(),
512
+ lhs._value_type() | rhs._value_type(),
482
513
  ],
483
514
  )
484
515