Skip to content

Commit ca84bca

Browse files
committed
Merge branch 'main' into move-pydantic,-sqlmodel,-alembic-to-optional-dependencies
2 parents c6b0e71 + 7e0a95f commit ca84bca

48 files changed

Lines changed: 1358 additions & 739 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,5 @@ For some pull requests when adding new components you will have to generate a py
108108
(Please check in with the team before adding a new component to Reflex we are cautious about adding new components to Reflex's core.)
109109

110110
```bash
111-
uv run python scripts/make_pyi.py
111+
uv run python -m reflex.utils.pyi_generator
112112
```

pyi_hashes.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"reflex/components/base/meta.pyi": "0445c66fbc32671c795640ef1a4827e9",
1212
"reflex/components/base/script.pyi": "43a0e21f257b10d2c76ed359284a9d80",
1313
"reflex/components/base/strict_mode.pyi": "d169c575d676c73edc6a3f593badfd1f",
14-
"reflex/components/core/__init__.pyi": "6419485660830fe0af9c9c5715a4ed03",
14+
"reflex/components/core/__init__.pyi": "007170b97e58bdf28b2aee381d91c0c7",
1515
"reflex/components/core/auto_scroll.pyi": "c628ed503c7bfcee0dd05cf48d5b763d",
1616
"reflex/components/core/banner.pyi": "407352aa1833b80b21d30647ec7717d8",
1717
"reflex/components/core/client_side_routing.pyi": "c3d38a1de89cfcd76735a1559e99ed05",
@@ -21,13 +21,14 @@
2121
"reflex/components/core/html.pyi": "faf9bb353ef4784e7f17ac97c93ef697",
2222
"reflex/components/core/sticky.pyi": "cdf17e6cd287e7300acd25669701d117",
2323
"reflex/components/core/upload.pyi": "f9be9b74d97d841b53b963d8704d5809",
24+
"reflex/components/core/window_events.pyi": "04be3d73886d12774498004b712c136e",
2425
"reflex/components/datadisplay/__init__.pyi": "52755871369acbfd3a96b46b9a11d32e",
2526
"reflex/components/datadisplay/code.pyi": "3787ca724cae7b29d57ea03f981b8c22",
2627
"reflex/components/datadisplay/dataeditor.pyi": "20eb36b4b8b6e77a73c584ac1d7c272f",
2728
"reflex/components/datadisplay/shiki_code_block.pyi": "0bf1ed97bcc4159df150d56d92d78945",
28-
"reflex/components/el/__init__.pyi": "8943a76f52fb5ed6a1c04b7cd31976f9",
29+
"reflex/components/el/__init__.pyi": "00ded672c0336da6225036f56855b042",
2930
"reflex/components/el/element.pyi": "7faa2cda13a04870d6c1cbfb4b3a2a0a",
30-
"reflex/components/el/elements/__init__.pyi": "5042206599bd3483a6b7a8f922f7c1f2",
31+
"reflex/components/el/elements/__init__.pyi": "2e30624329b8b535dfd8969f95efdd25",
3132
"reflex/components/el/elements/base.pyi": "3fde62b5c749a40c43d1a4f0d0dccda4",
3233
"reflex/components/el/elements/forms.pyi": "b7db5e64a2d0ee1a7ecf72cac927587a",
3334
"reflex/components/el/elements/inline.pyi": "027f051369a253446365e77a4d621013",
@@ -37,9 +38,9 @@
3738
"reflex/components/el/elements/scripts.pyi": "d38ffd5cc01d62979f9788b9c478f82d",
3839
"reflex/components/el/elements/sectioning.pyi": "11deb805947a6b7ec88c409c362273c5",
3940
"reflex/components/el/elements/tables.pyi": "e5573a4a8c9cb13d8169a596b6699b31",
40-
"reflex/components/el/elements/typography.pyi": "dc4e234a7a58be0a9c2c6036a52f9b59",
41+
"reflex/components/el/elements/typography.pyi": "9f9f6990749f4a3c643f8ab344df00cd",
4142
"reflex/components/gridjs/datatable.pyi": "5c19d2b5788a8520d43a4d6dcc247705",
42-
"reflex/components/lucide/icon.pyi": "e48c9fa2fe6308d366634b6a5157bf3a",
43+
"reflex/components/lucide/icon.pyi": "637bf77970ef805ac4bdc1eba77ece76",
4344
"reflex/components/markdown/markdown.pyi": "a569dd6a60d67baebfc4d04cddf85020",
4445
"reflex/components/moment/moment.pyi": "4ca29ae9cae720eb5c4955682e4cb7df",
4546
"reflex/components/plotly/plotly.pyi": "1de86aa6881e59d4053206e62e3039c3",
@@ -80,7 +81,7 @@
8081
"reflex/components/radix/themes/components/scroll_area.pyi": "7cbfa553778dce45256e9530b0be883b",
8182
"reflex/components/radix/themes/components/segmented_control.pyi": "c23a595bfc16aaf4d479dfaaa92a3273",
8283
"reflex/components/radix/themes/components/select.pyi": "3703abe61e53cd619e0ea18da5003c44",
83-
"reflex/components/radix/themes/components/separator.pyi": "e93e99178867d5846932161a6e8bf760",
84+
"reflex/components/radix/themes/components/separator.pyi": "7a08430b5986fd098459a56d00a84fc8",
8485
"reflex/components/radix/themes/components/skeleton.pyi": "f3f84004eb63983947393df976428ee3",
8586
"reflex/components/radix/themes/components/slider.pyi": "e31b84a6bdd286f25a5fa8f4bde95738",
8687
"reflex/components/radix/themes/components/spinner.pyi": "da0d693bf1b4e72d027a1c871850710e",

pyproject.toml

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "reflex"
3-
version = "0.8.2dev1"
3+
version = "0.8.4dev1"
44
description = "Web apps in pure Python."
55
license.text = "Apache-2.0"
66
authors = [
@@ -64,18 +64,49 @@ documentation = "https://reflex.dev/docs/getting-started/introduction"
6464
[project.scripts]
6565
reflex = "reflex.reflex:cli"
6666

67+
[dependency-groups]
68+
dev = [
69+
"asynctest",
70+
"darglint",
71+
"dill",
72+
"fastapi",
73+
"hatchling",
74+
"libsass",
75+
"numpy",
76+
"pandas",
77+
"pillow",
78+
"playwright",
79+
"plotly",
80+
"pre-commit",
81+
"psutil",
82+
"psycopg[binary]",
83+
"pyright",
84+
"pytest-asyncio",
85+
"pytest-benchmark",
86+
"pytest-codspeed",
87+
"pytest-cov",
88+
"pytest-mock",
89+
"pytest-playwright",
90+
"pytest-retry",
91+
"pytest-split",
92+
"pytest",
93+
"python-dotenv",
94+
"ruff",
95+
"selenium",
96+
"starlette-admin",
97+
"toml",
98+
"uvicorn",
99+
]
100+
101+
67102
[build-system]
68103
requires = ["hatchling"]
69104
build-backend = "hatchling.build"
70105

71106
[tool.hatch.build]
72107
include = ["reflex", "scripts/hatch_build.py"]
73-
74-
[tool.hatch.build.targets.sdist]
75-
artifacts = ["*.pyi"]
76-
77-
[tool.hatch.build.targets.wheel]
78-
artifacts = ["*.pyi"]
108+
targets.sdist.artifacts = ["*.pyi"]
109+
targets.wheel.artifacts = ["*.pyi"]
79110

80111
[tool.hatch.build.hooks.custom]
81112
path = "scripts/hatch_build.py"
@@ -158,43 +189,6 @@ asyncio_mode = "auto"
158189
skip = "docs/*,*.html,examples/*, *.pyi, poetry.lock, uv.lock"
159190
ignore-words-list = "te, TreeE"
160191

161-
[dependency-groups]
162-
dev = [
163-
"alembic >=1.15.2,<2.0",
164-
"asynctest >=0.13",
165-
"darglint >=1.8",
166-
"dill >=0.3",
167-
"fastapi >=0.115.0",
168-
"hatchling >=1.27",
169-
"libsass >=0.23",
170-
"numpy >=2.2",
171-
"pandas >=2.2",
172-
"pillow >=11",
173-
"playwright >=1.51",
174-
"plotly >=6.0",
175-
"pre-commit ==4.2.0",
176-
"psutil >=7.0.0",
177-
"psycopg[binary] >=3.2",
178-
"pydantic >=1.10.21,<3.0",
179-
"pyright >=1.1.400",
180-
"pytest >=8.3",
181-
"pytest-asyncio >=0.26",
182-
"pytest-benchmark >=5.1",
183-
"pytest-codspeed >=3.2",
184-
"pytest-cov >=6.1",
185-
"pytest-mock >=3.14",
186-
"pytest-playwright >=0.7",
187-
"pytest-retry >=1.7",
188-
"pytest-split >=0.10",
189-
"python-dotenv >=1",
190-
"ruff >=0.11",
191-
"selenium >=4.31",
192-
"sqlmodel >=0.0.24,<0.1",
193-
"starlette-admin >=0.14",
194-
"toml >=0.10.2",
195-
"uvicorn >=0.34.0",
196-
]
197-
198192

199193
[tool.coverage.run]
200194
source = ["reflex"]
@@ -239,7 +233,7 @@ fail_fast = true
239233

240234
[[tool.pre-commit.repos]]
241235
repo = "https://github.com/astral-sh/ruff-pre-commit"
242-
rev = "v0.12.2"
236+
rev = "v0.12.3"
243237
hooks = [
244238
{ id = "ruff-format", args = [
245239
"reflex",
@@ -271,7 +265,7 @@ hooks = [
271265

272266
[[tool.pre-commit.repos]]
273267
repo = "https://github.com/RobertCraigie/pyright-python"
274-
rev = "v1.1.402"
268+
rev = "v1.1.403"
275269
hooks = [{ id = "pyright", args = ["reflex", "tests"], language = "system" }]
276270

277271
[[tool.pre-commit.repos]]
@@ -283,3 +277,6 @@ hooks = [{ id = "darglint", exclude = "^reflex/reflex.py" }]
283277
repo = "https://github.com/pre-commit/mirrors-prettier"
284278
rev = "f62a70a3a7114896b062de517d72829ea1c884b6"
285279
hooks = [{ id = "prettier", require_serial = true }]
280+
281+
[tool.uv]
282+
required-version = ">=0.7.0"

reflex/.templates/web/utils/state.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ export const useEventLoop = (
993993
window.onerror = function (msg, url, lineNo, columnNo, error) {
994994
addEvents([
995995
Event(`${exception_state_name}.handle_frontend_exception`, {
996-
stack: error.stack,
996+
info: error.name + ": " + error.message + "\n" + error.stack,
997997
component_stack: "",
998998
}),
999999
]);
@@ -1005,7 +1005,12 @@ export const useEventLoop = (
10051005
window.onunhandledrejection = function (event) {
10061006
addEvents([
10071007
Event(`${exception_state_name}.handle_frontend_exception`, {
1008-
stack: event.reason?.stack,
1008+
info:
1009+
event.reason?.name +
1010+
": " +
1011+
event.reason?.message +
1012+
"\n" +
1013+
event.reason?.stack,
10091014
component_stack: "",
10101015
}),
10111016
]);

reflex/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@
240240
"upload",
241241
],
242242
"components.core.auto_scroll": ["auto_scroll"],
243+
"components.core.window_events": ["window_event_listener"],
243244
}
244245

245246
COMPONENTS_BASE_MAPPING: dict = {

reflex/app.py

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,9 @@ class App(MiddlewareMixin, LifespanMixin):
398398
# The state class to use for the app.
399399
_state: type[BaseState] | None = None
400400

401+
# Whether to enable state for the app. If False, the app will not use state.
402+
enable_state: bool = True
403+
401404
# Class to manage many client states.
402405
_state_manager: StateManager | None = None
403406

@@ -475,7 +478,8 @@ def __post_init__(self):
475478
if issubclass(clz, AppMixin):
476479
clz._init_mixin(self)
477480

478-
self._setup_state()
481+
if self.enable_state:
482+
self._enable_state()
479483

480484
# Set up the admin dash.
481485
self._setup_admin_dash()
@@ -490,7 +494,7 @@ def _enable_state(self) -> None:
490494
"""Enable state for the app."""
491495
if not self._state:
492496
self._state = State
493-
self._setup_state()
497+
self._setup_state()
494498

495499
def _setup_state(self) -> None:
496500
"""Set up the state for the app.
@@ -589,21 +593,16 @@ def __call__(self) -> ASGIApp:
589593
Returns:
590594
The backend api.
591595
"""
596+
from reflex.vars.base import GLOBAL_CACHE
597+
592598
# For py3.9 compatibility when redis is used, we MUST add any decorator pages
593599
# before compiling the app in a thread to avoid event loop error (REF-2172).
594600
self._apply_decorated_pages()
595601

596-
compile_future = concurrent.futures.ThreadPoolExecutor(max_workers=1).submit(
597-
self._compile, prerender_routes=is_prod_mode()
598-
)
599-
600-
def callback(f: concurrent.futures.Future):
601-
# Force background compile errors to print eagerly
602-
return f.result()
602+
self._compile(prerender_routes=is_prod_mode())
603603

604-
compile_future.add_done_callback(callback)
605-
# Wait for the compile to finish to ensure all optional endpoints are mounted.
606-
compile_future.result()
604+
# We will not be making more vars, so we can clear the global cache to free up memory.
605+
GLOBAL_CACHE.clear()
607606

608607
if not self._api:
609608
msg = "The app has not been initialized."
@@ -837,14 +836,10 @@ def _compile_page(self, route: str, save_page: bool = True):
837836
save_page: If True, the compiled page is saved to self._pages.
838837
"""
839838
n_states_before = len(all_base_state_classes)
840-
component, enable_state = compiler.compile_unevaluated_page(
841-
route, self._unevaluated_pages[route], self._state, self.style, self.theme
839+
component = compiler.compile_unevaluated_page(
840+
route, self._unevaluated_pages[route], self.style, self.theme
842841
)
843842

844-
# Indicate that the app should use state.
845-
if enable_state:
846-
self._enable_state()
847-
848843
# Indicate that evaluating this page creates one or more state classes.
849844
if len(all_base_state_classes) > n_states_before:
850845
self._stateful_pages[route] = None
@@ -1138,7 +1133,6 @@ def get_compilation_time() -> str:
11381133
for route in stateful_pages:
11391134
console.debug(f"BE Evaluating stateful page: {route}")
11401135
self._compile_page(route, save_page=False)
1141-
self._enable_state()
11421136
self._add_optional_endpoints()
11431137
return
11441138

@@ -1337,8 +1331,6 @@ def memoized_toast_provider():
13371331
for route, component in zip(self._pages, page_components, strict=True):
13381332
ExecutorSafeFunctions.COMPONENTS[route] = component
13391333

1340-
ExecutorSafeFunctions.STATE = self._state
1341-
13421334
modify_files_tasks: list[tuple[str, str, Callable[[str], str]]] = []
13431335

13441336
with console.timing("Compile to Javascript"), executor as executor:

0 commit comments

Comments
 (0)