reflex 0.6.8a1__py3-none-any.whl → 0.7.0__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 (248) hide show
  1. reflex/.templates/jinja/custom_components/pyproject.toml.jinja2 +1 -1
  2. reflex/.templates/jinja/web/pages/_app.js.jinja2 +7 -7
  3. reflex/.templates/jinja/web/pages/utils.js.jinja2 +3 -3
  4. reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +1 -4
  5. reflex/.templates/web/utils/state.js +65 -36
  6. reflex/__init__.py +4 -17
  7. reflex/__init__.pyi +1 -2
  8. reflex/app.py +286 -135
  9. reflex/app_mixins/lifespan.py +9 -9
  10. reflex/app_mixins/middleware.py +6 -6
  11. reflex/app_module_for_backend.py +3 -7
  12. reflex/base.py +7 -7
  13. reflex/compiler/compiler.py +8 -0
  14. reflex/compiler/utils.py +57 -18
  15. reflex/components/base/app_wrap.pyi +16 -16
  16. reflex/components/base/bare.py +1 -1
  17. reflex/components/base/body.pyi +16 -16
  18. reflex/components/base/document.pyi +76 -76
  19. reflex/components/base/error_boundary.py +2 -1
  20. reflex/components/base/error_boundary.pyi +19 -22
  21. reflex/components/base/fragment.pyi +16 -16
  22. reflex/components/base/head.pyi +31 -31
  23. reflex/components/base/link.pyi +31 -31
  24. reflex/components/base/meta.py +2 -2
  25. reflex/components/base/meta.pyi +61 -61
  26. reflex/components/base/script.pyi +19 -19
  27. reflex/components/base/strict_mode.py +10 -0
  28. reflex/components/base/strict_mode.pyi +57 -0
  29. reflex/components/component.py +38 -77
  30. reflex/components/core/banner.py +159 -4
  31. reflex/components/core/banner.pyi +162 -76
  32. reflex/components/core/breakpoints.py +3 -1
  33. reflex/components/core/client_side_routing.py +1 -1
  34. reflex/components/core/client_side_routing.pyi +32 -32
  35. reflex/components/core/clipboard.pyi +17 -20
  36. reflex/components/core/cond.py +9 -10
  37. reflex/components/core/debounce.py +1 -1
  38. reflex/components/core/debounce.pyi +17 -17
  39. reflex/components/core/foreach.py +28 -3
  40. reflex/components/core/html.py +1 -1
  41. reflex/components/core/html.pyi +16 -16
  42. reflex/components/core/match.py +5 -5
  43. reflex/components/core/sticky.py +134 -0
  44. reflex/components/core/sticky.pyi +449 -0
  45. reflex/components/core/upload.py +2 -2
  46. reflex/components/core/upload.pyi +80 -88
  47. reflex/components/datadisplay/code.py +5 -14
  48. reflex/components/datadisplay/code.pyi +31 -31
  49. reflex/components/datadisplay/dataeditor.py +7 -4
  50. reflex/components/datadisplay/dataeditor.pyi +40 -54
  51. reflex/components/datadisplay/logo.py +13 -8
  52. reflex/components/datadisplay/shiki_code_block.py +14 -9
  53. reflex/components/datadisplay/shiki_code_block.pyi +46 -46
  54. reflex/components/dynamic.py +22 -3
  55. reflex/components/el/constants/reflex.py +1 -1
  56. reflex/components/el/element.py +1 -1
  57. reflex/components/el/element.pyi +16 -16
  58. reflex/components/el/elements/base.pyi +16 -16
  59. reflex/components/el/elements/forms.py +4 -4
  60. reflex/components/el/elements/forms.pyi +224 -258
  61. reflex/components/el/elements/inline.pyi +421 -421
  62. reflex/components/el/elements/media.pyi +376 -376
  63. reflex/components/el/elements/metadata.pyi +91 -91
  64. reflex/components/el/elements/other.pyi +106 -106
  65. reflex/components/el/elements/scripts.pyi +46 -46
  66. reflex/components/el/elements/sectioning.pyi +226 -226
  67. reflex/components/el/elements/tables.pyi +151 -151
  68. reflex/components/el/elements/typography.pyi +226 -226
  69. reflex/components/gridjs/datatable.pyi +31 -31
  70. reflex/components/lucide/icon.py +46 -8
  71. reflex/components/lucide/icon.pyi +85 -31
  72. reflex/components/markdown/markdown.py +10 -8
  73. reflex/components/markdown/markdown.pyi +16 -16
  74. reflex/components/moment/moment.py +2 -2
  75. reflex/components/moment/moment.pyi +17 -19
  76. reflex/components/next/base.pyi +16 -16
  77. reflex/components/next/image.py +16 -4
  78. reflex/components/next/image.pyi +22 -20
  79. reflex/components/next/link.py +1 -1
  80. reflex/components/next/link.pyi +16 -16
  81. reflex/components/next/video.pyi +16 -16
  82. reflex/components/plotly/__init__.py +29 -2
  83. reflex/components/plotly/plotly.py +240 -5
  84. reflex/components/plotly/plotly.pyi +799 -44
  85. reflex/components/props.py +3 -3
  86. reflex/components/radix/__init__.pyi +1 -1
  87. reflex/components/radix/primitives/accordion.py +9 -5
  88. reflex/components/radix/primitives/accordion.pyi +110 -108
  89. reflex/components/radix/primitives/base.pyi +31 -31
  90. reflex/components/radix/primitives/drawer.py +5 -2
  91. reflex/components/radix/primitives/drawer.pyi +179 -187
  92. reflex/components/radix/primitives/form.pyi +160 -172
  93. reflex/components/radix/primitives/progress.py +1 -1
  94. reflex/components/radix/primitives/progress.pyi +76 -76
  95. reflex/components/radix/primitives/slider.py +1 -1
  96. reflex/components/radix/primitives/slider.pyi +78 -82
  97. reflex/components/radix/themes/base.pyi +121 -121
  98. reflex/components/radix/themes/color_mode.py +11 -9
  99. reflex/components/radix/themes/color_mode.pyi +47 -49
  100. reflex/components/radix/themes/components/alert_dialog.py +3 -0
  101. reflex/components/radix/themes/components/alert_dialog.pyi +110 -112
  102. reflex/components/radix/themes/components/aspect_ratio.pyi +16 -16
  103. reflex/components/radix/themes/components/avatar.pyi +16 -16
  104. reflex/components/radix/themes/components/badge.pyi +16 -16
  105. reflex/components/radix/themes/components/button.pyi +16 -16
  106. reflex/components/radix/themes/components/callout.pyi +76 -76
  107. reflex/components/radix/themes/components/card.py +1 -1
  108. reflex/components/radix/themes/components/card.pyi +17 -17
  109. reflex/components/radix/themes/components/checkbox.pyi +49 -55
  110. reflex/components/radix/themes/components/checkbox_cards.pyi +31 -31
  111. reflex/components/radix/themes/components/checkbox_group.pyi +31 -31
  112. reflex/components/radix/themes/components/context_menu.py +5 -0
  113. reflex/components/radix/themes/components/context_menu.pyi +149 -155
  114. reflex/components/radix/themes/components/data_list.pyi +61 -61
  115. reflex/components/radix/themes/components/dialog.py +3 -0
  116. reflex/components/radix/themes/components/dialog.pyi +113 -117
  117. reflex/components/radix/themes/components/dropdown_menu.py +5 -0
  118. reflex/components/radix/themes/components/dropdown_menu.pyi +133 -137
  119. reflex/components/radix/themes/components/hover_card.py +3 -0
  120. reflex/components/radix/themes/components/hover_card.pyi +63 -67
  121. reflex/components/radix/themes/components/icon_button.py +2 -2
  122. reflex/components/radix/themes/components/icon_button.pyi +17 -16
  123. reflex/components/radix/themes/components/inset.pyi +16 -16
  124. reflex/components/radix/themes/components/popover.py +3 -0
  125. reflex/components/radix/themes/components/popover.pyi +68 -70
  126. reflex/components/radix/themes/components/progress.pyi +16 -16
  127. reflex/components/radix/themes/components/radio.pyi +16 -16
  128. reflex/components/radix/themes/components/radio_cards.py +2 -0
  129. reflex/components/radix/themes/components/radio_cards.pyi +32 -34
  130. reflex/components/radix/themes/components/radio_group.py +1 -1
  131. reflex/components/radix/themes/components/radio_group.pyi +62 -64
  132. reflex/components/radix/themes/components/scroll_area.pyi +16 -16
  133. reflex/components/radix/themes/components/segmented_control.pyi +32 -35
  134. reflex/components/radix/themes/components/select.py +4 -0
  135. reflex/components/radix/themes/components/select.pyi +145 -157
  136. reflex/components/radix/themes/components/separator.pyi +16 -16
  137. reflex/components/radix/themes/components/skeleton.py +3 -0
  138. reflex/components/radix/themes/components/skeleton.pyi +16 -16
  139. reflex/components/radix/themes/components/slider.pyi +22 -28
  140. reflex/components/radix/themes/components/spinner.pyi +16 -16
  141. reflex/components/radix/themes/components/switch.pyi +17 -19
  142. reflex/components/radix/themes/components/table.pyi +106 -106
  143. reflex/components/radix/themes/components/tabs.py +3 -0
  144. reflex/components/radix/themes/components/tabs.pyi +78 -82
  145. reflex/components/radix/themes/components/text_area.py +12 -0
  146. reflex/components/radix/themes/components/text_area.pyi +21 -33
  147. reflex/components/radix/themes/components/text_field.py +1 -1
  148. reflex/components/radix/themes/components/text_field.pyi +52 -80
  149. reflex/components/radix/themes/components/tooltip.py +6 -1
  150. reflex/components/radix/themes/components/tooltip.pyi +20 -21
  151. reflex/components/radix/themes/layout/__init__.pyi +1 -1
  152. reflex/components/radix/themes/layout/base.pyi +16 -16
  153. reflex/components/radix/themes/layout/box.pyi +16 -16
  154. reflex/components/radix/themes/layout/center.pyi +16 -16
  155. reflex/components/radix/themes/layout/container.pyi +16 -16
  156. reflex/components/radix/themes/layout/flex.pyi +16 -16
  157. reflex/components/radix/themes/layout/grid.pyi +16 -16
  158. reflex/components/radix/themes/layout/list.py +2 -2
  159. reflex/components/radix/themes/layout/list.pyi +76 -76
  160. reflex/components/radix/themes/layout/section.pyi +16 -16
  161. reflex/components/radix/themes/layout/spacer.pyi +16 -16
  162. reflex/components/radix/themes/layout/stack.py +2 -2
  163. reflex/components/radix/themes/layout/stack.pyi +46 -46
  164. reflex/components/radix/themes/typography/blockquote.pyi +16 -16
  165. reflex/components/radix/themes/typography/code.pyi +16 -16
  166. reflex/components/radix/themes/typography/heading.pyi +16 -16
  167. reflex/components/radix/themes/typography/link.py +1 -1
  168. reflex/components/radix/themes/typography/link.pyi +16 -16
  169. reflex/components/radix/themes/typography/text.py +2 -2
  170. reflex/components/radix/themes/typography/text.pyi +106 -106
  171. reflex/components/react_player/audio.pyi +33 -39
  172. reflex/components/react_player/react_player.py +1 -1
  173. reflex/components/react_player/react_player.pyi +32 -38
  174. reflex/components/react_player/video.pyi +33 -39
  175. reflex/components/recharts/__init__.py +2 -0
  176. reflex/components/recharts/__init__.pyi +2 -0
  177. reflex/components/recharts/cartesian.pyi +282 -282
  178. reflex/components/recharts/charts.py +15 -15
  179. reflex/components/recharts/charts.pyi +164 -164
  180. reflex/components/recharts/general.py +19 -4
  181. reflex/components/recharts/general.pyi +132 -81
  182. reflex/components/recharts/polar.py +2 -2
  183. reflex/components/recharts/polar.pyi +55 -55
  184. reflex/components/recharts/recharts.py +4 -4
  185. reflex/components/recharts/recharts.pyi +31 -31
  186. reflex/components/sonner/toast.py +15 -13
  187. reflex/components/sonner/toast.pyi +22 -22
  188. reflex/components/suneditor/editor.py +6 -4
  189. reflex/components/suneditor/editor.pyi +26 -40
  190. reflex/components/tags/iter_tag.py +3 -3
  191. reflex/components/tags/tag.py +25 -3
  192. reflex/config.py +48 -20
  193. reflex/constants/__init__.py +1 -0
  194. reflex/constants/base.py +4 -1
  195. reflex/constants/compiler.py +5 -2
  196. reflex/constants/config.py +8 -1
  197. reflex/constants/installer.py +9 -9
  198. reflex/constants/style.py +1 -1
  199. reflex/custom_components/custom_components.py +18 -10
  200. reflex/event.py +228 -233
  201. reflex/experimental/__init__.py +19 -11
  202. reflex/experimental/client_state.py +53 -28
  203. reflex/experimental/hooks.py +5 -5
  204. reflex/experimental/layout.py +8 -5
  205. reflex/experimental/layout.pyi +79 -83
  206. reflex/experimental/misc.py +3 -3
  207. reflex/istate/wrappers.py +1 -1
  208. reflex/middleware/hydrate_middleware.py +2 -2
  209. reflex/model.py +11 -6
  210. reflex/page.py +5 -5
  211. reflex/reflex.py +104 -26
  212. reflex/route.py +1 -1
  213. reflex/state.py +358 -401
  214. reflex/style.py +27 -3
  215. reflex/testing.py +34 -39
  216. reflex/utils/build.py +6 -2
  217. reflex/utils/codespaces.py +1 -4
  218. reflex/utils/compat.py +6 -5
  219. reflex/utils/console.py +71 -21
  220. reflex/utils/exceptions.py +89 -26
  221. reflex/utils/exec.py +69 -74
  222. reflex/utils/export.py +6 -1
  223. reflex/utils/format.py +8 -40
  224. reflex/utils/imports.py +5 -2
  225. reflex/utils/lazy_loader.py +7 -1
  226. reflex/utils/path_ops.py +74 -14
  227. reflex/utils/prerequisites.py +345 -68
  228. reflex/utils/processes.py +45 -32
  229. reflex/utils/pyi_generator.py +39 -33
  230. reflex/utils/registry.py +4 -4
  231. reflex/utils/serializers.py +1 -1
  232. reflex/utils/telemetry.py +5 -4
  233. reflex/utils/types.py +42 -18
  234. reflex/vars/base.py +695 -330
  235. reflex/vars/datetime.py +6 -7
  236. reflex/vars/dep_tracking.py +344 -0
  237. reflex/vars/function.py +11 -5
  238. reflex/vars/number.py +31 -43
  239. reflex/vars/object.py +74 -64
  240. reflex/vars/sequence.py +79 -67
  241. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/METADATA +7 -10
  242. reflex-0.7.0.dist-info/RECORD +401 -0
  243. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/WHEEL +1 -1
  244. reflex/experimental/assets.py +0 -37
  245. reflex/proxy.py +0 -119
  246. reflex-0.6.8a1.dist-info/RECORD +0 -398
  247. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/LICENSE +0 -0
  248. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/entry_points.txt +0 -0
reflex/vars/number.py CHANGED
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
  import dataclasses
6
6
  import json
7
7
  import math
8
- import sys
9
8
  from typing import (
10
9
  TYPE_CHECKING,
11
10
  Any,
@@ -18,9 +17,8 @@ from typing import (
18
17
  )
19
18
 
20
19
  from reflex.constants.base import Dirs
21
- from reflex.utils.exceptions import PrimitiveUnserializableToJSON, VarTypeError
20
+ from reflex.utils.exceptions import PrimitiveUnserializableToJSONError, VarTypeError
22
21
  from reflex.utils.imports import ImportDict, ImportVar
23
- from reflex.utils.types import is_optional
24
22
 
25
23
  from .base import (
26
24
  CustomVarOperationReturn,
@@ -32,7 +30,7 @@ from .base import (
32
30
  var_operation_return,
33
31
  )
34
32
 
35
- NUMBER_T = TypeVar("NUMBER_T", int, float, Union[int, float], bool)
33
+ NUMBER_T = TypeVar("NUMBER_T", int, float, bool)
36
34
 
37
35
  if TYPE_CHECKING:
38
36
  from .sequence import ArrayVar
@@ -62,7 +60,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
62
60
  def __add__(self, other: number_types) -> NumberVar: ...
63
61
 
64
62
  @overload
65
- def __add__(self, other: NoReturn) -> NoReturn: ...
63
+ def __add__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
66
64
 
67
65
  def __add__(self, other: Any):
68
66
  """Add two numbers.
@@ -81,7 +79,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
81
79
  def __radd__(self, other: number_types) -> NumberVar: ...
82
80
 
83
81
  @overload
84
- def __radd__(self, other: NoReturn) -> NoReturn: ...
82
+ def __radd__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
85
83
 
86
84
  def __radd__(self, other: Any):
87
85
  """Add two numbers.
@@ -100,7 +98,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
100
98
  def __sub__(self, other: number_types) -> NumberVar: ...
101
99
 
102
100
  @overload
103
- def __sub__(self, other: NoReturn) -> NoReturn: ...
101
+ def __sub__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
104
102
 
105
103
  def __sub__(self, other: Any):
106
104
  """Subtract two numbers.
@@ -120,7 +118,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
120
118
  def __rsub__(self, other: number_types) -> NumberVar: ...
121
119
 
122
120
  @overload
123
- def __rsub__(self, other: NoReturn) -> NoReturn: ...
121
+ def __rsub__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
124
122
 
125
123
  def __rsub__(self, other: Any):
126
124
  """Subtract two numbers.
@@ -161,7 +159,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
161
159
  """
162
160
  from .sequence import ArrayVar, LiteralArrayVar
163
161
 
164
- if isinstance(other, (list, tuple, set, ArrayVar)):
162
+ if isinstance(other, (list, tuple, ArrayVar)):
165
163
  if isinstance(other, ArrayVar):
166
164
  return other * self
167
165
  return LiteralArrayVar.create(other) * self
@@ -188,7 +186,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
188
186
  """
189
187
  from .sequence import ArrayVar, LiteralArrayVar
190
188
 
191
- if isinstance(other, (list, tuple, set, ArrayVar)):
189
+ if isinstance(other, (list, tuple, ArrayVar)):
192
190
  if isinstance(other, ArrayVar):
193
191
  return other * self
194
192
  return LiteralArrayVar.create(other) * self
@@ -202,7 +200,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
202
200
  def __truediv__(self, other: number_types) -> NumberVar: ...
203
201
 
204
202
  @overload
205
- def __truediv__(self, other: NoReturn) -> NoReturn: ...
203
+ def __truediv__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
206
204
 
207
205
  def __truediv__(self, other: Any):
208
206
  """Divide two numbers.
@@ -222,7 +220,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
222
220
  def __rtruediv__(self, other: number_types) -> NumberVar: ...
223
221
 
224
222
  @overload
225
- def __rtruediv__(self, other: NoReturn) -> NoReturn: ...
223
+ def __rtruediv__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
226
224
 
227
225
  def __rtruediv__(self, other: Any):
228
226
  """Divide two numbers.
@@ -242,7 +240,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
242
240
  def __floordiv__(self, other: number_types) -> NumberVar: ...
243
241
 
244
242
  @overload
245
- def __floordiv__(self, other: NoReturn) -> NoReturn: ...
243
+ def __floordiv__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
246
244
 
247
245
  def __floordiv__(self, other: Any):
248
246
  """Floor divide two numbers.
@@ -262,7 +260,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
262
260
  def __rfloordiv__(self, other: number_types) -> NumberVar: ...
263
261
 
264
262
  @overload
265
- def __rfloordiv__(self, other: NoReturn) -> NoReturn: ...
263
+ def __rfloordiv__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
266
264
 
267
265
  def __rfloordiv__(self, other: Any):
268
266
  """Floor divide two numbers.
@@ -282,7 +280,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
282
280
  def __mod__(self, other: number_types) -> NumberVar: ...
283
281
 
284
282
  @overload
285
- def __mod__(self, other: NoReturn) -> NoReturn: ...
283
+ def __mod__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
286
284
 
287
285
  def __mod__(self, other: Any):
288
286
  """Modulo two numbers.
@@ -302,7 +300,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
302
300
  def __rmod__(self, other: number_types) -> NumberVar: ...
303
301
 
304
302
  @overload
305
- def __rmod__(self, other: NoReturn) -> NoReturn: ...
303
+ def __rmod__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
306
304
 
307
305
  def __rmod__(self, other: Any):
308
306
  """Modulo two numbers.
@@ -322,7 +320,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
322
320
  def __pow__(self, other: number_types) -> NumberVar: ...
323
321
 
324
322
  @overload
325
- def __pow__(self, other: NoReturn) -> NoReturn: ...
323
+ def __pow__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
326
324
 
327
325
  def __pow__(self, other: Any):
328
326
  """Exponentiate two numbers.
@@ -342,7 +340,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
342
340
  def __rpow__(self, other: number_types) -> NumberVar: ...
343
341
 
344
342
  @overload
345
- def __rpow__(self, other: NoReturn) -> NoReturn: ...
343
+ def __rpow__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
346
344
 
347
345
  def __rpow__(self, other: Any):
348
346
  """Exponentiate two numbers.
@@ -418,7 +416,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
418
416
  def __lt__(self, other: number_types) -> BooleanVar: ...
419
417
 
420
418
  @overload
421
- def __lt__(self, other: NoReturn) -> NoReturn: ...
419
+ def __lt__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
422
420
 
423
421
  def __lt__(self, other: Any):
424
422
  """Less than comparison.
@@ -431,13 +429,13 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
431
429
  """
432
430
  if not isinstance(other, NUMBER_TYPES):
433
431
  raise_unsupported_operand_types("<", (type(self), type(other)))
434
- return less_than_operation(self, +other)
432
+ return less_than_operation(+self, +other)
435
433
 
436
434
  @overload
437
435
  def __le__(self, other: number_types) -> BooleanVar: ...
438
436
 
439
437
  @overload
440
- def __le__(self, other: NoReturn) -> NoReturn: ...
438
+ def __le__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
441
439
 
442
440
  def __le__(self, other: Any):
443
441
  """Less than or equal comparison.
@@ -450,7 +448,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
450
448
  """
451
449
  if not isinstance(other, NUMBER_TYPES):
452
450
  raise_unsupported_operand_types("<=", (type(self), type(other)))
453
- return less_than_or_equal_operation(self, +other)
451
+ return less_than_or_equal_operation(+self, +other)
454
452
 
455
453
  def __eq__(self, other: Any):
456
454
  """Equal comparison.
@@ -462,7 +460,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
462
460
  The result of the comparison.
463
461
  """
464
462
  if isinstance(other, NUMBER_TYPES):
465
- return equal_operation(self, +other)
463
+ return equal_operation(+self, +other)
466
464
  return equal_operation(self, other)
467
465
 
468
466
  def __ne__(self, other: Any):
@@ -475,14 +473,14 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
475
473
  The result of the comparison.
476
474
  """
477
475
  if isinstance(other, NUMBER_TYPES):
478
- return not_equal_operation(self, +other)
476
+ return not_equal_operation(+self, +other)
479
477
  return not_equal_operation(self, other)
480
478
 
481
479
  @overload
482
480
  def __gt__(self, other: number_types) -> BooleanVar: ...
483
481
 
484
482
  @overload
485
- def __gt__(self, other: NoReturn) -> NoReturn: ...
483
+ def __gt__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
486
484
 
487
485
  def __gt__(self, other: Any):
488
486
  """Greater than comparison.
@@ -495,13 +493,13 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
495
493
  """
496
494
  if not isinstance(other, NUMBER_TYPES):
497
495
  raise_unsupported_operand_types(">", (type(self), type(other)))
498
- return greater_than_operation(self, +other)
496
+ return greater_than_operation(+self, +other)
499
497
 
500
498
  @overload
501
499
  def __ge__(self, other: number_types) -> BooleanVar: ...
502
500
 
503
501
  @overload
504
- def __ge__(self, other: NoReturn) -> NoReturn: ...
502
+ def __ge__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
505
503
 
506
504
  def __ge__(self, other: Any):
507
505
  """Greater than or equal comparison.
@@ -514,17 +512,7 @@ class NumberVar(Var[NUMBER_T], python_types=(int, float)):
514
512
  """
515
513
  if not isinstance(other, NUMBER_TYPES):
516
514
  raise_unsupported_operand_types(">=", (type(self), type(other)))
517
- return greater_than_or_equal_operation(self, +other)
518
-
519
- def bool(self):
520
- """Boolean conversion.
521
-
522
- Returns:
523
- The boolean value of the number.
524
- """
525
- if is_optional(self._var_type):
526
- return boolify((self != None) & (self != 0)) # noqa: E711
527
- return self != 0
515
+ return greater_than_or_equal_operation(+self, +other)
528
516
 
529
517
  def _is_strict_float(self) -> bool:
530
518
  """Check if the number is a float.
@@ -572,7 +560,7 @@ def binary_number_operation(
572
560
  Returns:
573
561
  The binary number operation.
574
562
  """
575
- return operation(lhs, rhs) # type: ignore
563
+ return operation(lhs, rhs) # pyright: ignore [reportReturnType, reportArgumentType]
576
564
 
577
565
  return wrapper
578
566
 
@@ -984,7 +972,7 @@ def boolean_not_operation(value: BooleanVar):
984
972
  @dataclasses.dataclass(
985
973
  eq=False,
986
974
  frozen=True,
987
- **{"slots": True} if sys.version_info >= (3, 10) else {},
975
+ slots=True,
988
976
  )
989
977
  class LiteralNumberVar(LiteralVar, NumberVar):
990
978
  """Base class for immutable literal number vars."""
@@ -998,10 +986,10 @@ class LiteralNumberVar(LiteralVar, NumberVar):
998
986
  The JSON representation of the var.
999
987
 
1000
988
  Raises:
1001
- PrimitiveUnserializableToJSON: If the var is unserializable to JSON.
989
+ PrimitiveUnserializableToJSONError: If the var is unserializable to JSON.
1002
990
  """
1003
991
  if math.isinf(self._var_value) or math.isnan(self._var_value):
1004
- raise PrimitiveUnserializableToJSON(
992
+ raise PrimitiveUnserializableToJSONError(
1005
993
  f"No valid JSON representation for {self}"
1006
994
  )
1007
995
  return json.dumps(self._var_value)
@@ -1043,7 +1031,7 @@ class LiteralNumberVar(LiteralVar, NumberVar):
1043
1031
  @dataclasses.dataclass(
1044
1032
  eq=False,
1045
1033
  frozen=True,
1046
- **{"slots": True} if sys.version_info >= (3, 10) else {},
1034
+ slots=True,
1047
1035
  )
1048
1036
  class LiteralBooleanVar(LiteralVar, BooleanVar):
1049
1037
  """Base class for immutable literal boolean vars."""
reflex/vars/object.py CHANGED
@@ -3,13 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import dataclasses
6
- import sys
7
6
  import typing
8
7
  from inspect import isclass
9
8
  from typing import (
10
9
  Any,
11
- Dict,
12
10
  List,
11
+ Mapping,
13
12
  NoReturn,
14
13
  Tuple,
15
14
  Type,
@@ -19,9 +18,16 @@ from typing import (
19
18
  overload,
20
19
  )
21
20
 
21
+ from typing_extensions import is_typeddict
22
+
22
23
  from reflex.utils import types
23
24
  from reflex.utils.exceptions import VarAttributeError
24
- from reflex.utils.types import GenericType, get_attribute_access_type, get_origin
25
+ from reflex.utils.types import (
26
+ GenericType,
27
+ get_attribute_access_type,
28
+ get_origin,
29
+ safe_issubclass,
30
+ )
25
31
 
26
32
  from .base import (
27
33
  CachedVarOperation,
@@ -36,7 +42,7 @@ from .base import (
36
42
  from .number import BooleanVar, NumberVar, raise_unsupported_operand_types
37
43
  from .sequence import ArrayVar, StringVar
38
44
 
39
- OBJECT_TYPE = TypeVar("OBJECT_TYPE")
45
+ OBJECT_TYPE = TypeVar("OBJECT_TYPE", covariant=True)
40
46
 
41
47
  KEY_TYPE = TypeVar("KEY_TYPE")
42
48
  VALUE_TYPE = TypeVar("VALUE_TYPE")
@@ -46,7 +52,7 @@ ARRAY_INNER_TYPE = TypeVar("ARRAY_INNER_TYPE")
46
52
  OTHER_KEY_TYPE = TypeVar("OTHER_KEY_TYPE")
47
53
 
48
54
 
49
- class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
55
+ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
50
56
  """Base class for immutable object vars."""
51
57
 
52
58
  def _key_type(self) -> Type:
@@ -59,7 +65,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
59
65
 
60
66
  @overload
61
67
  def _value_type(
62
- self: ObjectVar[Dict[Any, VALUE_TYPE]],
68
+ self: ObjectVar[Mapping[Any, VALUE_TYPE]],
63
69
  ) -> Type[VALUE_TYPE]: ...
64
70
 
65
71
  @overload
@@ -73,9 +79,9 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
73
79
  """
74
80
  fixed_type = get_origin(self._var_type) or self._var_type
75
81
  if not isclass(fixed_type):
76
- return Any
77
- args = get_args(self._var_type) if issubclass(fixed_type, dict) else ()
78
- return args[1] if args else Any
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]
79
85
 
80
86
  def keys(self) -> ArrayVar[List[str]]:
81
87
  """Get the keys of the object.
@@ -87,7 +93,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
87
93
 
88
94
  @overload
89
95
  def values(
90
- self: ObjectVar[Dict[Any, VALUE_TYPE]],
96
+ self: ObjectVar[Mapping[Any, VALUE_TYPE]],
91
97
  ) -> ArrayVar[List[VALUE_TYPE]]: ...
92
98
 
93
99
  @overload
@@ -103,7 +109,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
103
109
 
104
110
  @overload
105
111
  def entries(
106
- self: ObjectVar[Dict[Any, VALUE_TYPE]],
112
+ self: ObjectVar[Mapping[Any, VALUE_TYPE]],
107
113
  ) -> ArrayVar[List[Tuple[str, VALUE_TYPE]]]: ...
108
114
 
109
115
  @overload
@@ -132,50 +138,50 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
132
138
 
133
139
  # NoReturn is used here to catch when key value is Any
134
140
  @overload
135
- def __getitem__(
136
- self: ObjectVar[Dict[Any, NoReturn]],
141
+ def __getitem__( # pyright: ignore [reportOverlappingOverload]
142
+ self: ObjectVar[Mapping[Any, NoReturn]],
137
143
  key: Var | Any,
138
144
  ) -> Var: ...
139
145
 
146
+ @overload
147
+ def __getitem__(
148
+ self: (ObjectVar[Mapping[Any, bool]]),
149
+ key: Var | Any,
150
+ ) -> BooleanVar: ...
151
+
140
152
  @overload
141
153
  def __getitem__(
142
154
  self: (
143
- ObjectVar[Dict[Any, int]]
144
- | ObjectVar[Dict[Any, float]]
145
- | ObjectVar[Dict[Any, int | float]]
155
+ ObjectVar[Mapping[Any, int]]
156
+ | ObjectVar[Mapping[Any, float]]
157
+ | ObjectVar[Mapping[Any, int | float]]
146
158
  ),
147
159
  key: Var | Any,
148
160
  ) -> NumberVar: ...
149
161
 
150
162
  @overload
151
163
  def __getitem__(
152
- self: ObjectVar[Dict[Any, str]],
164
+ self: ObjectVar[Mapping[Any, str]],
153
165
  key: Var | Any,
154
166
  ) -> StringVar: ...
155
167
 
156
168
  @overload
157
169
  def __getitem__(
158
- self: ObjectVar[Dict[Any, list[ARRAY_INNER_TYPE]]],
170
+ self: ObjectVar[Mapping[Any, list[ARRAY_INNER_TYPE]]],
159
171
  key: Var | Any,
160
172
  ) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
161
173
 
162
174
  @overload
163
175
  def __getitem__(
164
- self: ObjectVar[Dict[Any, set[ARRAY_INNER_TYPE]]],
165
- key: Var | Any,
166
- ) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
167
-
168
- @overload
169
- def __getitem__(
170
- self: ObjectVar[Dict[Any, tuple[ARRAY_INNER_TYPE, ...]]],
176
+ self: ObjectVar[Mapping[Any, tuple[ARRAY_INNER_TYPE, ...]]],
171
177
  key: Var | Any,
172
178
  ) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
173
179
 
174
180
  @overload
175
181
  def __getitem__(
176
- self: ObjectVar[Dict[Any, dict[OTHER_KEY_TYPE, VALUE_TYPE]]],
182
+ self: ObjectVar[Mapping[Any, Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]],
177
183
  key: Var | Any,
178
- ) -> ObjectVar[dict[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
184
+ ) -> ObjectVar[Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
179
185
 
180
186
  def __getitem__(self, key: Var | Any) -> Var:
181
187
  """Get an item from the object.
@@ -186,58 +192,56 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
186
192
  Returns:
187
193
  The item from the object.
188
194
  """
195
+ from .sequence import LiteralStringVar
196
+
189
197
  if not isinstance(key, (StringVar, str, int, NumberVar)) or (
190
198
  isinstance(key, NumberVar) and key._is_strict_float()
191
199
  ):
192
200
  raise_unsupported_operand_types("[]", (type(self), type(key)))
201
+ if isinstance(key, str) and isinstance(Var.create(key), LiteralStringVar):
202
+ return self.__getattr__(key)
193
203
  return ObjectItemOperation.create(self, key).guess_type()
194
204
 
195
205
  # NoReturn is used here to catch when key value is Any
196
206
  @overload
197
- def __getattr__(
198
- self: ObjectVar[Dict[Any, NoReturn]],
207
+ def __getattr__( # pyright: ignore [reportOverlappingOverload]
208
+ self: ObjectVar[Mapping[Any, NoReturn]],
199
209
  name: str,
200
210
  ) -> Var: ...
201
211
 
202
212
  @overload
203
213
  def __getattr__(
204
214
  self: (
205
- ObjectVar[Dict[Any, int]]
206
- | ObjectVar[Dict[Any, float]]
207
- | ObjectVar[Dict[Any, int | float]]
215
+ ObjectVar[Mapping[Any, int]]
216
+ | ObjectVar[Mapping[Any, float]]
217
+ | ObjectVar[Mapping[Any, int | float]]
208
218
  ),
209
219
  name: str,
210
220
  ) -> NumberVar: ...
211
221
 
212
222
  @overload
213
223
  def __getattr__(
214
- self: ObjectVar[Dict[Any, str]],
224
+ self: ObjectVar[Mapping[Any, str]],
215
225
  name: str,
216
226
  ) -> StringVar: ...
217
227
 
218
228
  @overload
219
229
  def __getattr__(
220
- self: ObjectVar[Dict[Any, list[ARRAY_INNER_TYPE]]],
230
+ self: ObjectVar[Mapping[Any, list[ARRAY_INNER_TYPE]]],
221
231
  name: str,
222
232
  ) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
223
233
 
224
234
  @overload
225
235
  def __getattr__(
226
- self: ObjectVar[Dict[Any, set[ARRAY_INNER_TYPE]]],
227
- name: str,
228
- ) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
229
-
230
- @overload
231
- def __getattr__(
232
- self: ObjectVar[Dict[Any, tuple[ARRAY_INNER_TYPE, ...]]],
236
+ self: ObjectVar[Mapping[Any, tuple[ARRAY_INNER_TYPE, ...]]],
233
237
  name: str,
234
238
  ) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
235
239
 
236
240
  @overload
237
241
  def __getattr__(
238
- self: ObjectVar[Dict[Any, dict[OTHER_KEY_TYPE, VALUE_TYPE]]],
242
+ self: ObjectVar[Mapping[Any, Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]],
239
243
  name: str,
240
- ) -> ObjectVar[dict[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
244
+ ) -> ObjectVar[Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
241
245
 
242
246
  @overload
243
247
  def __getattr__(
@@ -245,7 +249,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
245
249
  name: str,
246
250
  ) -> ObjectItemOperation: ...
247
251
 
248
- def __getattr__(self, name) -> Var:
252
+ def __getattr__(self, name: str) -> Var:
249
253
  """Get an attribute of the var.
250
254
 
251
255
  Args:
@@ -265,9 +269,12 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
265
269
  if types.is_optional(var_type):
266
270
  var_type = get_args(var_type)[0]
267
271
 
268
- fixed_type = var_type if isclass(var_type) else get_origin(var_type)
269
- if (isclass(fixed_type) and not issubclass(fixed_type, dict)) or (
270
- fixed_type in types.UnionTypes
272
+ fixed_type = get_origin(var_type) or var_type
273
+
274
+ if (
275
+ is_typeddict(fixed_type)
276
+ or (isclass(fixed_type) and not safe_issubclass(fixed_type, Mapping))
277
+ or (fixed_type in types.UnionTypes)
271
278
  ):
272
279
  attribute_type = get_attribute_access_type(var_type, name)
273
280
  if attribute_type is None:
@@ -294,12 +301,12 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
294
301
  @dataclasses.dataclass(
295
302
  eq=False,
296
303
  frozen=True,
297
- **{"slots": True} if sys.version_info >= (3, 10) else {},
304
+ slots=True,
298
305
  )
299
306
  class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
300
307
  """Base class for immutable literal object vars."""
301
308
 
302
- _var_value: Dict[Union[Var, Any], Union[Var, Any]] = dataclasses.field(
309
+ _var_value: Mapping[Union[Var, Any], Union[Var, Any]] = dataclasses.field(
303
310
  default_factory=dict
304
311
  )
305
312
 
@@ -310,7 +317,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
310
317
  The type of the keys of the object.
311
318
  """
312
319
  args_list = typing.get_args(self._var_type)
313
- return args_list[0] if args_list else Any
320
+ return args_list[0] if args_list else Any # pyright: ignore [reportReturnType]
314
321
 
315
322
  def _value_type(self) -> Type:
316
323
  """Get the type of the values of the object.
@@ -319,7 +326,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
319
326
  The type of the values of the object.
320
327
  """
321
328
  args_list = typing.get_args(self._var_type)
322
- return args_list[1] if args_list else Any
329
+ return args_list[1] if args_list else Any # pyright: ignore [reportReturnType]
323
330
 
324
331
  @cached_property_no_lock
325
332
  def _cached_var_name(self) -> str:
@@ -344,17 +351,20 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
344
351
 
345
352
  Returns:
346
353
  The JSON representation of the object.
354
+
355
+ Raises:
356
+ TypeError: The keys and values of the object must be literal vars to get the JSON representation
347
357
  """
348
- return (
349
- "{"
350
- + ", ".join(
351
- [
352
- f"{LiteralVar.create(key).json()}:{LiteralVar.create(value).json()}"
353
- for key, value in self._var_value.items()
354
- ]
355
- )
356
- + "}"
357
- )
358
+ keys_and_values = []
359
+ for key, value in self._var_value.items():
360
+ key = LiteralVar.create(key)
361
+ value = LiteralVar.create(value)
362
+ if not isinstance(key, LiteralVar) or not isinstance(value, LiteralVar):
363
+ raise TypeError(
364
+ "The keys and values of the object must be literal vars to get the JSON representation."
365
+ )
366
+ keys_and_values.append(f"{key.json()}:{value.json()}")
367
+ return "{" + ", ".join(keys_and_values) + "}"
358
368
 
359
369
  def __hash__(self) -> int:
360
370
  """Get the hash of the var.
@@ -383,7 +393,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
383
393
  @classmethod
384
394
  def create(
385
395
  cls,
386
- _var_value: dict,
396
+ _var_value: Mapping,
387
397
  _var_type: Type[OBJECT_TYPE] | None = None,
388
398
  _var_data: VarData | None = None,
389
399
  ) -> LiteralObjectVar[OBJECT_TYPE]:
@@ -466,7 +476,7 @@ def object_merge_operation(lhs: ObjectVar, rhs: ObjectVar):
466
476
  """
467
477
  return var_operation_return(
468
478
  js_expression=f"({{...{lhs}, ...{rhs}}})",
469
- var_type=Dict[
479
+ var_type=Mapping[
470
480
  Union[lhs._key_type(), rhs._key_type()],
471
481
  Union[lhs._value_type(), rhs._value_type()],
472
482
  ],
@@ -476,7 +486,7 @@ def object_merge_operation(lhs: ObjectVar, rhs: ObjectVar):
476
486
  @dataclasses.dataclass(
477
487
  eq=False,
478
488
  frozen=True,
479
- **{"slots": True} if sys.version_info >= (3, 10) else {},
489
+ slots=True,
480
490
  )
481
491
  class ObjectItemOperation(CachedVarOperation, Var):
482
492
  """Operation to get an item from an object."""