reflex 0.7.14a5__py3-none-any.whl → 0.8.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.
- reflex/.templates/jinja/app/rxconfig.py.jinja2 +4 -1
- reflex/.templates/jinja/web/package.json.jinja2 +1 -1
- reflex/.templates/jinja/web/pages/_app.js.jinja2 +21 -11
- reflex/.templates/jinja/web/pages/_document.js.jinja2 +1 -1
- reflex/.templates/jinja/web/pages/base_page.js.jinja2 +0 -1
- reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 +4 -0
- reflex/.templates/jinja/web/styles/styles.css.jinja2 +1 -0
- reflex/.templates/jinja/web/utils/context.js.jinja2 +25 -8
- reflex/.templates/web/app/entry.client.js +8 -0
- reflex/.templates/web/app/routes.js +10 -0
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +12 -37
- reflex/.templates/web/postcss.config.js +1 -1
- reflex/.templates/web/react-router.config.js +6 -0
- reflex/.templates/web/styles/__reflex_style_reset.css +399 -0
- reflex/.templates/web/utils/client_side_routing.js +21 -19
- reflex/.templates/web/utils/react-theme.js +92 -0
- reflex/.templates/web/utils/state.js +251 -100
- reflex/.templates/web/vite-plugin-safari-cachebust.js +160 -0
- reflex/.templates/web/vite.config.js +39 -0
- reflex/__init__.py +1 -6
- reflex/__init__.pyi +327 -192
- reflex/app.py +103 -152
- reflex/base.py +1 -87
- reflex/compiler/compiler.py +70 -19
- reflex/compiler/templates.py +3 -3
- reflex/compiler/utils.py +91 -33
- reflex/components/__init__.py +0 -2
- reflex/components/__init__.pyi +34 -18
- reflex/components/base/__init__.py +1 -5
- reflex/components/base/__init__.pyi +30 -21
- reflex/components/base/app_wrap.pyi +7 -7
- reflex/components/base/body.pyi +7 -7
- reflex/components/base/document.py +18 -14
- reflex/components/base/document.pyi +88 -38
- reflex/components/base/error_boundary.pyi +7 -7
- reflex/components/base/fragment.pyi +7 -7
- reflex/components/base/link.pyi +12 -12
- reflex/components/base/meta.py +4 -15
- reflex/components/base/meta.pyi +31 -31
- reflex/components/base/script.py +60 -58
- reflex/components/base/script.pyi +248 -34
- reflex/components/base/strict_mode.pyi +7 -7
- reflex/components/component.py +146 -217
- reflex/components/core/__init__.py +1 -0
- reflex/components/core/__init__.pyi +77 -37
- reflex/components/core/auto_scroll.pyi +7 -7
- reflex/components/core/banner.pyi +33 -33
- reflex/components/core/client_side_routing.py +7 -6
- reflex/components/core/client_side_routing.pyi +8 -59
- reflex/components/core/clipboard.pyi +7 -7
- reflex/components/core/debounce.py +1 -0
- reflex/components/core/debounce.pyi +7 -7
- reflex/components/core/foreach.py +5 -4
- reflex/components/core/helmet.py +14 -0
- reflex/components/{next/base.pyi → core/helmet.pyi} +12 -10
- reflex/components/core/html.pyi +7 -7
- reflex/components/core/match.py +3 -3
- reflex/components/core/sticky.pyi +21 -20
- reflex/components/core/upload.py +4 -2
- reflex/components/core/upload.pyi +26 -25
- reflex/components/datadisplay/__init__.pyi +13 -7
- reflex/components/datadisplay/code.py +14 -79
- reflex/components/datadisplay/code.pyi +11 -13
- reflex/components/datadisplay/dataeditor.pyi +38 -15
- reflex/components/datadisplay/shiki_code_block.py +5 -3
- reflex/components/datadisplay/shiki_code_block.pyi +16 -15
- reflex/components/dynamic.py +5 -5
- reflex/components/el/__init__.pyi +506 -246
- reflex/components/el/element.pyi +7 -7
- reflex/components/el/elements/__init__.pyi +504 -245
- reflex/components/el/elements/base.pyi +7 -7
- reflex/components/el/elements/forms.pyi +146 -101
- reflex/components/el/elements/inline.pyi +142 -142
- reflex/components/el/elements/media.pyi +131 -130
- reflex/components/el/elements/metadata.pyi +32 -32
- reflex/components/el/elements/other.pyi +37 -37
- reflex/components/el/elements/scripts.pyi +17 -17
- reflex/components/el/elements/sectioning.pyi +77 -77
- reflex/components/el/elements/tables.pyi +52 -52
- reflex/components/el/elements/typography.pyi +77 -77
- reflex/components/field.py +175 -0
- reflex/components/gridjs/datatable.py +2 -2
- reflex/components/gridjs/datatable.pyi +14 -14
- reflex/components/lucide/icon.py +6 -2
- reflex/components/lucide/icon.pyi +19 -17
- reflex/components/markdown/markdown.py +5 -3
- reflex/components/markdown/markdown.pyi +7 -7
- reflex/components/moment/moment.py +1 -1
- reflex/components/moment/moment.pyi +7 -7
- reflex/components/plotly/plotly.py +12 -6
- reflex/components/plotly/plotly.pyi +50 -49
- reflex/components/props.py +376 -27
- reflex/components/radix/__init__.pyi +123 -65
- reflex/components/radix/primitives/__init__.pyi +6 -4
- reflex/components/radix/primitives/accordion.py +8 -1
- reflex/components/radix/primitives/accordion.pyi +37 -37
- reflex/components/radix/primitives/base.pyi +12 -12
- reflex/components/radix/primitives/drawer.pyi +56 -55
- reflex/components/radix/primitives/form.pyi +63 -53
- reflex/components/radix/primitives/progress.pyi +26 -25
- reflex/components/radix/primitives/slider.pyi +27 -27
- reflex/components/radix/themes/__init__.pyi +5 -6
- reflex/components/radix/themes/base.py +3 -3
- reflex/components/radix/themes/base.pyi +42 -42
- reflex/components/radix/themes/color_mode.py +5 -6
- reflex/components/radix/themes/color_mode.pyi +17 -17
- reflex/components/radix/themes/components/__init__.pyi +75 -38
- reflex/components/radix/themes/components/alert_dialog.pyi +37 -37
- reflex/components/radix/themes/components/aspect_ratio.pyi +7 -7
- reflex/components/radix/themes/components/avatar.pyi +7 -7
- reflex/components/radix/themes/components/badge.pyi +7 -7
- reflex/components/radix/themes/components/button.pyi +7 -7
- reflex/components/radix/themes/components/callout.pyi +26 -25
- reflex/components/radix/themes/components/card.pyi +7 -7
- reflex/components/radix/themes/components/checkbox.pyi +16 -15
- reflex/components/radix/themes/components/checkbox_cards.pyi +12 -12
- reflex/components/radix/themes/components/checkbox_group.pyi +12 -12
- reflex/components/radix/themes/components/context_menu.pyi +67 -67
- reflex/components/radix/themes/components/data_list.pyi +22 -22
- reflex/components/radix/themes/components/dialog.pyi +36 -35
- reflex/components/radix/themes/components/dropdown_menu.pyi +42 -42
- reflex/components/radix/themes/components/hover_card.pyi +21 -20
- reflex/components/radix/themes/components/icon_button.pyi +7 -7
- reflex/components/radix/themes/components/inset.pyi +7 -7
- reflex/components/radix/themes/components/popover.pyi +22 -22
- reflex/components/radix/themes/components/progress.pyi +7 -7
- reflex/components/radix/themes/components/radio.pyi +7 -7
- reflex/components/radix/themes/components/radio_cards.pyi +12 -12
- reflex/components/radix/themes/components/radio_group.pyi +21 -20
- reflex/components/radix/themes/components/scroll_area.pyi +7 -7
- reflex/components/radix/themes/components/segmented_control.pyi +12 -12
- reflex/components/radix/themes/components/select.pyi +46 -45
- reflex/components/radix/themes/components/separator.pyi +7 -7
- reflex/components/radix/themes/components/skeleton.pyi +7 -7
- reflex/components/radix/themes/components/slider.pyi +17 -9
- reflex/components/radix/themes/components/spinner.pyi +7 -7
- reflex/components/radix/themes/components/switch.pyi +7 -7
- reflex/components/radix/themes/components/table.pyi +37 -37
- reflex/components/radix/themes/components/tabs.pyi +26 -25
- reflex/components/radix/themes/components/text_area.pyi +15 -9
- reflex/components/radix/themes/components/text_field.pyi +32 -19
- reflex/components/radix/themes/components/tooltip.pyi +7 -7
- reflex/components/radix/themes/layout/__init__.pyi +27 -14
- reflex/components/radix/themes/layout/base.pyi +7 -7
- reflex/components/radix/themes/layout/box.pyi +7 -7
- reflex/components/radix/themes/layout/center.pyi +7 -7
- reflex/components/radix/themes/layout/container.pyi +7 -7
- reflex/components/radix/themes/layout/flex.pyi +7 -7
- reflex/components/radix/themes/layout/grid.pyi +7 -7
- reflex/components/radix/themes/layout/list.pyi +26 -25
- reflex/components/radix/themes/layout/section.pyi +7 -7
- reflex/components/radix/themes/layout/spacer.pyi +7 -7
- reflex/components/radix/themes/layout/stack.pyi +17 -17
- reflex/components/radix/themes/typography/__init__.pyi +7 -5
- reflex/components/radix/themes/typography/blockquote.pyi +7 -7
- reflex/components/radix/themes/typography/code.pyi +7 -7
- reflex/components/radix/themes/typography/heading.pyi +7 -7
- reflex/components/radix/themes/typography/link.py +46 -11
- reflex/components/radix/themes/typography/link.pyi +312 -9
- reflex/components/radix/themes/typography/text.pyi +36 -35
- reflex/components/react_player/audio.pyi +10 -8
- reflex/components/react_player/react_player.pyi +7 -7
- reflex/components/react_player/video.pyi +10 -8
- reflex/components/recharts/__init__.pyi +208 -100
- reflex/components/recharts/cartesian.py +10 -8
- reflex/components/recharts/cartesian.pyi +90 -94
- reflex/components/recharts/charts.py +4 -2
- reflex/components/recharts/charts.pyi +49 -49
- reflex/components/recharts/general.pyi +31 -31
- reflex/components/recharts/polar.py +8 -4
- reflex/components/recharts/polar.pyi +23 -23
- reflex/components/recharts/recharts.py +2 -2
- reflex/components/recharts/recharts.pyi +12 -12
- reflex/components/sonner/toast.py +3 -3
- reflex/components/sonner/toast.pyi +9 -9
- reflex/config.py +10 -113
- reflex/constants/__init__.py +2 -2
- reflex/constants/base.py +28 -11
- reflex/constants/compiler.py +12 -3
- reflex/constants/event.py +1 -0
- reflex/constants/installer.py +26 -20
- reflex/constants/route.py +27 -8
- reflex/constants/state.py +2 -0
- reflex/custom_components/custom_components.py +0 -14
- reflex/environment.py +77 -5
- reflex/event.py +178 -81
- reflex/experimental/__init__.py +0 -30
- reflex/istate/__init__.py +69 -0
- reflex/istate/manager.py +1 -0
- reflex/istate/proxy.py +5 -3
- reflex/page.py +0 -27
- reflex/plugins/__init__.py +3 -2
- reflex/plugins/base.py +5 -1
- reflex/plugins/shared_tailwind.py +215 -0
- reflex/plugins/sitemap.py +206 -0
- reflex/plugins/tailwind_v3.py +15 -108
- reflex/plugins/tailwind_v4.py +18 -110
- reflex/reflex.py +1 -0
- reflex/route.py +157 -75
- reflex/state.py +171 -155
- reflex/testing.py +86 -16
- reflex/utils/build.py +38 -82
- reflex/utils/exec.py +83 -175
- reflex/utils/export.py +2 -2
- reflex/utils/format.py +1 -5
- reflex/utils/imports.py +5 -16
- reflex/utils/misc.py +67 -0
- reflex/utils/prerequisites.py +66 -68
- reflex/utils/processes.py +24 -47
- reflex/utils/pyi_generator.py +44 -49
- reflex/utils/serializers.py +14 -1
- reflex/utils/telemetry.py +0 -15
- reflex/utils/types.py +197 -62
- reflex/vars/__init__.py +2 -0
- reflex/vars/base.py +367 -134
- {reflex-0.7.14a5.dist-info → reflex-0.8.0.dist-info}/METADATA +15 -8
- reflex-0.8.0.dist-info/RECORD +403 -0
- reflex/.templates/web/next.config.js +0 -7
- reflex/components/base/head.py +0 -20
- reflex/components/base/head.pyi +0 -116
- reflex/components/next/__init__.py +0 -10
- reflex/components/next/base.py +0 -7
- reflex/components/next/image.py +0 -117
- reflex/components/next/image.pyi +0 -94
- reflex/components/next/link.py +0 -20
- reflex/components/next/link.pyi +0 -67
- reflex/components/next/video.py +0 -38
- reflex/components/next/video.pyi +0 -68
- reflex/components/suneditor/__init__.py +0 -5
- reflex/components/suneditor/editor.py +0 -269
- reflex/components/suneditor/editor.pyi +0 -199
- reflex/experimental/layout.py +0 -254
- reflex-0.7.14a5.dist-info/RECORD +0 -407
- {reflex-0.7.14a5.dist-info → reflex-0.8.0.dist-info}/WHEEL +0 -0
- {reflex-0.7.14a5.dist-info → reflex-0.8.0.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.14a5.dist-info → reflex-0.8.0.dist-info}/licenses/LICENSE +0 -0
reflex/utils/telemetry.py
CHANGED
|
@@ -13,7 +13,6 @@ from datetime import datetime, timezone
|
|
|
13
13
|
from typing import TypedDict
|
|
14
14
|
|
|
15
15
|
import httpx
|
|
16
|
-
import psutil
|
|
17
16
|
|
|
18
17
|
from reflex import constants
|
|
19
18
|
from reflex.environment import environment
|
|
@@ -89,18 +88,6 @@ def get_reflex_enterprise_version() -> str | None:
|
|
|
89
88
|
return None
|
|
90
89
|
|
|
91
90
|
|
|
92
|
-
def get_memory() -> int:
|
|
93
|
-
"""Get the total memory in MB.
|
|
94
|
-
|
|
95
|
-
Returns:
|
|
96
|
-
The total memory in MB.
|
|
97
|
-
"""
|
|
98
|
-
try:
|
|
99
|
-
return psutil.virtual_memory().total >> 20
|
|
100
|
-
except ValueError: # needed to pass ubuntu test
|
|
101
|
-
return 0
|
|
102
|
-
|
|
103
|
-
|
|
104
91
|
def _raise_on_missing_project_hash() -> bool:
|
|
105
92
|
"""Check if an error should be raised when project hash is missing.
|
|
106
93
|
|
|
@@ -128,7 +115,6 @@ class _Properties(TypedDict):
|
|
|
128
115
|
bun_version: str | None
|
|
129
116
|
reflex_enterprise_version: str | None
|
|
130
117
|
cpu_count: int
|
|
131
|
-
memory: int
|
|
132
118
|
cpu_info: dict
|
|
133
119
|
|
|
134
120
|
|
|
@@ -182,7 +168,6 @@ def _get_event_defaults() -> _DefaultEvent | None:
|
|
|
182
168
|
),
|
|
183
169
|
"reflex_enterprise_version": get_reflex_enterprise_version(),
|
|
184
170
|
"cpu_count": get_cpu_count(),
|
|
185
|
-
"memory": get_memory(),
|
|
186
171
|
"cpu_info": dataclasses.asdict(cpuinfo) if cpuinfo else {},
|
|
187
172
|
},
|
|
188
173
|
}
|
reflex/utils/types.py
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import dataclasses
|
|
6
|
-
import
|
|
6
|
+
import sys
|
|
7
7
|
import types
|
|
8
8
|
from collections.abc import Callable, Iterable, Mapping, Sequence
|
|
9
|
-
from functools import cached_property, lru_cache
|
|
9
|
+
from functools import cached_property, lru_cache
|
|
10
10
|
from types import GenericAlias
|
|
11
11
|
from typing import ( # noqa: UP035
|
|
12
12
|
TYPE_CHECKING,
|
|
@@ -19,8 +19,11 @@ from typing import ( # noqa: UP035
|
|
|
19
19
|
Literal,
|
|
20
20
|
MutableMapping,
|
|
21
21
|
NoReturn,
|
|
22
|
+
Protocol,
|
|
22
23
|
Tuple,
|
|
24
|
+
TypeVar,
|
|
23
25
|
Union,
|
|
26
|
+
_eval_type, # pyright: ignore [reportAttributeAccessIssue]
|
|
24
27
|
_GenericAlias, # pyright: ignore [reportAttributeAccessIssue]
|
|
25
28
|
_SpecialGenericAlias, # pyright: ignore [reportAttributeAccessIssue]
|
|
26
29
|
get_args,
|
|
@@ -58,18 +61,91 @@ StateIterVar = list | set | tuple
|
|
|
58
61
|
if TYPE_CHECKING:
|
|
59
62
|
from reflex.vars.base import Var
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
VAR1 = TypeVar("VAR1", bound="Var")
|
|
65
|
+
VAR2 = TypeVar("VAR2", bound="Var")
|
|
66
|
+
VAR3 = TypeVar("VAR3", bound="Var")
|
|
67
|
+
VAR4 = TypeVar("VAR4", bound="Var")
|
|
68
|
+
VAR5 = TypeVar("VAR5", bound="Var")
|
|
69
|
+
VAR6 = TypeVar("VAR6", bound="Var")
|
|
70
|
+
VAR7 = TypeVar("VAR7", bound="Var")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class _ArgsSpec0(Protocol):
|
|
74
|
+
def __call__(self) -> Sequence[Var]: ...
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class _ArgsSpec1(Protocol):
|
|
78
|
+
def __call__(self, var1: VAR1, /) -> Sequence[Var]: ... # pyright: ignore [reportInvalidTypeVarUse]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class _ArgsSpec2(Protocol):
|
|
82
|
+
def __call__(self, var1: VAR1, var2: VAR2, /) -> Sequence[Var]: ... # pyright: ignore [reportInvalidTypeVarUse]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class _ArgsSpec3(Protocol):
|
|
86
|
+
def __call__(self, var1: VAR1, var2: VAR2, var3: VAR3, /) -> Sequence[Var]: ... # pyright: ignore [reportInvalidTypeVarUse]
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class _ArgsSpec4(Protocol):
|
|
90
|
+
def __call__(
|
|
91
|
+
self,
|
|
92
|
+
var1: VAR1, # pyright: ignore [reportInvalidTypeVarUse]
|
|
93
|
+
var2: VAR2, # pyright: ignore [reportInvalidTypeVarUse]
|
|
94
|
+
var3: VAR3, # pyright: ignore [reportInvalidTypeVarUse]
|
|
95
|
+
var4: VAR4, # pyright: ignore [reportInvalidTypeVarUse]
|
|
96
|
+
/,
|
|
97
|
+
) -> Sequence[Var]: ...
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class _ArgsSpec5(Protocol):
|
|
101
|
+
def __call__(
|
|
102
|
+
self,
|
|
103
|
+
var1: VAR1, # pyright: ignore [reportInvalidTypeVarUse]
|
|
104
|
+
var2: VAR2, # pyright: ignore [reportInvalidTypeVarUse]
|
|
105
|
+
var3: VAR3, # pyright: ignore [reportInvalidTypeVarUse]
|
|
106
|
+
var4: VAR4, # pyright: ignore [reportInvalidTypeVarUse]
|
|
107
|
+
var5: VAR5, # pyright: ignore [reportInvalidTypeVarUse]
|
|
108
|
+
/,
|
|
109
|
+
) -> Sequence[Var]: ...
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class _ArgsSpec6(Protocol):
|
|
113
|
+
def __call__(
|
|
114
|
+
self,
|
|
115
|
+
var1: VAR1, # pyright: ignore [reportInvalidTypeVarUse]
|
|
116
|
+
var2: VAR2, # pyright: ignore [reportInvalidTypeVarUse]
|
|
117
|
+
var3: VAR3, # pyright: ignore [reportInvalidTypeVarUse]
|
|
118
|
+
var4: VAR4, # pyright: ignore [reportInvalidTypeVarUse]
|
|
119
|
+
var5: VAR5, # pyright: ignore [reportInvalidTypeVarUse]
|
|
120
|
+
var6: VAR6, # pyright: ignore [reportInvalidTypeVarUse]
|
|
121
|
+
/,
|
|
122
|
+
) -> Sequence[Var]: ...
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class _ArgsSpec7(Protocol):
|
|
126
|
+
def __call__(
|
|
127
|
+
self,
|
|
128
|
+
var1: VAR1, # pyright: ignore [reportInvalidTypeVarUse]
|
|
129
|
+
var2: VAR2, # pyright: ignore [reportInvalidTypeVarUse]
|
|
130
|
+
var3: VAR3, # pyright: ignore [reportInvalidTypeVarUse]
|
|
131
|
+
var4: VAR4, # pyright: ignore [reportInvalidTypeVarUse]
|
|
132
|
+
var5: VAR5, # pyright: ignore [reportInvalidTypeVarUse]
|
|
133
|
+
var6: VAR6, # pyright: ignore [reportInvalidTypeVarUse]
|
|
134
|
+
var7: VAR7, # pyright: ignore [reportInvalidTypeVarUse]
|
|
135
|
+
/,
|
|
136
|
+
) -> Sequence[Var]: ...
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
ArgsSpec = (
|
|
140
|
+
_ArgsSpec0
|
|
141
|
+
| _ArgsSpec1
|
|
142
|
+
| _ArgsSpec2
|
|
143
|
+
| _ArgsSpec3
|
|
144
|
+
| _ArgsSpec4
|
|
145
|
+
| _ArgsSpec5
|
|
146
|
+
| _ArgsSpec6
|
|
147
|
+
| _ArgsSpec7
|
|
148
|
+
)
|
|
73
149
|
|
|
74
150
|
Scope = MutableMapping[str, Any]
|
|
75
151
|
Message = MutableMapping[str, Any]
|
|
@@ -85,11 +161,7 @@ PrimitiveToAnnotation = {
|
|
|
85
161
|
dict: Dict, # noqa: UP006
|
|
86
162
|
}
|
|
87
163
|
|
|
88
|
-
RESERVED_BACKEND_VAR_NAMES = {
|
|
89
|
-
"_abc_impl",
|
|
90
|
-
"_backend_vars",
|
|
91
|
-
"_was_touched",
|
|
92
|
-
}
|
|
164
|
+
RESERVED_BACKEND_VAR_NAMES = {"_abc_impl", "_backend_vars", "_was_touched", "_mixin"}
|
|
93
165
|
|
|
94
166
|
|
|
95
167
|
class Unset:
|
|
@@ -251,7 +323,11 @@ def is_optional(cls: GenericType) -> bool:
|
|
|
251
323
|
Returns:
|
|
252
324
|
Whether the class is an Optional.
|
|
253
325
|
"""
|
|
254
|
-
return
|
|
326
|
+
return (
|
|
327
|
+
cls is None
|
|
328
|
+
or cls is type(None)
|
|
329
|
+
or (is_union(cls) and type(None) in get_args(cls))
|
|
330
|
+
)
|
|
255
331
|
|
|
256
332
|
|
|
257
333
|
def is_classvar(a_type: Any) -> bool:
|
|
@@ -419,7 +495,7 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
|
|
|
419
495
|
return list[
|
|
420
496
|
get_attribute_access_type(
|
|
421
497
|
attr.target_class,
|
|
422
|
-
attr.remote_attr.key, #
|
|
498
|
+
attr.remote_attr.key, # pyright: ignore [reportAttributeAccessIssue]
|
|
423
499
|
)
|
|
424
500
|
]
|
|
425
501
|
elif isinstance(cls, type) and not is_generic_alias(cls) and issubclass(cls, Model):
|
|
@@ -917,47 +993,6 @@ def validate_literal(key: str, value: Any, expected_type: type, comp_name: str):
|
|
|
917
993
|
raise ValueError(msg)
|
|
918
994
|
|
|
919
995
|
|
|
920
|
-
def validate_parameter_literals(func: Callable):
|
|
921
|
-
"""Decorator to check that the arguments passed to a function
|
|
922
|
-
correspond to the correct function parameter if it (the parameter)
|
|
923
|
-
is a literal type.
|
|
924
|
-
|
|
925
|
-
Args:
|
|
926
|
-
func: The function to validate.
|
|
927
|
-
|
|
928
|
-
Returns:
|
|
929
|
-
The wrapper function.
|
|
930
|
-
"""
|
|
931
|
-
console.deprecate(
|
|
932
|
-
"validate_parameter_literals",
|
|
933
|
-
reason="Use manual validation instead.",
|
|
934
|
-
deprecation_version="0.7.11",
|
|
935
|
-
removal_version="0.8.0",
|
|
936
|
-
dedupe=True,
|
|
937
|
-
)
|
|
938
|
-
|
|
939
|
-
func_params = list(inspect.signature(func).parameters.items())
|
|
940
|
-
annotations = {param[0]: param[1].annotation for param in func_params}
|
|
941
|
-
|
|
942
|
-
@wraps(func)
|
|
943
|
-
def wrapper(*args, **kwargs):
|
|
944
|
-
# validate args
|
|
945
|
-
for param, arg in zip(annotations, args, strict=False):
|
|
946
|
-
if annotations[param] is inspect.Parameter.empty:
|
|
947
|
-
continue
|
|
948
|
-
validate_literal(param, arg, annotations[param], func.__name__)
|
|
949
|
-
|
|
950
|
-
# validate kwargs.
|
|
951
|
-
for key, value in kwargs.items():
|
|
952
|
-
annotation = annotations.get(key)
|
|
953
|
-
if not annotation or annotation is inspect.Parameter.empty:
|
|
954
|
-
continue
|
|
955
|
-
validate_literal(key, value, annotation, func.__name__)
|
|
956
|
-
return func(*args, **kwargs)
|
|
957
|
-
|
|
958
|
-
return wrapper
|
|
959
|
-
|
|
960
|
-
|
|
961
996
|
# Store this here for performance.
|
|
962
997
|
StateBases = get_base_class(StateVar)
|
|
963
998
|
StateIterBases = get_base_class(StateIterVar)
|
|
@@ -1118,3 +1153,103 @@ def typehint_issubclass(
|
|
|
1118
1153
|
)
|
|
1119
1154
|
if accepted_arg is not Any
|
|
1120
1155
|
)
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
def resolve_annotations(
|
|
1159
|
+
raw_annotations: Mapping[str, type[Any]], module_name: str | None
|
|
1160
|
+
) -> dict[str, type[Any]]:
|
|
1161
|
+
"""Partially taken from typing.get_type_hints.
|
|
1162
|
+
|
|
1163
|
+
Resolve string or ForwardRef annotations into type objects if possible.
|
|
1164
|
+
|
|
1165
|
+
Args:
|
|
1166
|
+
raw_annotations: The raw annotations to resolve.
|
|
1167
|
+
module_name: The name of the module.
|
|
1168
|
+
|
|
1169
|
+
Returns:
|
|
1170
|
+
The resolved annotations.
|
|
1171
|
+
"""
|
|
1172
|
+
module = sys.modules.get(module_name, None) if module_name is not None else None
|
|
1173
|
+
|
|
1174
|
+
base_globals: dict[str, Any] | None = (
|
|
1175
|
+
module.__dict__ if module is not None else None
|
|
1176
|
+
)
|
|
1177
|
+
|
|
1178
|
+
annotations = {}
|
|
1179
|
+
for name, value in raw_annotations.items():
|
|
1180
|
+
if isinstance(value, str):
|
|
1181
|
+
if sys.version_info == (3, 10, 0):
|
|
1182
|
+
value = ForwardRef(value, is_argument=False)
|
|
1183
|
+
else:
|
|
1184
|
+
value = ForwardRef(value, is_argument=False, is_class=True)
|
|
1185
|
+
try:
|
|
1186
|
+
if sys.version_info >= (3, 13):
|
|
1187
|
+
value = _eval_type(value, base_globals, None, type_params=())
|
|
1188
|
+
else:
|
|
1189
|
+
value = _eval_type(value, base_globals, None)
|
|
1190
|
+
except NameError:
|
|
1191
|
+
# this is ok, it can be fixed with update_forward_refs
|
|
1192
|
+
pass
|
|
1193
|
+
annotations[name] = value
|
|
1194
|
+
return annotations
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
TYPES_THAT_HAS_DEFAULT_VALUE = (int, float, tuple, list, set, dict, str)
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
def get_default_value_for_type(t: GenericType) -> Any:
|
|
1201
|
+
"""Get the default value of the var.
|
|
1202
|
+
|
|
1203
|
+
Args:
|
|
1204
|
+
t: The type of the var.
|
|
1205
|
+
|
|
1206
|
+
Returns:
|
|
1207
|
+
The default value of the var, if it has one, else None.
|
|
1208
|
+
|
|
1209
|
+
Raises:
|
|
1210
|
+
ImportError: If the var is a dataframe and pandas is not installed.
|
|
1211
|
+
"""
|
|
1212
|
+
if is_optional(t):
|
|
1213
|
+
return None
|
|
1214
|
+
|
|
1215
|
+
origin = get_origin(t) if is_generic_alias(t) else t
|
|
1216
|
+
if origin is Literal:
|
|
1217
|
+
args = get_args(t)
|
|
1218
|
+
return args[0] if args else None
|
|
1219
|
+
if safe_issubclass(origin, TYPES_THAT_HAS_DEFAULT_VALUE):
|
|
1220
|
+
return origin()
|
|
1221
|
+
if safe_issubclass(origin, Mapping):
|
|
1222
|
+
return {}
|
|
1223
|
+
if is_dataframe(origin):
|
|
1224
|
+
try:
|
|
1225
|
+
import pandas as pd
|
|
1226
|
+
|
|
1227
|
+
return pd.DataFrame()
|
|
1228
|
+
except ImportError as e:
|
|
1229
|
+
msg = "Please install pandas to use dataframes in your app."
|
|
1230
|
+
raise ImportError(msg) from e
|
|
1231
|
+
return None
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
IMMUTABLE_TYPES = (
|
|
1235
|
+
int,
|
|
1236
|
+
float,
|
|
1237
|
+
bool,
|
|
1238
|
+
str,
|
|
1239
|
+
bytes,
|
|
1240
|
+
frozenset,
|
|
1241
|
+
tuple,
|
|
1242
|
+
type(None),
|
|
1243
|
+
)
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
def is_immutable(i: Any) -> bool:
|
|
1247
|
+
"""Check if a value is immutable.
|
|
1248
|
+
|
|
1249
|
+
Args:
|
|
1250
|
+
i: The value to check.
|
|
1251
|
+
|
|
1252
|
+
Returns:
|
|
1253
|
+
Whether the value is immutable.
|
|
1254
|
+
"""
|
|
1255
|
+
return isinstance(i, IMMUTABLE_TYPES)
|
reflex/vars/__init__.py
CHANGED