Skip to content
Merged

0827dev #6091

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "reflex"
version = "0.8.26dev1"
version = "0.8.27dev1"
description = "Web apps in pure Python."
license.text = "Apache-2.0"
authors = [
Expand Down Expand Up @@ -156,6 +156,7 @@ lint.ignore = [
"PT012",
"PYI",
"RUF012",
"RUF067",
"S",
"SLF",
"SLOT",
Expand Down Expand Up @@ -243,7 +244,7 @@ fail_fast = true

[[tool.pre-commit.repos]]
repo = "https://github.com/astral-sh/ruff-pre-commit"
rev = "v0.14.9"
rev = "v0.14.13"
hooks = [
{ id = "ruff-format", args = [
"reflex",
Expand Down Expand Up @@ -275,7 +276,7 @@ hooks = [

[[tool.pre-commit.repos]]
repo = "https://github.com/RobertCraigie/pyright-python"
rev = "v1.1.407"
rev = "v1.1.408"
hooks = [{ id = "pyright", args = ["reflex", "tests"], language = "system" }]

[[tool.pre-commit.repos]]
Expand Down
9 changes: 6 additions & 3 deletions reflex/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2109,8 +2109,10 @@ def on_disconnect(self, sid: str) -> asyncio.Task | None:
)
# Don't await to avoid blocking disconnect, but handle potential errors
task.add_done_callback(
lambda t: t.exception()
and console.error(f"Token cleanup error: {t.exception()}")
lambda t: (
t.exception()
and console.error(f"Token cleanup error: {t.exception()}")
)
)
return task
return None
Expand Down Expand Up @@ -2218,7 +2220,8 @@ async def on_event(self, sid: str, data: Any):

# Unroll reverse proxy forwarded headers.
client_ip = (
headers.get(
headers
.get(
"x-forwarded-for",
client_ip,
)
Expand Down
3 changes: 2 additions & 1 deletion reflex/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ def _validate_stylesheet(stylesheet_full_path: Path, assets_app_path: Path) -> N
raise ValueError(msg)
if (
len(
stylesheet_full_path.absolute()
stylesheet_full_path
.absolute()
.relative_to(assets_app_path.absolute())
.parts
)
Expand Down
2 changes: 1 addition & 1 deletion reflex/components/base/error_boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def on_error_spec(
class ErrorBoundary(Component):
"""A React Error Boundary component that catches unhandled frontend exceptions."""

library = "react-error-boundary@6.0.3"
library = "react-error-boundary@6.1.0"
tag = "ErrorBoundary"

# Fired when the boundary catches an error.
Expand Down
4 changes: 2 additions & 2 deletions reflex/components/core/debounce.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ def create(cls, *children: Component, **props: Any) -> Component:
component.children = child.children
component._rename_props = child._rename_props # pyright: ignore[reportAttributeAccessIssue]
outer_get_all_custom_code = component._get_all_custom_code
component._get_all_custom_code = lambda: outer_get_all_custom_code() | (
child._get_all_custom_code()
component._get_all_custom_code = lambda: (
outer_get_all_custom_code() | (child._get_all_custom_code())
)
return component

Expand Down
3 changes: 2 additions & 1 deletion reflex/components/core/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ def _format_rejected_file_record(rf: ObjectVar[dict[str, Any]]) -> str:

return toast.error(
title="Files not Accepted",
description=rejected_files.to(ArrayVar)
description=rejected_files
.to(ArrayVar)
.foreach(_format_rejected_file_record)
.join("\n\n"),
close_button=True,
Expand Down
3 changes: 2 additions & 1 deletion reflex/components/datadisplay/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,8 @@ def _render(self):
theme = self.theme

return (
out.add_props(style=theme)
out
.add_props(style=theme)
.remove_props("theme", "code")
.add_props(
children=self.code,
Expand Down
6 changes: 4 additions & 2 deletions reflex/components/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ def make_component(component: Component) -> str:
if line.startswith("import "):
if 'from "$/' in line or 'from "/' in line:
module_code_lines[ix] = (
line.replace("import ", "const ", 1)
line
.replace("import ", "const ", 1)
.replace(" as ", ": ")
.replace(" from ", " = window['__reflex'][", 1)
+ "]"
Expand All @@ -128,7 +129,8 @@ def make_component(component: Component) -> str:
for lib in libs_in_window:
if f'from "{lib}"' in line:
module_code_lines[ix] = (
line.replace("import ", "const ", 1)
line
.replace("import ", "const ", 1)
.replace(
f' from "{lib}"', f" = window.__reflex['{lib}']", 1
)
Expand Down
3 changes: 2 additions & 1 deletion reflex/components/sonner/toast.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ def send_toast(
toast_ref.bool(),
toast,
FunctionVar("window.alert").call(
Var.create(
Var
.create(
message
if isinstance(message, str) and message
else props.get("title", props.get("description", ""))
Expand Down
4 changes: 2 additions & 2 deletions reflex/constants/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Bun(SimpleNamespace):
"""Bun constants."""

# The Bun version.
VERSION = "1.3.5"
VERSION = "1.3.6"

# Min Bun Version
MIN_VERSION = "1.3.0"
Expand Down Expand Up @@ -131,7 +131,7 @@ def DEPENDENCIES(cls) -> dict[str, str]:
"react": cls._react_version,
"react-helmet": "6.1.0",
"react-dom": cls._react_version,
"isbot": "5.1.32",
"isbot": "5.1.33",
"socket.io-client": "4.8.3",
"universal-cookie": "7.2.2",
}
Expand Down
3 changes: 2 additions & 1 deletion reflex/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,8 @@ def scroll_to(elem_id: str, align_to_top: bool | Var[bool] = True) -> EventSpec:
get_element_by_id = FunctionStringVar.create("document.getElementById")

return run_script(
get_element_by_id.call(elem_id)
get_element_by_id
.call(elem_id)
.to(ObjectVar)
.scrollIntoView.to(FunctionVar)
.call(align_to_top),
Expand Down
30 changes: 13 additions & 17 deletions reflex/reflex.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,23 +801,19 @@ def deploy(
app_name=app_name,
app_id=app_id,
export_fn=(
lambda zip_dest_dir,
api_url,
deploy_url,
frontend,
backend,
upload_db,
zipping: export_utils.export(
zip_dest_dir=zip_dest_dir,
api_url=api_url,
deploy_url=deploy_url,
frontend=frontend,
backend=backend,
zipping=zipping,
loglevel=config.loglevel.subprocess_level(),
upload_db_file=upload_db,
backend_excluded_dirs=backend_excluded_dirs,
prerender_routes=ssr,
lambda zip_dest_dir, api_url, deploy_url, frontend, backend, upload_db, zipping: (
export_utils.export(
zip_dest_dir=zip_dest_dir,
api_url=api_url,
deploy_url=deploy_url,
frontend=frontend,
backend=backend,
zipping=zipping,
loglevel=config.loglevel.subprocess_level(),
upload_db_file=upload_db,
backend_excluded_dirs=backend_excluded_dirs,
prerender_routes=ssr,
)
)
),
regions=list(region),
Expand Down
3 changes: 2 additions & 1 deletion reflex/utils/pyi_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,8 @@ def figure_out_return_type(annotation: Any):

if isinstance(annotation, str) and annotation.lower().startswith("tuple["):
inside_of_tuple = (
annotation.removeprefix("tuple[")
annotation
.removeprefix("tuple[")
.removeprefix("Tuple[")
.removesuffix("]")
)
Expand Down
8 changes: 5 additions & 3 deletions tests/integration/test_deploy_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ def test_deploy_url_in_app(deploy_url_sample: AppHarness, driver: WebDriver) ->
driver.find_element(By.ID, "goto_self").click()

WebDriverWait(driver, 10).until(
lambda driver: deploy_url_sample.frontend_url
and driver.current_url.removesuffix("/")
== deploy_url_sample.frontend_url.removesuffix("/")
lambda driver: (
deploy_url_sample.frontend_url
and driver.current_url.removesuffix("/")
== deploy_url_sample.frontend_url.removesuffix("/")
)
)
8 changes: 5 additions & 3 deletions tests/integration/test_event_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,11 @@ def index():
rx.button(
"Throttle",
id="btn-throttle",
on_click=lambda: EventActionState.on_click_throttle.throttle( # pyright: ignore [reportFunctionMemberAccess]
200
).stop_propagation,
on_click=lambda: (
EventActionState.on_click_throttle.throttle( # pyright: ignore [reportFunctionMemberAccess]
200
).stop_propagation
),
),
rx.button(
"Debounce",
Expand Down
10 changes: 6 additions & 4 deletions tests/integration/test_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,9 @@ async def get_state_text():
# type more characters
debounce_input.send_keys("getting testing done")
AppHarness.expect(
lambda: fully_controlled_input.poll_for_value(value_input)
== "getting testing done"
lambda: (
fully_controlled_input.poll_for_value(value_input) == "getting testing done"
)
)
assert debounce_input.get_attribute("value") == "getting testing done"
assert await get_state_text() == "getting testing done"
Expand All @@ -174,8 +175,9 @@ async def get_state_text():
# type into the on_change input
on_change_input.send_keys("overwrite the state")
AppHarness.expect(
lambda: fully_controlled_input.poll_for_value(value_input)
== "overwrite the state"
lambda: (
fully_controlled_input.poll_for_value(value_input) == "overwrite the state"
)
)
assert debounce_input.get_attribute("value") == "overwrite the state"
assert on_change_input.get_attribute("value") == "overwrite the state"
Expand Down
44 changes: 25 additions & 19 deletions tests/units/compiler/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,15 @@ def test_compile_stylesheets(tmp_path: Path, mocker: MockerFixture):
/ "styles"
/ (PageNames.STYLESHEET_ROOT + ".css")
),
"@layer __reflex_base;\n"
"@import url('./__reflex_style_reset.css');\n"
"@import url('@radix-ui/themes/styles.css');\n"
"@import url('https://fonts.googleapis.com/css?family=Sofia&effect=neon|outline|emboss|shadow-multiple');\n"
"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css');\n"
"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css');\n"
"@import url('./style.css');",
(
"@layer __reflex_base;\n"
"@import url('./__reflex_style_reset.css');\n"
"@import url('@radix-ui/themes/styles.css');\n"
"@import url('https://fonts.googleapis.com/css?family=Sofia&effect=neon|outline|emboss|shadow-multiple');\n"
"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css');\n"
"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css');\n"
"@import url('./style.css');"
),
)

assert (project / constants.Dirs.WEB / "styles" / "style.css").read_text() == (
Expand Down Expand Up @@ -221,12 +223,14 @@ def test_compile_stylesheets_scss_sass(tmp_path: Path, mocker: MockerFixture):
/ "styles"
/ (PageNames.STYLESHEET_ROOT + ".css")
),
"@layer __reflex_base;\n"
"@import url('./__reflex_style_reset.css');\n"
"@import url('@radix-ui/themes/styles.css');\n"
"@import url('./style.css');\n"
f"@import url('./{Path('preprocess') / Path('styles_a.css')!s}');\n"
f"@import url('./{Path('preprocess') / Path('styles_b.css')!s}');",
(
"@layer __reflex_base;\n"
"@import url('./__reflex_style_reset.css');\n"
"@import url('@radix-ui/themes/styles.css');\n"
"@import url('./style.css');\n"
f"@import url('./{Path('preprocess') / Path('styles_a.css')!s}');\n"
f"@import url('./{Path('preprocess') / Path('styles_b.css')!s}');"
),
)

stylesheets = [
Expand All @@ -241,12 +245,14 @@ def test_compile_stylesheets_scss_sass(tmp_path: Path, mocker: MockerFixture):
/ "styles"
/ (PageNames.STYLESHEET_ROOT + ".css")
),
"@layer __reflex_base;\n"
"@import url('./__reflex_style_reset.css');\n"
"@import url('@radix-ui/themes/styles.css');\n"
"@import url('./style.css');\n"
f"@import url('./{Path('preprocess') / Path('styles_a.css')!s}');\n"
f"@import url('./{Path('preprocess') / Path('styles_b.css')!s}');",
(
"@layer __reflex_base;\n"
"@import url('./__reflex_style_reset.css');\n"
"@import url('@radix-ui/themes/styles.css');\n"
"@import url('./style.css');\n"
f"@import url('./{Path('preprocess') / Path('styles_a.css')!s}');\n"
f"@import url('./{Path('preprocess') / Path('styles_b.css')!s}');"
),
)

assert (project / constants.Dirs.WEB / "styles" / "style.css").read_text() == (
Expand Down
18 changes: 11 additions & 7 deletions tests/units/components/core/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ def test_color(color, expected, expected_type: type[str] | type[Color]):
("second", rx.color("tomato", 5)),
rx.color(ColorState.color, 2),
),
'(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): return ("var(--mint-7)");'
' break;case JSON.stringify("second"): return ("var(--tomato-5)"); break;default: '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-2)")); break;}};}})()',
(
'(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): return ("var(--mint-7)");'
' break;case JSON.stringify("second"): return ("var(--tomato-5)"); break;default: '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-2)")); break;}};}})()'
),
),
(
rx.match(
Expand All @@ -108,10 +110,12 @@ def test_color(color, expected, expected_type: type[str] | type[Color]):
("second", rx.color(ColorState.color, 5)),
rx.color(ColorState.color, 2),
),
'(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-7)")); break;case JSON.stringify("second"): '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-5)")); break;default: '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-2)")); break;}};}})()',
(
'(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-7)")); break;case JSON.stringify("second"): '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-5)")); break;default: '
f'return (("var(--"+{color_state_name!s}.color{FIELD_MARKER}+"-2)")); break;}};}})()'
),
),
],
)
Expand Down
Loading
Loading