reflex 0.7.7a2__py3-none-any.whl → 0.7.8__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 (185) hide show
  1. reflex/.templates/web/utils/state.js +26 -16
  2. reflex/admin.py +1 -1
  3. reflex/app.py +6 -17
  4. reflex/app_mixins/lifespan.py +1 -1
  5. reflex/base.py +2 -2
  6. reflex/compiler/compiler.py +8 -7
  7. reflex/compiler/utils.py +6 -5
  8. reflex/components/base/app_wrap.pyi +18 -17
  9. reflex/components/base/bare.py +2 -1
  10. reflex/components/base/body.pyi +18 -17
  11. reflex/components/base/document.pyi +82 -81
  12. reflex/components/base/error_boundary.pyi +19 -18
  13. reflex/components/base/fragment.pyi +18 -17
  14. reflex/components/base/head.pyi +34 -33
  15. reflex/components/base/link.pyi +34 -33
  16. reflex/components/base/meta.pyi +66 -65
  17. reflex/components/base/script.pyi +21 -20
  18. reflex/components/base/strict_mode.pyi +18 -17
  19. reflex/components/component.py +20 -36
  20. reflex/components/core/auto_scroll.pyi +18 -17
  21. reflex/components/core/banner.pyi +98 -97
  22. reflex/components/core/breakpoints.py +1 -1
  23. reflex/components/core/client_side_routing.pyi +34 -33
  24. reflex/components/core/clipboard.py +1 -1
  25. reflex/components/core/clipboard.pyi +19 -18
  26. reflex/components/core/cond.py +2 -2
  27. reflex/components/core/debounce.py +3 -3
  28. reflex/components/core/debounce.pyi +20 -19
  29. reflex/components/core/foreach.py +2 -1
  30. reflex/components/core/html.pyi +18 -17
  31. reflex/components/core/match.py +2 -2
  32. reflex/components/core/sticky.pyi +66 -65
  33. reflex/components/core/upload.py +7 -10
  34. reflex/components/core/upload.pyi +86 -85
  35. reflex/components/datadisplay/code.pyi +34 -33
  36. reflex/components/datadisplay/dataeditor.py +3 -2
  37. reflex/components/datadisplay/dataeditor.pyi +35 -68
  38. reflex/components/datadisplay/shiki_code_block.pyi +50 -49
  39. reflex/components/el/element.pyi +18 -17
  40. reflex/components/el/elements/base.pyi +18 -17
  41. reflex/components/el/elements/forms.py +2 -1
  42. reflex/components/el/elements/forms.pyi +290 -332
  43. reflex/components/el/elements/inline.pyi +450 -449
  44. reflex/components/el/elements/media.pyi +402 -401
  45. reflex/components/el/elements/metadata.pyi +98 -97
  46. reflex/components/el/elements/other.pyi +114 -113
  47. reflex/components/el/elements/scripts.pyi +50 -49
  48. reflex/components/el/elements/sectioning.pyi +242 -241
  49. reflex/components/el/elements/tables.pyi +162 -161
  50. reflex/components/el/elements/typography.pyi +242 -241
  51. reflex/components/gridjs/datatable.py +3 -2
  52. reflex/components/gridjs/datatable.pyi +35 -34
  53. reflex/components/lucide/icon.pyi +50 -49
  54. reflex/components/markdown/markdown.py +2 -1
  55. reflex/components/markdown/markdown.pyi +18 -17
  56. reflex/components/moment/moment.pyi +19 -18
  57. reflex/components/next/base.pyi +18 -17
  58. reflex/components/next/image.pyi +20 -19
  59. reflex/components/next/link.pyi +18 -17
  60. reflex/components/next/video.pyi +18 -17
  61. reflex/components/plotly/plotly.py +3 -3
  62. reflex/components/plotly/plotly.pyi +326 -325
  63. reflex/components/radix/primitives/accordion.py +2 -1
  64. reflex/components/radix/primitives/accordion.pyi +115 -114
  65. reflex/components/radix/primitives/base.pyi +34 -33
  66. reflex/components/radix/primitives/drawer.py +2 -1
  67. reflex/components/radix/primitives/drawer.pyi +187 -186
  68. reflex/components/radix/primitives/form.pyi +168 -182
  69. reflex/components/radix/primitives/progress.pyi +82 -81
  70. reflex/components/radix/primitives/slider.py +2 -1
  71. reflex/components/radix/primitives/slider.pyi +84 -83
  72. reflex/components/radix/themes/base.pyi +130 -129
  73. reflex/components/radix/themes/color_mode.pyi +51 -50
  74. reflex/components/radix/themes/components/alert_dialog.pyi +118 -117
  75. reflex/components/radix/themes/components/aspect_ratio.pyi +18 -17
  76. reflex/components/radix/themes/components/avatar.pyi +18 -17
  77. reflex/components/radix/themes/components/badge.pyi +18 -17
  78. reflex/components/radix/themes/components/button.pyi +18 -17
  79. reflex/components/radix/themes/components/callout.pyi +82 -81
  80. reflex/components/radix/themes/components/card.pyi +18 -17
  81. reflex/components/radix/themes/components/checkbox.pyi +53 -52
  82. reflex/components/radix/themes/components/checkbox_cards.pyi +34 -33
  83. reflex/components/radix/themes/components/checkbox_group.py +2 -1
  84. reflex/components/radix/themes/components/checkbox_group.pyi +34 -33
  85. reflex/components/radix/themes/components/context_menu.pyi +225 -224
  86. reflex/components/radix/themes/components/data_list.pyi +66 -65
  87. reflex/components/radix/themes/components/dialog.pyi +121 -120
  88. reflex/components/radix/themes/components/dropdown_menu.pyi +142 -141
  89. reflex/components/radix/themes/components/hover_card.pyi +68 -67
  90. reflex/components/radix/themes/components/icon_button.pyi +18 -17
  91. reflex/components/radix/themes/components/inset.pyi +18 -17
  92. reflex/components/radix/themes/components/popover.pyi +73 -72
  93. reflex/components/radix/themes/components/progress.pyi +18 -17
  94. reflex/components/radix/themes/components/radio.pyi +18 -17
  95. reflex/components/radix/themes/components/radio_cards.pyi +35 -34
  96. reflex/components/radix/themes/components/radio_group.py +2 -1
  97. reflex/components/radix/themes/components/radio_group.pyi +67 -66
  98. reflex/components/radix/themes/components/scroll_area.pyi +18 -17
  99. reflex/components/radix/themes/components/segmented_control.py +2 -1
  100. reflex/components/radix/themes/components/segmented_control.pyi +35 -34
  101. reflex/components/radix/themes/components/select.py +2 -1
  102. reflex/components/radix/themes/components/select.pyi +155 -154
  103. reflex/components/radix/themes/components/separator.pyi +18 -17
  104. reflex/components/radix/themes/components/skeleton.pyi +18 -17
  105. reflex/components/radix/themes/components/slider.py +2 -1
  106. reflex/components/radix/themes/components/slider.pyi +20 -31
  107. reflex/components/radix/themes/components/spinner.pyi +18 -17
  108. reflex/components/radix/themes/components/switch.pyi +19 -18
  109. reflex/components/radix/themes/components/table.pyi +114 -113
  110. reflex/components/radix/themes/components/tabs.pyi +84 -83
  111. reflex/components/radix/themes/components/text_area.pyi +21 -24
  112. reflex/components/radix/themes/components/text_field.pyi +56 -63
  113. reflex/components/radix/themes/components/tooltip.py +2 -2
  114. reflex/components/radix/themes/components/tooltip.pyi +21 -20
  115. reflex/components/radix/themes/layout/base.pyi +18 -17
  116. reflex/components/radix/themes/layout/box.pyi +18 -17
  117. reflex/components/radix/themes/layout/center.pyi +18 -17
  118. reflex/components/radix/themes/layout/container.pyi +18 -17
  119. reflex/components/radix/themes/layout/flex.pyi +18 -17
  120. reflex/components/radix/themes/layout/grid.pyi +18 -17
  121. reflex/components/radix/themes/layout/list.py +2 -1
  122. reflex/components/radix/themes/layout/list.pyi +82 -81
  123. reflex/components/radix/themes/layout/section.pyi +18 -17
  124. reflex/components/radix/themes/layout/spacer.pyi +18 -17
  125. reflex/components/radix/themes/layout/stack.pyi +50 -49
  126. reflex/components/radix/themes/typography/blockquote.pyi +18 -17
  127. reflex/components/radix/themes/typography/code.pyi +18 -17
  128. reflex/components/radix/themes/typography/heading.pyi +18 -17
  129. reflex/components/radix/themes/typography/link.pyi +18 -17
  130. reflex/components/radix/themes/typography/text.pyi +114 -113
  131. reflex/components/react_player/audio.pyi +34 -36
  132. reflex/components/react_player/react_player.pyi +34 -33
  133. reflex/components/react_player/video.pyi +34 -36
  134. reflex/components/recharts/cartesian.py +7 -6
  135. reflex/components/recharts/cartesian.pyi +302 -301
  136. reflex/components/recharts/charts.py +2 -1
  137. reflex/components/recharts/charts.pyi +177 -176
  138. reflex/components/recharts/general.py +3 -2
  139. reflex/components/recharts/general.pyi +99 -98
  140. reflex/components/recharts/polar.py +9 -8
  141. reflex/components/recharts/polar.pyi +62 -61
  142. reflex/components/recharts/recharts.pyi +34 -33
  143. reflex/components/sonner/toast.pyi +19 -18
  144. reflex/components/suneditor/editor.py +22 -24
  145. reflex/components/suneditor/editor.pyi +27 -28
  146. reflex/components/tags/cond_tag.py +3 -3
  147. reflex/components/tags/iter_tag.py +2 -1
  148. reflex/components/tags/tag.py +3 -2
  149. reflex/config.py +27 -17
  150. reflex/constants/installer.py +4 -4
  151. reflex/constants/route.py +2 -3
  152. reflex/constants/utils.py +4 -3
  153. reflex/event.py +56 -28
  154. reflex/experimental/client_state.py +3 -2
  155. reflex/experimental/layout.pyi +84 -83
  156. reflex/istate/data.py +1 -1
  157. reflex/istate/storage.py +2 -2
  158. reflex/model.py +3 -3
  159. reflex/page.py +3 -2
  160. reflex/state.py +56 -57
  161. reflex/style.py +3 -2
  162. reflex/testing.py +12 -21
  163. reflex/utils/codespaces.py +14 -15
  164. reflex/utils/decorator.py +2 -1
  165. reflex/utils/exec.py +1 -1
  166. reflex/utils/format.py +2 -2
  167. reflex/utils/imports.py +6 -8
  168. reflex/utils/misc.py +2 -1
  169. reflex/utils/net.py +2 -1
  170. reflex/utils/prerequisites.py +12 -5
  171. reflex/utils/processes.py +6 -5
  172. reflex/utils/pyi_generator.py +6 -5
  173. reflex/utils/serializers.py +13 -25
  174. reflex/utils/types.py +34 -46
  175. reflex/vars/base.py +60 -56
  176. reflex/vars/dep_tracking.py +4 -4
  177. reflex/vars/function.py +13 -36
  178. reflex/vars/number.py +5 -17
  179. reflex/vars/object.py +9 -16
  180. reflex/vars/sequence.py +11 -23
  181. {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/METADATA +1 -1
  182. {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/RECORD +185 -185
  183. {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/WHEEL +0 -0
  184. {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/entry_points.txt +0 -0
  185. {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import enum
6
- from typing import Any, Dict, Literal, Union
6
+ from typing import Any, Literal
7
7
 
8
8
  from reflex.base import Base
9
9
  from reflex.components.component import Component, NoSSRComponent
@@ -118,29 +118,27 @@ class Editor(NoSSRComponent):
118
118
  # "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it"
119
119
  # default: "en".
120
120
  lang: Var[
121
- Union[
122
- Literal[
123
- "en",
124
- "da",
125
- "de",
126
- "es",
127
- "fr",
128
- "ja",
129
- "ko",
130
- "pt_br",
131
- "ru",
132
- "zh_cn",
133
- "ro",
134
- "pl",
135
- "ckb",
136
- "lv",
137
- "se",
138
- "ua",
139
- "he",
140
- "it",
141
- ],
142
- dict,
121
+ Literal[
122
+ "en",
123
+ "da",
124
+ "de",
125
+ "es",
126
+ "fr",
127
+ "ja",
128
+ "ko",
129
+ "pt_br",
130
+ "ru",
131
+ "zh_cn",
132
+ "ro",
133
+ "pl",
134
+ "ckb",
135
+ "lv",
136
+ "se",
137
+ "ua",
138
+ "he",
139
+ "it",
143
140
  ]
141
+ | dict
144
142
  ]
145
143
 
146
144
  # This is used to set the HTML form name of the editor.
@@ -169,7 +167,7 @@ class Editor(NoSSRComponent):
169
167
  auto_focus: Var[bool]
170
168
 
171
169
  # Pass an EditorOptions instance to modify the behaviour of Editor even more.
172
- set_options: Var[Dict]
170
+ set_options: Var[dict]
173
171
 
174
172
  # Whether all SunEditor plugins should be loaded.
175
173
  # default: True.
@@ -4,7 +4,8 @@
4
4
  # This file was generated by `reflex/utils/pyi_generator.py`!
5
5
  # ------------------------------------------------------
6
6
  import enum
7
- from typing import Any, Dict, Literal, Mapping, Optional, Sequence, overload
7
+ from collections.abc import Mapping, Sequence
8
+ from typing import Any, Literal, overload
8
9
 
9
10
  from reflex.base import Base
10
11
  from reflex.components.component import NoSSRComponent
@@ -107,7 +108,7 @@ class Editor(NoSSRComponent):
107
108
  height: Var[str] | str | None = None,
108
109
  placeholder: Var[str] | str | None = None,
109
110
  auto_focus: Var[bool] | bool | None = None,
110
- set_options: Dict | Var[Dict] | None = None,
111
+ set_options: Var[dict] | dict | None = None,
111
112
  set_all_plugins: Var[bool] | bool | None = None,
112
113
  set_contents: Var[str] | str | None = None,
113
114
  append_contents: Var[str] | str | None = None,
@@ -126,33 +127,31 @@ class Editor(NoSSRComponent):
126
127
  class_name: Any | None = None,
127
128
  autofocus: bool | None = None,
128
129
  custom_attrs: dict[str, Var | Any] | None = None,
129
- on_blur: Optional[EventType[()] | EventType[str]] = None,
130
- on_change: Optional[EventType[()] | EventType[str]] = None,
131
- on_click: Optional[EventType[()]] = None,
132
- on_context_menu: Optional[EventType[()]] = None,
133
- on_copy: Optional[EventType[()]] = None,
134
- on_cut: Optional[EventType[()]] = None,
135
- on_double_click: Optional[EventType[()]] = None,
136
- on_focus: Optional[EventType[()]] = None,
137
- on_input: Optional[EventType[()]] = None,
138
- on_load: Optional[EventType[()] | EventType[bool]] = None,
139
- on_mount: Optional[EventType[()]] = None,
140
- on_mouse_down: Optional[EventType[()]] = None,
141
- on_mouse_enter: Optional[EventType[()]] = None,
142
- on_mouse_leave: Optional[EventType[()]] = None,
143
- on_mouse_move: Optional[EventType[()]] = None,
144
- on_mouse_out: Optional[EventType[()]] = None,
145
- on_mouse_over: Optional[EventType[()]] = None,
146
- on_mouse_up: Optional[EventType[()]] = None,
147
- on_paste: Optional[
148
- EventType[()] | EventType[str] | EventType[str, bool]
149
- ] = None,
150
- on_scroll: Optional[EventType[()]] = None,
151
- on_unmount: Optional[EventType[()]] = None,
152
- toggle_code_view: Optional[EventType[()] | EventType[bool]] = None,
153
- toggle_full_screen: Optional[EventType[()] | EventType[bool]] = None,
130
+ on_blur: EventType[()] | EventType[str] | None = None,
131
+ on_change: EventType[()] | EventType[str] | None = None,
132
+ on_click: EventType[()] | None = None,
133
+ on_context_menu: EventType[()] | None = None,
134
+ on_copy: EventType[()] | None = None,
135
+ on_cut: EventType[()] | None = None,
136
+ on_double_click: EventType[()] | None = None,
137
+ on_focus: EventType[()] | None = None,
138
+ on_input: EventType[()] | None = None,
139
+ on_load: EventType[()] | EventType[bool] | None = None,
140
+ on_mount: EventType[()] | None = None,
141
+ on_mouse_down: EventType[()] | None = None,
142
+ on_mouse_enter: EventType[()] | None = None,
143
+ on_mouse_leave: EventType[()] | None = None,
144
+ on_mouse_move: EventType[()] | None = None,
145
+ on_mouse_out: EventType[()] | None = None,
146
+ on_mouse_over: EventType[()] | None = None,
147
+ on_mouse_up: EventType[()] | None = None,
148
+ on_paste: EventType[()] | EventType[str] | EventType[str, bool] | None = None,
149
+ on_scroll: EventType[()] | None = None,
150
+ on_unmount: EventType[()] | None = None,
151
+ toggle_code_view: EventType[()] | EventType[bool] | None = None,
152
+ toggle_full_screen: EventType[()] | EventType[bool] | None = None,
154
153
  **props,
155
- ) -> "Editor":
154
+ ) -> Editor:
156
155
  """Create an instance of Editor. No children allowed.
157
156
 
158
157
  Args:
@@ -1,7 +1,7 @@
1
1
  """Tag to conditionally render components."""
2
2
 
3
3
  import dataclasses
4
- from typing import Any, Dict
4
+ from typing import Any
5
5
 
6
6
  from reflex.components.tags.tag import Tag
7
7
  from reflex.vars.base import Var
@@ -15,7 +15,7 @@ class CondTag(Tag):
15
15
  cond: Var[Any] = dataclasses.field(default_factory=lambda: Var.create(True))
16
16
 
17
17
  # The code to render if the condition is true.
18
- true_value: Dict = dataclasses.field(default_factory=dict)
18
+ true_value: dict = dataclasses.field(default_factory=dict)
19
19
 
20
20
  # The code to render if the condition is false.
21
- false_value: Dict | None = None
21
+ false_value: dict | None = None
@@ -4,7 +4,8 @@ from __future__ import annotations
4
4
 
5
5
  import dataclasses
6
6
  import inspect
7
- from typing import TYPE_CHECKING, Callable, Iterable
7
+ from collections.abc import Callable, Iterable
8
+ from typing import TYPE_CHECKING
8
9
 
9
10
  from reflex.components.tags.tag import Tag
10
11
  from reflex.utils.types import GenericType
@@ -3,7 +3,8 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import dataclasses
6
- from typing import Any, List, Mapping, Sequence
6
+ from collections.abc import Mapping, Sequence
7
+ from typing import Any
7
8
 
8
9
  from reflex.event import EventChain
9
10
  from reflex.utils import format
@@ -57,7 +58,7 @@ class Tag:
57
58
  {name: LiteralVar.create(value) for name, value in self.props.items()},
58
59
  )
59
60
 
60
- def format_props(self) -> List:
61
+ def format_props(self) -> list:
61
62
  """Format the tag's props.
62
63
 
63
64
  Returns:
reflex/config.py CHANGED
@@ -13,6 +13,7 @@ import platform
13
13
  import sys
14
14
  import threading
15
15
  import urllib.parse
16
+ from collections.abc import Callable
16
17
  from functools import lru_cache
17
18
  from importlib.util import find_spec
18
19
  from pathlib import Path
@@ -21,7 +22,6 @@ from typing import (
21
22
  TYPE_CHECKING,
22
23
  Annotated,
23
24
  Any,
24
- Callable,
25
25
  Generic,
26
26
  TypeVar,
27
27
  get_args,
@@ -49,6 +49,29 @@ except ImportError:
49
49
  load_dotenv = None
50
50
 
51
51
 
52
+ def _load_dotenv_from_str(env_files: str) -> None:
53
+ if not env_files:
54
+ return
55
+
56
+ if load_dotenv is None:
57
+ console.error(
58
+ """The `python-dotenv` package is required to load environment variables from a file. Run `pip install "python-dotenv>=1.0.1"`."""
59
+ )
60
+ return
61
+
62
+ # load env files in reverse order if they exist
63
+ for env_file_path in [
64
+ Path(p) for s in reversed(env_files.split(os.pathsep)) if (p := s.strip())
65
+ ]:
66
+ if env_file_path.exists():
67
+ load_dotenv(env_file_path, override=True)
68
+
69
+
70
+ # Load the env files at import time if they are set in the ENV_FILE environment variable.
71
+ if load_dotenv is not None and (env_files := os.getenv("ENV_FILE")):
72
+ _load_dotenv_from_str(env_files)
73
+
74
+
52
75
  class DBConfig(Base):
53
76
  """Database config."""
54
77
 
@@ -410,7 +433,7 @@ class EnvVar(Generic[T]):
410
433
  os.environ[self.name] = str_value
411
434
 
412
435
 
413
- @lru_cache()
436
+ @lru_cache
414
437
  def get_type_hints_environment(cls: type) -> dict[str, Any]:
415
438
  """Get the type hints for the environment variables.
416
439
 
@@ -936,21 +959,8 @@ class Config(Base):
936
959
  Returns:
937
960
  The updated config values.
938
961
  """
939
- env_file = self.env_file or os.environ.get("ENV_FILE", None)
940
- if env_file:
941
- if load_dotenv is None:
942
- console.error(
943
- """The `python-dotenv` package is required to load environment variables from a file. Run `pip install "python-dotenv>=1.0.1"`."""
944
- )
945
- else:
946
- # load env files in reverse order if they exist
947
- for env_file_path in [
948
- Path(p)
949
- for s in reversed(env_file.split(os.pathsep))
950
- if (p := s.strip())
951
- ]:
952
- if env_file_path.exists():
953
- load_dotenv(env_file_path, override=True)
962
+ if self.env_file:
963
+ _load_dotenv_from_str(self.env_file)
954
964
 
955
965
  updated_values = {}
956
966
  # Iterate over the fields.
@@ -75,7 +75,7 @@ fetch-retries=0
75
75
 
76
76
 
77
77
  def _determine_nextjs_version() -> str:
78
- default_version = "15.2.4"
78
+ default_version = "15.3.0"
79
79
  if (version := os.getenv("NEXTJS_VERSION")) and version != default_version:
80
80
  from reflex.utils import console
81
81
 
@@ -92,9 +92,9 @@ class PackageJson(SimpleNamespace):
92
92
  class Commands(SimpleNamespace):
93
93
  """The commands to define in package.json."""
94
94
 
95
- DEV = "next dev"
96
- EXPORT = "next build"
97
- EXPORT_SITEMAP = "next build && next-sitemap"
95
+ DEV = "next dev {flags}"
96
+ EXPORT = "next build {flags}"
97
+ EXPORT_SITEMAP = "next build {flags} && next-sitemap"
98
98
  PROD = "next start"
99
99
 
100
100
  PATH = "package.json"
reflex/constants/route.py CHANGED
@@ -7,9 +7,8 @@ from types import SimpleNamespace
7
7
  class RouteArgType(SimpleNamespace):
8
8
  """Type of dynamic route arg extracted from URI route."""
9
9
 
10
- # Typecast to str is needed for Enum to work.
11
- SINGLE = str("arg_single")
12
- LIST = str("arg_list")
10
+ SINGLE = "arg_single"
11
+ LIST = "arg_list"
13
12
 
14
13
 
15
14
  # the name of the backend var containing path and client information
reflex/constants/utils.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """Utility functions for constants."""
2
2
 
3
- from typing import Any, Callable, Generic, Type, TypeVar
3
+ from collections.abc import Callable
4
+ from typing import Any, Generic, TypeVar
4
5
 
5
6
  T = TypeVar("T")
6
7
  V = TypeVar("V")
@@ -9,7 +10,7 @@ V = TypeVar("V")
9
10
  class classproperty(Generic[T, V]):
10
11
  """A class property decorator."""
11
12
 
12
- def __init__(self, getter: Callable[[Type[T]], V]) -> None:
13
+ def __init__(self, getter: Callable[[type[T]], V]) -> None:
13
14
  """Initialize the class property.
14
15
 
15
16
  Args:
@@ -17,7 +18,7 @@ class classproperty(Generic[T, V]):
17
18
  """
18
19
  self.getter = getattr(getter, "__func__", getter)
19
20
 
20
- def __get__(self, instance: Any, owner: Type[T]) -> V:
21
+ def __get__(self, instance: Any, owner: type[T]) -> V:
21
22
  """Get the value of the class property.
22
23
 
23
24
  Args:
reflex/event.py CHANGED
@@ -7,16 +7,14 @@ import inspect
7
7
  import types
8
8
  import urllib.parse
9
9
  from base64 import b64encode
10
+ from collections.abc import Callable, Sequence
10
11
  from functools import partial
11
12
  from typing import (
12
13
  TYPE_CHECKING,
13
14
  Annotated,
14
15
  Any,
15
- Callable,
16
16
  Generic,
17
17
  Protocol,
18
- Sequence,
19
- Type,
20
18
  TypedDict,
21
19
  TypeVar,
22
20
  get_args,
@@ -40,6 +38,7 @@ from reflex.utils.exceptions import (
40
38
  from reflex.utils.types import (
41
39
  ArgsSpec,
42
40
  GenericType,
41
+ Unset,
43
42
  safe_issubclass,
44
43
  typehint_issubclass,
45
44
  )
@@ -202,13 +201,14 @@ class EventHandler(EventActionsMixin):
202
201
  """
203
202
  return getattr(self.fn, BACKGROUND_TASK_MARKER, False)
204
203
 
205
- def __call__(self, *args: Any) -> EventSpec:
204
+ def __call__(self, *args: Any, **kwargs: Any) -> EventSpec:
206
205
  """Pass arguments to the handler to get an event spec.
207
206
 
208
207
  This method configures event handlers that take in arguments.
209
208
 
210
209
  Args:
211
210
  *args: The arguments to pass to the handler.
211
+ **kwargs: The keyword arguments to pass to the handler.
212
212
 
213
213
  Returns:
214
214
  The event spec, containing both the function and args.
@@ -220,11 +220,34 @@ class EventHandler(EventActionsMixin):
220
220
 
221
221
  # Get the function args.
222
222
  fn_args = list(inspect.signature(self.fn).parameters)[1:]
223
+
224
+ if not isinstance(
225
+ repeated_arg := next(
226
+ (kwarg for kwarg in kwargs if kwarg in fn_args[: len(args)]), Unset()
227
+ ),
228
+ Unset,
229
+ ):
230
+ raise EventHandlerTypeError(
231
+ f"Event handler {self.fn.__name__} received repeated argument {repeated_arg}."
232
+ )
233
+
234
+ if not isinstance(
235
+ extra_arg := next(
236
+ (kwarg for kwarg in kwargs if kwarg not in fn_args), Unset()
237
+ ),
238
+ Unset,
239
+ ):
240
+ raise EventHandlerTypeError(
241
+ f"Event handler {self.fn.__name__} received extra argument {extra_arg}."
242
+ )
243
+
244
+ fn_args = fn_args[: len(args)] + list(kwargs)
245
+
223
246
  fn_args = (Var(_js_expr=arg) for arg in fn_args)
224
247
 
225
248
  # Construct the payload.
226
249
  values = []
227
- for arg in args:
250
+ for arg in [*args, *kwargs.values()]:
228
251
  # Special case for file uploads.
229
252
  if isinstance(arg, FileUpload):
230
253
  return arg.as_event_spec(handler=self)
@@ -645,21 +668,21 @@ class IdentityEventReturn(Generic[T], Protocol):
645
668
 
646
669
  @overload
647
670
  def passthrough_event_spec( # pyright: ignore [reportOverlappingOverload]
648
- event_type: Type[T], /
671
+ event_type: type[T], /
649
672
  ) -> Callable[[Var[T]], tuple[Var[T]]]: ...
650
673
 
651
674
 
652
675
  @overload
653
676
  def passthrough_event_spec(
654
- event_type_1: Type[T], event_type2: Type[U], /
677
+ event_type_1: type[T], event_type2: type[U], /
655
678
  ) -> Callable[[Var[T], Var[U]], tuple[Var[T], Var[U]]]: ...
656
679
 
657
680
 
658
681
  @overload
659
- def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: ...
682
+ def passthrough_event_spec(*event_types: type[T]) -> IdentityEventReturn[T]: ...
660
683
 
661
684
 
662
- def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: # pyright: ignore [reportInconsistentOverload]
685
+ def passthrough_event_spec(*event_types: type[T]) -> IdentityEventReturn[T]: # pyright: ignore [reportInconsistentOverload]
663
686
  """A helper function that returns the input event as output.
664
687
 
665
688
  Args:
@@ -1132,10 +1155,12 @@ def call_script(
1132
1155
  callback_kwargs = {}
1133
1156
  if callback is not None:
1134
1157
  callback_kwargs = {
1135
- "callback": format.format_queue_events(
1136
- callback,
1137
- args_spec=lambda result: [result],
1138
- )._js_expr,
1158
+ "callback": str(
1159
+ format.format_queue_events(
1160
+ callback,
1161
+ args_spec=lambda result: [result],
1162
+ )
1163
+ ),
1139
1164
  }
1140
1165
  if isinstance(javascript_code, str):
1141
1166
  # When there is VarData, include it and eval the JS code inline on the client.
@@ -1171,10 +1196,12 @@ def call_function(
1171
1196
  callback_kwargs = {"callback": None}
1172
1197
  if callback is not None:
1173
1198
  callback_kwargs = {
1174
- "callback": format.format_queue_events(
1175
- callback,
1176
- args_spec=lambda result: [result],
1177
- ),
1199
+ "callback": str(
1200
+ format.format_queue_events(
1201
+ callback,
1202
+ args_spec=lambda result: [result],
1203
+ ),
1204
+ )
1178
1205
  }
1179
1206
 
1180
1207
  javascript_code = (
@@ -1779,7 +1806,7 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
1779
1806
  )
1780
1807
  sig = inspect.signature(arg_spec) # pyright: ignore [reportArgumentType]
1781
1808
  if sig.parameters:
1782
- arg_def = tuple((f"_{p}" for p in sig.parameters))
1809
+ arg_def = tuple(f"_{p}" for p in sig.parameters)
1783
1810
  arg_def_expr = LiteralVar.create([Var(_js_expr=arg) for arg in arg_def])
1784
1811
  else:
1785
1812
  # add a default argument for addEvents if none were specified in value.args_spec
@@ -1960,7 +1987,9 @@ IndividualEventType = TypeAliasType(
1960
1987
  )
1961
1988
 
1962
1989
  EventType = TypeAliasType(
1963
- "EventType", ItemOrList[IndividualEventType[Unpack[ARGS]]], type_params=(ARGS,)
1990
+ "EventType",
1991
+ ItemOrList[LAMBDA_OR_STATE[Unpack[ARGS]] | BASIC_EVENT_TYPES],
1992
+ type_params=(ARGS,),
1964
1993
  )
1965
1994
 
1966
1995
 
@@ -1972,7 +2001,7 @@ else:
1972
2001
  BASE_STATE = TypeVar("BASE_STATE")
1973
2002
 
1974
2003
 
1975
- class EventNamespace(types.SimpleNamespace):
2004
+ class EventNamespace:
1976
2005
  """A namespace for event related classes."""
1977
2006
 
1978
2007
  Event = Event
@@ -1988,23 +2017,22 @@ class EventNamespace(types.SimpleNamespace):
1988
2017
  EventCallback = EventCallback
1989
2018
 
1990
2019
  @overload
1991
- @staticmethod
1992
- def __call__(
1993
- func: None = None, *, background: bool | None = None
2020
+ def __new__(
2021
+ cls, func: None = None, *, background: bool | None = None
1994
2022
  ) -> Callable[
1995
2023
  [Callable[[BASE_STATE, Unpack[P]], Any]], EventCallback[Unpack[P]] # pyright: ignore [reportInvalidTypeVarUse]
1996
2024
  ]: ...
1997
2025
 
1998
2026
  @overload
1999
- @staticmethod
2000
- def __call__(
2027
+ def __new__(
2028
+ cls,
2001
2029
  func: Callable[[BASE_STATE, Unpack[P]], Any],
2002
2030
  *,
2003
2031
  background: bool | None = None,
2004
2032
  ) -> EventCallback[Unpack[P]]: ...
2005
2033
 
2006
- @staticmethod
2007
- def __call__(
2034
+ def __new__(
2035
+ cls,
2008
2036
  func: Callable[[BASE_STATE, Unpack[P]], Any] | None = None,
2009
2037
  *,
2010
2038
  background: bool | None = None,
@@ -2076,4 +2104,4 @@ class EventNamespace(types.SimpleNamespace):
2076
2104
  run_script = staticmethod(run_script)
2077
2105
 
2078
2106
 
2079
- event = EventNamespace()
2107
+ event = EventNamespace
@@ -4,7 +4,8 @@ from __future__ import annotations
4
4
 
5
5
  import dataclasses
6
6
  import re
7
- from typing import Any, Callable
7
+ from collections.abc import Callable
8
+ from typing import Any
8
9
 
9
10
  from reflex import constants
10
11
  from reflex.event import EventChain, EventHandler, EventSpec, run_script
@@ -77,7 +78,7 @@ class ClientStateVar(Var):
77
78
  var_name: str | None = None,
78
79
  default: Any = NoValue,
79
80
  global_ref: bool = True,
80
- ) -> "ClientStateVar":
81
+ ) -> ClientStateVar:
81
82
  """Create a local_state Var that can be accessed and updated on the client.
82
83
 
83
84
  The `ClientStateVar` should be included in the highest parent component