Merge remote-tracking branch 'origin/main' into masenf/async-computed-var
This commit is contained in:
commit
213307c413
@ -28,7 +28,7 @@ repos:
|
|||||||
entry: python3 scripts/make_pyi.py
|
entry: python3 scripts/make_pyi.py
|
||||||
|
|
||||||
- repo: https://github.com/RobertCraigie/pyright-python
|
- repo: https://github.com/RobertCraigie/pyright-python
|
||||||
rev: v1.1.334
|
rev: v1.1.392
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyright
|
- id: pyright
|
||||||
args: [reflex, tests]
|
args: [reflex, tests]
|
||||||
|
@ -34,13 +34,13 @@ def render_component(num: int):
|
|||||||
rx.box(
|
rx.box(
|
||||||
rx.accordion.root(
|
rx.accordion.root(
|
||||||
rx.accordion.item(
|
rx.accordion.item(
|
||||||
header="Full Ingredients", # type: ignore
|
header="Full Ingredients",
|
||||||
content="Yes. It's built with accessibility in mind.", # type: ignore
|
content="Yes. It's built with accessibility in mind.",
|
||||||
font_size="3em",
|
font_size="3em",
|
||||||
),
|
),
|
||||||
rx.accordion.item(
|
rx.accordion.item(
|
||||||
header="Applications", # type: ignore
|
header="Applications",
|
||||||
content="Yes. It's unstyled by default, giving you freedom over the look and feel.", # type: ignore
|
content="Yes. It's unstyled by default, giving you freedom over the look and feel.",
|
||||||
),
|
),
|
||||||
collapsible=True,
|
collapsible=True,
|
||||||
variant="ghost",
|
variant="ghost",
|
||||||
@ -166,9 +166,9 @@ def app_with_10_components(
|
|||||||
root=root,
|
root=root,
|
||||||
app_source=functools.partial(
|
app_source=functools.partial(
|
||||||
AppWithTenComponentsOnePage,
|
AppWithTenComponentsOnePage,
|
||||||
render_component=render_component, # type: ignore
|
render_component=render_component, # pyright: ignore [reportCallIssue]
|
||||||
),
|
),
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
@ -189,9 +189,9 @@ def app_with_100_components(
|
|||||||
root=root,
|
root=root,
|
||||||
app_source=functools.partial(
|
app_source=functools.partial(
|
||||||
AppWithHundredComponentOnePage,
|
AppWithHundredComponentOnePage,
|
||||||
render_component=render_component, # type: ignore
|
render_component=render_component, # pyright: ignore [reportCallIssue]
|
||||||
),
|
),
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
@ -212,9 +212,9 @@ def app_with_1000_components(
|
|||||||
root=root,
|
root=root,
|
||||||
app_source=functools.partial(
|
app_source=functools.partial(
|
||||||
AppWithThousandComponentsOnePage,
|
AppWithThousandComponentsOnePage,
|
||||||
render_component=render_component, # type: ignore
|
render_component=render_component, # pyright: ignore [reportCallIssue]
|
||||||
),
|
),
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
||||||
|
@ -28,7 +28,7 @@ def render_multiple_pages(app, num: int):
|
|||||||
"""
|
"""
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
from rxconfig import config # type: ignore
|
from rxconfig import config # pyright: ignore [reportMissingImports]
|
||||||
|
|
||||||
import reflex as rx
|
import reflex as rx
|
||||||
|
|
||||||
@ -74,13 +74,13 @@ def render_multiple_pages(app, num: int):
|
|||||||
rx.select(
|
rx.select(
|
||||||
["C", "PF", "SF", "PG", "SG"],
|
["C", "PF", "SF", "PG", "SG"],
|
||||||
placeholder="Select a position. (All)",
|
placeholder="Select a position. (All)",
|
||||||
on_change=State.set_position, # type: ignore
|
on_change=State.set_position, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
size="3",
|
size="3",
|
||||||
),
|
),
|
||||||
rx.select(
|
rx.select(
|
||||||
college,
|
college,
|
||||||
placeholder="Select a college. (All)",
|
placeholder="Select a college. (All)",
|
||||||
on_change=State.set_college, # type: ignore
|
on_change=State.set_college, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
size="3",
|
size="3",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -95,7 +95,7 @@ def render_multiple_pages(app, num: int):
|
|||||||
default_value=[18, 50],
|
default_value=[18, 50],
|
||||||
min=18,
|
min=18,
|
||||||
max=50,
|
max=50,
|
||||||
on_value_commit=State.set_age, # type: ignore
|
on_value_commit=State.set_age, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
),
|
),
|
||||||
align_items="left",
|
align_items="left",
|
||||||
width="100%",
|
width="100%",
|
||||||
@ -110,7 +110,7 @@ def render_multiple_pages(app, num: int):
|
|||||||
default_value=[0, 25000000],
|
default_value=[0, 25000000],
|
||||||
min=0,
|
min=0,
|
||||||
max=25000000,
|
max=25000000,
|
||||||
on_value_commit=State.set_salary, # type: ignore
|
on_value_commit=State.set_salary, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
),
|
),
|
||||||
align_items="left",
|
align_items="left",
|
||||||
width="100%",
|
width="100%",
|
||||||
@ -130,7 +130,7 @@ def render_multiple_pages(app, num: int):
|
|||||||
|
|
||||||
def AppWithOnePage():
|
def AppWithOnePage():
|
||||||
"""A reflex app with one page."""
|
"""A reflex app with one page."""
|
||||||
from rxconfig import config # type: ignore
|
from rxconfig import config # pyright: ignore [reportMissingImports]
|
||||||
|
|
||||||
import reflex as rx
|
import reflex as rx
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ def app_with_ten_pages(
|
|||||||
root=root,
|
root=root,
|
||||||
app_source=functools.partial(
|
app_source=functools.partial(
|
||||||
AppWithTenPages,
|
AppWithTenPages,
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
render_comp=render_multiple_pages, # pyright: ignore [reportCallIssue]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -255,9 +255,9 @@ def app_with_hundred_pages(
|
|||||||
root=root,
|
root=root,
|
||||||
app_source=functools.partial(
|
app_source=functools.partial(
|
||||||
AppWithHundredPages,
|
AppWithHundredPages,
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
render_comp=render_multiple_pages, # pyright: ignore [reportCallIssue]
|
||||||
),
|
),
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
@ -278,9 +278,9 @@ def app_with_thousand_pages(
|
|||||||
root=root,
|
root=root,
|
||||||
app_source=functools.partial(
|
app_source=functools.partial(
|
||||||
AppWithThousandPages,
|
AppWithThousandPages,
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
render_comp=render_multiple_pages, # pyright: ignore [reportCallIssue]
|
||||||
),
|
),
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
@ -301,9 +301,9 @@ def app_with_ten_thousand_pages(
|
|||||||
root=root,
|
root=root,
|
||||||
app_source=functools.partial(
|
app_source=functools.partial(
|
||||||
AppWithTenThousandPages,
|
AppWithTenThousandPages,
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
render_comp=render_multiple_pages, # pyright: ignore [reportCallIssue]
|
||||||
),
|
),
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
||||||
|
434
poetry.lock
generated
434
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@ keywords = ["web", "framework"]
|
|||||||
classifiers = ["Development Status :: 4 - Beta"]
|
classifiers = ["Development Status :: 4 - Beta"]
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.10"
|
python = ">=3.10, <4.0"
|
||||||
fastapi = ">=0.96.0,!=0.111.0,!=0.111.1"
|
fastapi = ">=0.96.0,!=0.111.0,!=0.111.1"
|
||||||
gunicorn = ">=20.1.0,<24.0"
|
gunicorn = ">=20.1.0,<24.0"
|
||||||
jinja2 = ">=3.1.2,<4.0"
|
jinja2 = ">=3.1.2,<4.0"
|
||||||
@ -55,7 +55,7 @@ typing_extensions = ">=4.6.0"
|
|||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
pytest = ">=7.1.2,<9.0"
|
pytest = ">=7.1.2,<9.0"
|
||||||
pytest-mock = ">=3.10.0,<4.0"
|
pytest-mock = ">=3.10.0,<4.0"
|
||||||
pyright = ">=1.1.229,<1.1.335"
|
pyright = ">=1.1.392, <1.2"
|
||||||
darglint = ">=1.8.1,<2.0"
|
darglint = ">=1.8.1,<2.0"
|
||||||
dill = ">=0.3.8"
|
dill = ">=0.3.8"
|
||||||
toml = ">=0.10.2,<1.0"
|
toml = ">=0.10.2,<1.0"
|
||||||
@ -80,21 +80,22 @@ requires = ["poetry-core>=1.5.1"]
|
|||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.pyright]
|
[tool.pyright]
|
||||||
|
reportIncompatibleMethodOverride = false
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
target-version = "py39"
|
target-version = "py310"
|
||||||
output-format = "concise"
|
output-format = "concise"
|
||||||
lint.isort.split-on-trailing-comma = false
|
lint.isort.split-on-trailing-comma = false
|
||||||
lint.select = ["B", "C4", "D", "E", "ERA", "F", "FURB", "I", "N", "PERF", "PTH", "RUF", "SIM", "T", "TRY", "W"]
|
lint.select = ["ANN001","B", "C4", "D", "E", "ERA", "F", "FURB", "I", "N", "PERF", "PGH", "PTH", "RUF", "SIM", "T", "TRY", "W"]
|
||||||
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012", "TRY0"]
|
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012", "TRY0"]
|
||||||
lint.pydocstyle.convention = "google"
|
lint.pydocstyle.convention = "google"
|
||||||
|
|
||||||
[tool.ruff.lint.per-file-ignores]
|
[tool.ruff.lint.per-file-ignores]
|
||||||
"__init__.py" = ["F401"]
|
"__init__.py" = ["F401"]
|
||||||
"tests/*.py" = ["D100", "D103", "D104", "B018", "PERF", "T", "N"]
|
"tests/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
|
||||||
"benchmarks/*.py" = ["D100", "D103", "D104", "B018", "PERF", "T", "N"]
|
"benchmarks/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
|
||||||
"reflex/.templates/*.py" = ["D100", "D103", "D104"]
|
"reflex/.templates/*.py" = ["D100", "D103", "D104"]
|
||||||
"*.pyi" = ["D301", "D415", "D417", "D418", "E742", "N"]
|
"*.pyi" = ["D301", "D415", "D417", "D418", "E742", "N", "PGH"]
|
||||||
"pyi_generator.py" = ["N802"]
|
"pyi_generator.py" = ["N802"]
|
||||||
"reflex/constants/*.py" = ["N"]
|
"reflex/constants/*.py" = ["N"]
|
||||||
"*/blank.py" = ["I001"]
|
"*/blank.py" = ["I001"]
|
||||||
|
@ -90,7 +90,7 @@
|
|||||||
break;
|
break;
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
default:
|
default:
|
||||||
return {{ component.default }};
|
return {{ render(component.default) }};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
@ -84,6 +84,9 @@ In the example above, you will be able to do `rx.list`
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from types import ModuleType
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from reflex.utils import (
|
from reflex.utils import (
|
||||||
compat, # for side-effects
|
compat, # for side-effects
|
||||||
lazy_loader,
|
lazy_loader,
|
||||||
@ -365,5 +368,5 @@ getattr, __dir__, __all__ = lazy_loader.attach(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name: ModuleType | Any):
|
||||||
return getattr(name)
|
return getattr(name)
|
||||||
|
@ -131,7 +131,7 @@ from .components.radix.themes.layout.container import container as container
|
|||||||
from .components.radix.themes.layout.flex import flex as flex
|
from .components.radix.themes.layout.flex import flex as flex
|
||||||
from .components.radix.themes.layout.grid import grid as grid
|
from .components.radix.themes.layout.grid import grid as grid
|
||||||
from .components.radix.themes.layout.list import list_item as list_item
|
from .components.radix.themes.layout.list import list_item as list_item
|
||||||
from .components.radix.themes.layout.list import list_ns as list # noqa
|
from .components.radix.themes.layout.list import list_ns as list # noqa: F401
|
||||||
from .components.radix.themes.layout.list import ordered_list as ordered_list
|
from .components.radix.themes.layout.list import ordered_list as ordered_list
|
||||||
from .components.radix.themes.layout.list import unordered_list as unordered_list
|
from .components.radix.themes.layout.list import unordered_list as unordered_list
|
||||||
from .components.radix.themes.layout.section import section as section
|
from .components.radix.themes.layout.section import section as section
|
||||||
|
@ -27,6 +27,7 @@ from typing import (
|
|||||||
Dict,
|
Dict,
|
||||||
Generic,
|
Generic,
|
||||||
List,
|
List,
|
||||||
|
MutableMapping,
|
||||||
Optional,
|
Optional,
|
||||||
Set,
|
Set,
|
||||||
Type,
|
Type,
|
||||||
@ -145,7 +146,7 @@ def default_backend_exception_handler(exception: Exception) -> EventSpec:
|
|||||||
position="top-center",
|
position="top-center",
|
||||||
id="backend_error",
|
id="backend_error",
|
||||||
style={"width": "500px"},
|
style={"width": "500px"},
|
||||||
) # type: ignore
|
) # pyright: ignore [reportReturnType]
|
||||||
else:
|
else:
|
||||||
error_message.insert(0, "An error occurred.")
|
error_message.insert(0, "An error occurred.")
|
||||||
return window_alert("\n".join(error_message))
|
return window_alert("\n".join(error_message))
|
||||||
@ -407,23 +408,28 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
if self.api:
|
if self.api:
|
||||||
|
|
||||||
class HeaderMiddleware:
|
class HeaderMiddleware:
|
||||||
def __init__(self, app):
|
def __init__(self, app: ASGIApp):
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
async def __call__(self, scope, receive, send):
|
async def __call__(
|
||||||
|
self, scope: MutableMapping[str, Any], receive: Any, send: Callable
|
||||||
|
):
|
||||||
original_send = send
|
original_send = send
|
||||||
|
|
||||||
async def modified_send(message):
|
async def modified_send(message: dict):
|
||||||
headers = dict(scope["headers"])
|
if message["type"] == "websocket.accept":
|
||||||
protocol_key = b"sec-websocket-protocol"
|
if scope.get("subprotocols"):
|
||||||
if (
|
# The following *does* say "subprotocol" instead of "subprotocols", intentionally.
|
||||||
message["type"] == "websocket.accept"
|
message["subprotocol"] = scope["subprotocols"][0]
|
||||||
and protocol_key in headers
|
|
||||||
):
|
headers = dict(message.get("headers", []))
|
||||||
message["headers"] = [
|
header_key = b"sec-websocket-protocol"
|
||||||
*message.get("headers", []),
|
if subprotocol := headers.get(header_key):
|
||||||
(b"sec-websocket-protocol", headers[protocol_key]),
|
message["headers"] = [
|
||||||
]
|
*message.get("headers", []),
|
||||||
|
(header_key, subprotocol),
|
||||||
|
]
|
||||||
|
|
||||||
return await original_send(message)
|
return await original_send(message)
|
||||||
|
|
||||||
return await self.app(scope, receive, modified_send)
|
return await self.app(scope, receive, modified_send)
|
||||||
@ -672,7 +678,10 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
for route in self._pages:
|
for route in self._pages:
|
||||||
replaced_route = replace_brackets_with_keywords(route)
|
replaced_route = replace_brackets_with_keywords(route)
|
||||||
for rw, r, nr in zip(
|
for rw, r, nr in zip(
|
||||||
replaced_route.split("/"), route.split("/"), new_route.split("/")
|
replaced_route.split("/"),
|
||||||
|
route.split("/"),
|
||||||
|
new_route.split("/"),
|
||||||
|
strict=False,
|
||||||
):
|
):
|
||||||
if rw in segments and r != nr:
|
if rw in segments and r != nr:
|
||||||
# If the slugs in the segments of both routes are not the same, then the route is invalid
|
# If the slugs in the segments of both routes are not the same, then the route is invalid
|
||||||
@ -703,8 +712,8 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
Args:
|
Args:
|
||||||
component: The component to display at the page.
|
component: The component to display at the page.
|
||||||
title: The title of the page.
|
title: The title of the page.
|
||||||
description: The description of the page.
|
|
||||||
image: The image to display on the page.
|
image: The image to display on the page.
|
||||||
|
description: The description of the page.
|
||||||
on_load: The event handler(s) that will be called each time the page load.
|
on_load: The event handler(s) that will be called each time the page load.
|
||||||
meta: The metadata of the page.
|
meta: The metadata of the page.
|
||||||
"""
|
"""
|
||||||
@ -771,7 +780,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
frontend_packages = get_config().frontend_packages
|
frontend_packages = get_config().frontend_packages
|
||||||
_frontend_packages = []
|
_frontend_packages = []
|
||||||
for package in frontend_packages:
|
for package in frontend_packages:
|
||||||
if package in (get_config().tailwind or {}).get("plugins", []): # type: ignore
|
if package in (get_config().tailwind or {}).get("plugins", []):
|
||||||
console.warn(
|
console.warn(
|
||||||
f"Tailwind packages are inferred from 'plugins', remove `{package}` from `frontend_packages`"
|
f"Tailwind packages are inferred from 'plugins', remove `{package}` from `frontend_packages`"
|
||||||
)
|
)
|
||||||
@ -1022,7 +1031,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
compiler.compile_document_root(
|
compiler.compile_document_root(
|
||||||
self.head_components,
|
self.head_components,
|
||||||
html_lang=self.html_lang,
|
html_lang=self.html_lang,
|
||||||
html_custom_attrs=self.html_custom_attrs, # type: ignore
|
html_custom_attrs=self.html_custom_attrs, # pyright: ignore [reportArgumentType]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1045,7 +1054,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
max_workers=environment.REFLEX_COMPILE_THREADS.get() or None
|
max_workers=environment.REFLEX_COMPILE_THREADS.get() or None
|
||||||
)
|
)
|
||||||
|
|
||||||
for route, component in zip(self._pages, page_components):
|
for route, component in zip(self._pages, page_components, strict=True):
|
||||||
ExecutorSafeFunctions.COMPONENTS[route] = component
|
ExecutorSafeFunctions.COMPONENTS[route] = component
|
||||||
|
|
||||||
ExecutorSafeFunctions.STATE = self._state
|
ExecutorSafeFunctions.STATE = self._state
|
||||||
@ -1053,7 +1062,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
with executor:
|
with executor:
|
||||||
result_futures = []
|
result_futures = []
|
||||||
|
|
||||||
def _submit_work(fn, *args, **kwargs):
|
def _submit_work(fn: Callable, *args, **kwargs):
|
||||||
f = executor.submit(fn, *args, **kwargs)
|
f = executor.submit(fn, *args, **kwargs)
|
||||||
result_futures.append(f)
|
result_futures.append(f)
|
||||||
|
|
||||||
@ -1242,6 +1251,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
frontend_arg_spec,
|
frontend_arg_spec,
|
||||||
backend_arg_spec,
|
backend_arg_spec,
|
||||||
],
|
],
|
||||||
|
strict=True,
|
||||||
):
|
):
|
||||||
if hasattr(handler_fn, "__name__"):
|
if hasattr(handler_fn, "__name__"):
|
||||||
_fn_name = handler_fn.__name__
|
_fn_name = handler_fn.__name__
|
||||||
@ -1383,15 +1393,14 @@ async def process(
|
|||||||
if app._process_background(state, event) is not None:
|
if app._process_background(state, event) is not None:
|
||||||
# `final=True` allows the frontend send more events immediately.
|
# `final=True` allows the frontend send more events immediately.
|
||||||
yield StateUpdate(final=True)
|
yield StateUpdate(final=True)
|
||||||
return
|
else:
|
||||||
|
# Process the event synchronously.
|
||||||
|
async for update in state._process(event):
|
||||||
|
# Postprocess the event.
|
||||||
|
update = await app._postprocess(state, event, update)
|
||||||
|
|
||||||
# Process the event synchronously.
|
# Yield the update.
|
||||||
async for update in state._process(event):
|
yield update
|
||||||
# Postprocess the event.
|
|
||||||
update = await app._postprocess(state, event, update)
|
|
||||||
|
|
||||||
# Yield the update.
|
|
||||||
yield update
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
telemetry.send_error(ex, context="backend")
|
telemetry.send_error(ex, context="backend")
|
||||||
|
|
||||||
@ -1586,20 +1595,20 @@ class EventNamespace(AsyncNamespace):
|
|||||||
self.sid_to_token = {}
|
self.sid_to_token = {}
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
def on_connect(self, sid, environ):
|
def on_connect(self, sid: str, environ: dict):
|
||||||
"""Event for when the websocket is connected.
|
"""Event for when the websocket is connected.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sid: The Socket.IO session id.
|
sid: The Socket.IO session id.
|
||||||
environ: The request information, including HTTP headers.
|
environ: The request information, including HTTP headers.
|
||||||
"""
|
"""
|
||||||
subprotocol = environ.get("HTTP_SEC_WEBSOCKET_PROTOCOL", None)
|
subprotocol = environ.get("HTTP_SEC_WEBSOCKET_PROTOCOL")
|
||||||
if subprotocol and subprotocol != constants.Reflex.VERSION:
|
if subprotocol and subprotocol != constants.Reflex.VERSION:
|
||||||
console.warn(
|
console.warn(
|
||||||
f"Frontend version {subprotocol} for session {sid} does not match the backend version {constants.Reflex.VERSION}."
|
f"Frontend version {subprotocol} for session {sid} does not match the backend version {constants.Reflex.VERSION}."
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_disconnect(self, sid):
|
def on_disconnect(self, sid: str):
|
||||||
"""Event for when the websocket disconnects.
|
"""Event for when the websocket disconnects.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1621,7 +1630,7 @@ class EventNamespace(AsyncNamespace):
|
|||||||
self.emit(str(constants.SocketEvent.EVENT), update, to=sid)
|
self.emit(str(constants.SocketEvent.EVENT), update, to=sid)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def on_event(self, sid, data):
|
async def on_event(self, sid: str, data: Any):
|
||||||
"""Event for receiving front-end websocket events.
|
"""Event for receiving front-end websocket events.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@ -1688,7 +1697,7 @@ class EventNamespace(AsyncNamespace):
|
|||||||
# Emit the update from processing the event.
|
# Emit the update from processing the event.
|
||||||
await self.emit_update(update=update, sid=sid)
|
await self.emit_update(update=update, sid=sid)
|
||||||
|
|
||||||
async def on_ping(self, sid):
|
async def on_ping(self, sid: str):
|
||||||
"""Event for testing the API endpoint.
|
"""Event for testing the API endpoint.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -32,7 +32,7 @@ class LifespanMixin(AppMixin):
|
|||||||
try:
|
try:
|
||||||
async with contextlib.AsyncExitStack() as stack:
|
async with contextlib.AsyncExitStack() as stack:
|
||||||
for task in self.lifespan_tasks:
|
for task in self.lifespan_tasks:
|
||||||
run_msg = f"Started lifespan task: {task.__name__} as {{type}}" # type: ignore
|
run_msg = f"Started lifespan task: {task.__name__} as {{type}}" # pyright: ignore [reportAttributeAccessIssue]
|
||||||
if isinstance(task, asyncio.Task):
|
if isinstance(task, asyncio.Task):
|
||||||
running_tasks.append(task)
|
running_tasks.append(task)
|
||||||
else:
|
else:
|
||||||
@ -61,7 +61,7 @@ class LifespanMixin(AppMixin):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
task: The task to register.
|
task: The task to register.
|
||||||
task_kwargs: The kwargs of the task.
|
**task_kwargs: The kwargs of the task.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
InvalidLifespanTaskTypeError: If the task is a generator function.
|
InvalidLifespanTaskTypeError: If the task is a generator function.
|
||||||
@ -73,7 +73,7 @@ class LifespanMixin(AppMixin):
|
|||||||
|
|
||||||
if task_kwargs:
|
if task_kwargs:
|
||||||
original_task = task
|
original_task = task
|
||||||
task = functools.partial(task, **task_kwargs) # type: ignore
|
task = functools.partial(task, **task_kwargs) # pyright: ignore [reportArgumentType]
|
||||||
functools.update_wrapper(task, original_task) # type: ignore
|
functools.update_wrapper(task, original_task) # pyright: ignore [reportArgumentType]
|
||||||
self.lifespan_tasks.add(task) # type: ignore
|
self.lifespan_tasks.add(task)
|
||||||
console.debug(f"Registered lifespan task: {task.__name__}") # type: ignore
|
console.debug(f"Registered lifespan task: {task.__name__}") # pyright: ignore [reportAttributeAccessIssue]
|
||||||
|
@ -53,11 +53,11 @@ class MiddlewareMixin(AppMixin):
|
|||||||
"""
|
"""
|
||||||
for middleware in self.middleware:
|
for middleware in self.middleware:
|
||||||
if asyncio.iscoroutinefunction(middleware.preprocess):
|
if asyncio.iscoroutinefunction(middleware.preprocess):
|
||||||
out = await middleware.preprocess(app=self, state=state, event=event) # type: ignore
|
out = await middleware.preprocess(app=self, state=state, event=event) # pyright: ignore [reportArgumentType]
|
||||||
else:
|
else:
|
||||||
out = middleware.preprocess(app=self, state=state, event=event) # type: ignore
|
out = middleware.preprocess(app=self, state=state, event=event) # pyright: ignore [reportArgumentType]
|
||||||
if out is not None:
|
if out is not None:
|
||||||
return out # type: ignore
|
return out # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
async def _postprocess(
|
async def _postprocess(
|
||||||
self, state: BaseState, event: Event, update: StateUpdate
|
self, state: BaseState, event: Event, update: StateUpdate
|
||||||
@ -78,18 +78,18 @@ class MiddlewareMixin(AppMixin):
|
|||||||
for middleware in self.middleware:
|
for middleware in self.middleware:
|
||||||
if asyncio.iscoroutinefunction(middleware.postprocess):
|
if asyncio.iscoroutinefunction(middleware.postprocess):
|
||||||
out = await middleware.postprocess(
|
out = await middleware.postprocess(
|
||||||
app=self, # type: ignore
|
app=self, # pyright: ignore [reportArgumentType]
|
||||||
state=state,
|
state=state,
|
||||||
event=event,
|
event=event,
|
||||||
update=update,
|
update=update,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
out = middleware.postprocess(
|
out = middleware.postprocess(
|
||||||
app=self, # type: ignore
|
app=self, # pyright: ignore [reportArgumentType]
|
||||||
state=state,
|
state=state,
|
||||||
event=event,
|
event=event,
|
||||||
update=update,
|
update=update,
|
||||||
)
|
)
|
||||||
if out is not None:
|
if out is not None:
|
||||||
return out # type: ignore
|
return out # pyright: ignore [reportReturnType]
|
||||||
return update
|
return update
|
||||||
|
@ -13,7 +13,7 @@ except ModuleNotFoundError:
|
|||||||
if not TYPE_CHECKING:
|
if not TYPE_CHECKING:
|
||||||
import pydantic.main as pydantic_main
|
import pydantic.main as pydantic_main
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from pydantic.fields import ModelField # type: ignore
|
from pydantic.fields import ModelField
|
||||||
|
|
||||||
|
|
||||||
def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None:
|
def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None:
|
||||||
@ -44,13 +44,13 @@ def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None
|
|||||||
|
|
||||||
# monkeypatch pydantic validate_field_name method to skip validating
|
# monkeypatch pydantic validate_field_name method to skip validating
|
||||||
# shadowed state vars when reloading app via utils.prerequisites.get_app(reload=True)
|
# shadowed state vars when reloading app via utils.prerequisites.get_app(reload=True)
|
||||||
pydantic_main.validate_field_name = validate_field_name # type: ignore
|
pydantic_main.validate_field_name = validate_field_name # pyright: ignore [reportPossiblyUnboundVariable, reportPrivateImportUsage]
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
|
|
||||||
class Base(BaseModel): # pyright: ignore [reportUnboundVariable]
|
class Base(BaseModel): # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
"""The base class subclassed by all Reflex classes.
|
"""The base class subclassed by all Reflex classes.
|
||||||
|
|
||||||
This class wraps Pydantic and provides common methods such as
|
This class wraps Pydantic and provides common methods such as
|
||||||
@ -75,12 +75,12 @@ class Base(BaseModel): # pyright: ignore [reportUnboundVariable]
|
|||||||
"""
|
"""
|
||||||
from reflex.utils.serializers import serialize
|
from reflex.utils.serializers import serialize
|
||||||
|
|
||||||
return self.__config__.json_dumps( # type: ignore
|
return self.__config__.json_dumps(
|
||||||
self.dict(),
|
self.dict(),
|
||||||
default=serialize,
|
default=serialize,
|
||||||
)
|
)
|
||||||
|
|
||||||
def set(self, **kwargs):
|
def set(self, **kwargs: Any):
|
||||||
"""Set multiple fields and return the object.
|
"""Set multiple fields and return the object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -113,12 +113,12 @@ class Base(BaseModel): # pyright: ignore [reportUnboundVariable]
|
|||||||
default_value: The default value of the field
|
default_value: The default value of the field
|
||||||
"""
|
"""
|
||||||
var_name = var._var_field_name
|
var_name = var._var_field_name
|
||||||
new_field = ModelField.infer(
|
new_field = ModelField.infer( # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
name=var_name,
|
name=var_name,
|
||||||
value=default_value,
|
value=default_value,
|
||||||
annotation=var._var_type,
|
annotation=var._var_type,
|
||||||
class_validators=None,
|
class_validators=None,
|
||||||
config=cls.__config__, # type: ignore
|
config=cls.__config__,
|
||||||
)
|
)
|
||||||
cls.__fields__.update({var_name: new_field})
|
cls.__fields__.update({var_name: new_field})
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import traceback
|
||||||
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable, Dict, Optional, Type, Union
|
from typing import Any, Callable, Dict, Optional, Type, Union
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
@ -13,7 +15,9 @@ from reflex.vars.base import Var
|
|||||||
try:
|
try:
|
||||||
from pydantic.v1.fields import ModelField
|
from pydantic.v1.fields import ModelField
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
from pydantic.fields import ModelField # type: ignore
|
from pydantic.fields import (
|
||||||
|
ModelField, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
|
)
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.components.base import (
|
from reflex.components.base import (
|
||||||
@ -116,7 +120,7 @@ def compile_imports(import_dict: ParsedImportDict) -> list[dict]:
|
|||||||
default, rest = compile_import_statement(fields)
|
default, rest = compile_import_statement(fields)
|
||||||
|
|
||||||
# prevent lib from being rendered on the page if all imports are non rendered kind
|
# prevent lib from being rendered on the page if all imports are non rendered kind
|
||||||
if not any(f.render for f in fields): # type: ignore
|
if not any(f.render for f in fields):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not lib:
|
if not lib:
|
||||||
@ -164,8 +168,12 @@ def compile_state(state: Type[BaseState]) -> dict:
|
|||||||
try:
|
try:
|
||||||
initial_state = state(_reflex_internal_init=True).dict(initial=True)
|
initial_state = state(_reflex_internal_init=True).dict(initial=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
timestamp = datetime.now().strftime("%Y-%m-%d__%H-%M-%S")
|
||||||
|
constants.Reflex.LOGS_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
log_path = constants.Reflex.LOGS_DIR / f"state_compile_error_{timestamp}.log"
|
||||||
|
traceback.TracebackException.from_exception(e).print(file=log_path.open("w+"))
|
||||||
console.warn(
|
console.warn(
|
||||||
f"Failed to compile initial state with computed vars, excluding them: {e}"
|
f"Failed to compile initial state with computed vars. Error log saved to {log_path}"
|
||||||
)
|
)
|
||||||
initial_state = state(_reflex_internal_init=True).dict(
|
initial_state = state(_reflex_internal_init=True).dict(
|
||||||
initial=True, include_computed=False
|
initial=True, include_computed=False
|
||||||
@ -495,7 +503,7 @@ def empty_dir(path: str | Path, keep_files: list[str] | None = None):
|
|||||||
path_ops.rm(element)
|
path_ops.rm(element)
|
||||||
|
|
||||||
|
|
||||||
def is_valid_url(url) -> bool:
|
def is_valid_url(url: str) -> bool:
|
||||||
"""Check if a url is valid.
|
"""Check if a url is valid.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -31,7 +31,7 @@ class Bare(Component):
|
|||||||
return cls(contents=contents)
|
return cls(contents=contents)
|
||||||
else:
|
else:
|
||||||
contents = str(contents) if contents is not None else ""
|
contents = str(contents) if contents is not None else ""
|
||||||
return cls(contents=contents) # type: ignore
|
return cls(contents=contents)
|
||||||
|
|
||||||
def _get_all_hooks_internal(self) -> dict[str, VarData | None]:
|
def _get_all_hooks_internal(self) -> dict[str, VarData | None]:
|
||||||
"""Include the hooks for the component.
|
"""Include the hooks for the component.
|
||||||
|
@ -53,11 +53,11 @@ class Description(Meta):
|
|||||||
"""A component that displays the title of the current page."""
|
"""A component that displays the title of the current page."""
|
||||||
|
|
||||||
# The type of the description.
|
# The type of the description.
|
||||||
name: str = "description"
|
name: str | None = "description"
|
||||||
|
|
||||||
|
|
||||||
class Image(Meta):
|
class Image(Meta):
|
||||||
"""A component that displays the title of the current page."""
|
"""A component that displays the title of the current page."""
|
||||||
|
|
||||||
# The type of the image.
|
# The type of the image.
|
||||||
property: str = "og:image"
|
property: str | None = "og:image"
|
||||||
|
@ -150,7 +150,7 @@ class BaseComponent(Base, ABC):
|
|||||||
class ComponentNamespace(SimpleNamespace):
|
class ComponentNamespace(SimpleNamespace):
|
||||||
"""A namespace to manage components with subcomponents."""
|
"""A namespace to manage components with subcomponents."""
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
"""Get the hash of the namespace.
|
"""Get the hash of the namespace.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -426,7 +426,7 @@ class Component(BaseComponent, ABC):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
def determine_key(value):
|
def determine_key(value: Any):
|
||||||
# Try to create a var from the value
|
# Try to create a var from the value
|
||||||
key = value if isinstance(value, Var) else LiteralVar.create(value)
|
key = value if isinstance(value, Var) else LiteralVar.create(value)
|
||||||
|
|
||||||
@ -462,9 +462,7 @@ class Component(BaseComponent, ABC):
|
|||||||
if types.is_union(passed_type):
|
if types.is_union(passed_type):
|
||||||
# We need to check all possible types in the union.
|
# We need to check all possible types in the union.
|
||||||
passed_types = (
|
passed_types = (
|
||||||
arg
|
arg for arg in passed_type.__args__ if arg is not type(None)
|
||||||
for arg in passed_type.__args__ # type: ignore
|
|
||||||
if arg is not type(None)
|
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
# If the passed var is a union, check if all possible types are valid.
|
# If the passed var is a union, check if all possible types are valid.
|
||||||
@ -491,7 +489,7 @@ class Component(BaseComponent, ABC):
|
|||||||
# Check if the key is an event trigger.
|
# Check if the key is an event trigger.
|
||||||
if key in component_specific_triggers:
|
if key in component_specific_triggers:
|
||||||
kwargs["event_triggers"][key] = EventChain.create(
|
kwargs["event_triggers"][key] = EventChain.create(
|
||||||
value=value, # type: ignore
|
value=value,
|
||||||
args_spec=component_specific_triggers[key],
|
args_spec=component_specific_triggers[key],
|
||||||
key=key,
|
key=key,
|
||||||
)
|
)
|
||||||
@ -578,7 +576,7 @@ class Component(BaseComponent, ABC):
|
|||||||
annotation = field.annotation
|
annotation = field.annotation
|
||||||
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
||||||
args_spec = metadata[0]
|
args_spec = metadata[0]
|
||||||
default_triggers[field.name] = args_spec or (no_args_event_spec) # type: ignore
|
default_triggers[field.name] = args_spec or (no_args_event_spec)
|
||||||
return default_triggers
|
return default_triggers
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
@ -709,7 +707,7 @@ class Component(BaseComponent, ABC):
|
|||||||
# Filter out None props
|
# Filter out None props
|
||||||
props = {key: value for key, value in props.items() if value is not None}
|
props = {key: value for key, value in props.items() if value is not None}
|
||||||
|
|
||||||
def validate_children(children):
|
def validate_children(children: tuple | list):
|
||||||
for child in children:
|
for child in children:
|
||||||
if isinstance(child, (tuple, list)):
|
if isinstance(child, (tuple, list)):
|
||||||
validate_children(child)
|
validate_children(child)
|
||||||
@ -761,7 +759,7 @@ class Component(BaseComponent, ABC):
|
|||||||
|
|
||||||
# Walk the MRO to call all `add_style` methods.
|
# Walk the MRO to call all `add_style` methods.
|
||||||
for base in self._iter_parent_classes_with_method("add_style"):
|
for base in self._iter_parent_classes_with_method("add_style"):
|
||||||
s = base.add_style(self) # type: ignore
|
s = base.add_style(self)
|
||||||
if s is not None:
|
if s is not None:
|
||||||
styles.append(s)
|
styles.append(s)
|
||||||
|
|
||||||
@ -853,7 +851,7 @@ class Component(BaseComponent, ABC):
|
|||||||
else {}
|
else {}
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self) -> Dict:
|
def render(self) -> dict:
|
||||||
"""Render the component.
|
"""Render the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -871,7 +869,7 @@ class Component(BaseComponent, ABC):
|
|||||||
self._replace_prop_names(rendered_dict)
|
self._replace_prop_names(rendered_dict)
|
||||||
return rendered_dict
|
return rendered_dict
|
||||||
|
|
||||||
def _replace_prop_names(self, rendered_dict) -> None:
|
def _replace_prop_names(self, rendered_dict: dict) -> None:
|
||||||
"""Replace the prop names in the render dictionary.
|
"""Replace the prop names in the render dictionary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -911,7 +909,7 @@ class Component(BaseComponent, ABC):
|
|||||||
comp.__name__ for comp in (Fragment, Foreach, Cond, Match)
|
comp.__name__ for comp in (Fragment, Foreach, Cond, Match)
|
||||||
]
|
]
|
||||||
|
|
||||||
def validate_child(child):
|
def validate_child(child: Any):
|
||||||
child_name = type(child).__name__
|
child_name = type(child).__name__
|
||||||
|
|
||||||
# Iterate through the immediate children of fragment
|
# Iterate through the immediate children of fragment
|
||||||
@ -1674,7 +1672,7 @@ class CustomComponent(Component):
|
|||||||
if base_value is not None and isinstance(value, Component):
|
if base_value is not None and isinstance(value, Component):
|
||||||
self.component_props[key] = value
|
self.component_props[key] = value
|
||||||
value = base_value._replace(
|
value = base_value._replace(
|
||||||
merge_var_data=VarData( # type: ignore
|
merge_var_data=VarData(
|
||||||
imports=value._get_all_imports(),
|
imports=value._get_all_imports(),
|
||||||
hooks=value._get_all_hooks(),
|
hooks=value._get_all_hooks(),
|
||||||
)
|
)
|
||||||
@ -1707,7 +1705,7 @@ class CustomComponent(Component):
|
|||||||
return hash(self.tag)
|
return hash(self.tag)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_props(cls) -> Set[str]:
|
def get_props(cls) -> Set[str]: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
"""Get the props for the component.
|
"""Get the props for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -1802,7 +1800,7 @@ class CustomComponent(Component):
|
|||||||
include_children=include_children, ignore_ids=ignore_ids
|
include_children=include_children, ignore_ids=ignore_ids
|
||||||
)
|
)
|
||||||
|
|
||||||
@lru_cache(maxsize=None) # noqa
|
@lru_cache(maxsize=None) # noqa: B019
|
||||||
def get_component(self) -> Component:
|
def get_component(self) -> Component:
|
||||||
"""Render the component.
|
"""Render the component.
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ from reflex.vars.function import FunctionStringVar
|
|||||||
from reflex.vars.number import BooleanVar
|
from reflex.vars.number import BooleanVar
|
||||||
from reflex.vars.sequence import LiteralArrayVar
|
from reflex.vars.sequence import LiteralArrayVar
|
||||||
|
|
||||||
connect_error_var_data: VarData = VarData( # type: ignore
|
connect_error_var_data: VarData = VarData(
|
||||||
imports=Imports.EVENTS,
|
imports=Imports.EVENTS,
|
||||||
hooks={Hooks.EVENTS: None},
|
hooks={Hooks.EVENTS: None},
|
||||||
)
|
)
|
||||||
@ -99,14 +99,14 @@ class ConnectionToaster(Toaster):
|
|||||||
"""
|
"""
|
||||||
toast_id = "websocket-error"
|
toast_id = "websocket-error"
|
||||||
target_url = WebsocketTargetURL.create()
|
target_url = WebsocketTargetURL.create()
|
||||||
props = ToastProps( # type: ignore
|
props = ToastProps(
|
||||||
description=LiteralVar.create(
|
description=LiteralVar.create(
|
||||||
f"Check if server is reachable at {target_url}",
|
f"Check if server is reachable at {target_url}",
|
||||||
),
|
),
|
||||||
close_button=True,
|
close_button=True,
|
||||||
duration=120000,
|
duration=120000,
|
||||||
id=toast_id,
|
id=toast_id,
|
||||||
)
|
) # pyright: ignore [reportCallIssue]
|
||||||
|
|
||||||
individual_hooks = [
|
individual_hooks = [
|
||||||
f"const toast_props = {LiteralVar.create(props)!s};",
|
f"const toast_props = {LiteralVar.create(props)!s};",
|
||||||
@ -116,7 +116,7 @@ class ConnectionToaster(Toaster):
|
|||||||
_var_data=VarData(
|
_var_data=VarData(
|
||||||
imports={
|
imports={
|
||||||
"react": ["useEffect", "useState"],
|
"react": ["useEffect", "useState"],
|
||||||
**dict(target_url._get_all_var_data().imports), # type: ignore
|
**dict(target_url._get_all_var_data().imports), # pyright: ignore [reportArgumentType, reportOptionalMemberAccess]
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
).call(
|
).call(
|
||||||
|
@ -82,7 +82,9 @@ class Breakpoints(Dict[K, V]):
|
|||||||
return Breakpoints(
|
return Breakpoints(
|
||||||
{
|
{
|
||||||
k: v
|
k: v
|
||||||
for k, v in zip(["initial", *breakpoint_names], thresholds)
|
for k, v in zip(
|
||||||
|
["initial", *breakpoint_names], thresholds, strict=True
|
||||||
|
)
|
||||||
if v is not None
|
if v is not None
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -41,7 +41,7 @@ class ClientSideRouting(Component):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def wait_for_client_redirect(component) -> Component:
|
def wait_for_client_redirect(component: Component) -> Component:
|
||||||
"""Wait for a redirect to occur before rendering a component.
|
"""Wait for a redirect to occur before rendering a component.
|
||||||
|
|
||||||
This prevents the 404 page from flashing while the redirect is happening.
|
This prevents the 404 page from flashing while the redirect is happening.
|
||||||
|
@ -60,7 +60,7 @@ class ClientSideRouting(Component):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
def wait_for_client_redirect(component) -> Component: ...
|
def wait_for_client_redirect(component: Component) -> Component: ...
|
||||||
|
|
||||||
class Default404Page(Component):
|
class Default404Page(Component):
|
||||||
@overload
|
@overload
|
||||||
|
@ -26,10 +26,9 @@ class Cond(MemoizationLeaf):
|
|||||||
cond: Var[Any]
|
cond: Var[Any]
|
||||||
|
|
||||||
# The component to render if the cond is true.
|
# The component to render if the cond is true.
|
||||||
comp1: BaseComponent = None # type: ignore
|
comp1: BaseComponent | None = None
|
||||||
|
|
||||||
# The component to render if the cond is false.
|
# The component to render if the cond is false.
|
||||||
comp2: BaseComponent = None # type: ignore
|
comp2: BaseComponent | None = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(
|
||||||
@ -73,8 +72,8 @@ class Cond(MemoizationLeaf):
|
|||||||
def _render(self) -> Tag:
|
def _render(self) -> Tag:
|
||||||
return CondTag(
|
return CondTag(
|
||||||
cond=self.cond,
|
cond=self.cond,
|
||||||
true_value=self.comp1.render(),
|
true_value=self.comp1.render(), # pyright: ignore [reportOptionalMemberAccess]
|
||||||
false_value=self.comp2.render(),
|
false_value=self.comp2.render(), # pyright: ignore [reportOptionalMemberAccess]
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self) -> Dict:
|
def render(self) -> Dict:
|
||||||
@ -111,7 +110,7 @@ class Cond(MemoizationLeaf):
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def cond(condition: Any, c1: Component, c2: Any) -> Component: ...
|
def cond(condition: Any, c1: Component, c2: Any) -> Component: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -154,7 +153,7 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
|||||||
if c2 is None:
|
if c2 is None:
|
||||||
raise ValueError("For conditional vars, the second argument must be set.")
|
raise ValueError("For conditional vars, the second argument must be set.")
|
||||||
|
|
||||||
def create_var(cond_part):
|
def create_var(cond_part: Any) -> Var[Any]:
|
||||||
return LiteralVar.create(cond_part)
|
return LiteralVar.create(cond_part)
|
||||||
|
|
||||||
# convert the truth and false cond parts into vars so the _var_data can be obtained.
|
# convert the truth and false cond parts into vars so the _var_data can be obtained.
|
||||||
@ -163,16 +162,16 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
|||||||
|
|
||||||
# Create the conditional var.
|
# Create the conditional var.
|
||||||
return ternary_operation(
|
return ternary_operation(
|
||||||
cond_var.bool()._replace( # type: ignore
|
cond_var.bool()._replace(
|
||||||
merge_var_data=VarData(imports=_IS_TRUE_IMPORT),
|
merge_var_data=VarData(imports=_IS_TRUE_IMPORT),
|
||||||
), # type: ignore
|
),
|
||||||
c1,
|
c1,
|
||||||
c2,
|
c2,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def color_mode_cond(light: Component, dark: Component | None = None) -> Component: ... # type: ignore
|
def color_mode_cond(light: Component, dark: Component | None = None) -> Component: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
|
@ -28,7 +28,7 @@ class DebounceInput(Component):
|
|||||||
min_length: Var[int]
|
min_length: Var[int]
|
||||||
|
|
||||||
# Time to wait between end of input and triggering on_change
|
# Time to wait between end of input and triggering on_change
|
||||||
debounce_timeout: Var[int] = DEFAULT_DEBOUNCE_TIMEOUT # type: ignore
|
debounce_timeout: Var[int] = Var.create(DEFAULT_DEBOUNCE_TIMEOUT)
|
||||||
|
|
||||||
# If true, notify when Enter key is pressed
|
# If true, notify when Enter key is pressed
|
||||||
force_notify_by_enter: Var[bool]
|
force_notify_by_enter: Var[bool]
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Callable, Iterable
|
from typing import Any, Callable, Iterable
|
||||||
|
|
||||||
@ -97,9 +98,20 @@ class Foreach(Component):
|
|||||||
# Determine the index var name based on the params accepted by render_fn.
|
# Determine the index var name based on the params accepted by render_fn.
|
||||||
props["index_var_name"] = params[1].name
|
props["index_var_name"] = params[1].name
|
||||||
else:
|
else:
|
||||||
|
render_fn = self.render_fn
|
||||||
# Otherwise, use a deterministic index, based on the render function bytecode.
|
# Otherwise, use a deterministic index, based on the render function bytecode.
|
||||||
code_hash = (
|
code_hash = (
|
||||||
hash(self.render_fn.__code__)
|
hash(
|
||||||
|
getattr(
|
||||||
|
render_fn,
|
||||||
|
"__code__",
|
||||||
|
(
|
||||||
|
repr(self.render_fn)
|
||||||
|
if not isinstance(render_fn, functools.partial)
|
||||||
|
else render_fn.func.__code__
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
.to_bytes(
|
.to_bytes(
|
||||||
length=8,
|
length=8,
|
||||||
byteorder="big",
|
byteorder="big",
|
||||||
|
@ -109,7 +109,7 @@ class Match(MemoizationLeaf):
|
|||||||
return cases, default
|
return cases, default
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _create_case_var_with_var_data(cls, case_element):
|
def _create_case_var_with_var_data(cls, case_element: Any) -> Var:
|
||||||
"""Convert a case element into a Var.If the case
|
"""Convert a case element into a Var.If the case
|
||||||
is a Style type, we extract the var data and merge it with the
|
is a Style type, we extract the var data and merge it with the
|
||||||
newly created Var.
|
newly created Var.
|
||||||
@ -222,7 +222,7 @@ class Match(MemoizationLeaf):
|
|||||||
cond=match_cond_var,
|
cond=match_cond_var,
|
||||||
match_cases=match_cases,
|
match_cases=match_cases,
|
||||||
default=default,
|
default=default,
|
||||||
children=[case[-1] for case in match_cases] + [default], # type: ignore
|
children=[case[-1] for case in match_cases] + [default], # pyright: ignore [reportArgumentType]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -236,13 +236,13 @@ class Match(MemoizationLeaf):
|
|||||||
_js_expr=format.format_match(
|
_js_expr=format.format_match(
|
||||||
cond=str(match_cond_var),
|
cond=str(match_cond_var),
|
||||||
match_cases=match_cases,
|
match_cases=match_cases,
|
||||||
default=default, # type: ignore
|
default=default, # pyright: ignore [reportArgumentType]
|
||||||
),
|
),
|
||||||
_var_type=default._var_type, # type: ignore
|
_var_type=default._var_type, # pyright: ignore [reportAttributeAccessIssue,reportOptionalMemberAccess]
|
||||||
_var_data=VarData.merge(
|
_var_data=VarData.merge(
|
||||||
match_cond_var._get_all_var_data(),
|
match_cond_var._get_all_var_data(),
|
||||||
*[el._get_all_var_data() for case in match_cases for el in case],
|
*[el._get_all_var_data() for case in match_cases for el in case],
|
||||||
default._get_all_var_data(), # type: ignore
|
default._get_all_var_data(), # pyright: ignore [reportAttributeAccessIssue, reportOptionalMemberAccess]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ class Upload(MemoizationLeaf):
|
|||||||
on_drop = upload_props["on_drop"]
|
on_drop = upload_props["on_drop"]
|
||||||
if isinstance(on_drop, Callable):
|
if isinstance(on_drop, Callable):
|
||||||
# Call the lambda to get the event chain.
|
# Call the lambda to get the event chain.
|
||||||
on_drop = call_event_fn(on_drop, _on_drop_spec) # type: ignore
|
on_drop = call_event_fn(on_drop, _on_drop_spec)
|
||||||
if isinstance(on_drop, EventSpec):
|
if isinstance(on_drop, EventSpec):
|
||||||
# Update the provided args for direct use with on_drop.
|
# Update the provided args for direct use with on_drop.
|
||||||
on_drop = on_drop.with_args(
|
on_drop = on_drop.with_args(
|
||||||
|
@ -449,7 +449,7 @@ class CodeBlock(Component, MarkdownComponentMap):
|
|||||||
|
|
||||||
if can_copy:
|
if can_copy:
|
||||||
code = children[0]
|
code = children[0]
|
||||||
copy_button = ( # type: ignore
|
copy_button = (
|
||||||
copy_button
|
copy_button
|
||||||
if copy_button is not None
|
if copy_button is not None
|
||||||
else Button.create(
|
else Button.create(
|
||||||
|
@ -165,7 +165,7 @@ class DataEditor(NoSSRComponent):
|
|||||||
|
|
||||||
tag = "DataEditor"
|
tag = "DataEditor"
|
||||||
is_default = True
|
is_default = True
|
||||||
library: str = "@glideapps/glide-data-grid@^6.0.3"
|
library: str | None = "@glideapps/glide-data-grid@^6.0.3"
|
||||||
lib_dependencies: List[str] = [
|
lib_dependencies: List[str] = [
|
||||||
"lodash@^4.17.21",
|
"lodash@^4.17.21",
|
||||||
"react-responsive-carousel@^3.2.7",
|
"react-responsive-carousel@^3.2.7",
|
||||||
@ -321,6 +321,8 @@ class DataEditor(NoSSRComponent):
|
|||||||
Returns:
|
Returns:
|
||||||
The import dict.
|
The import dict.
|
||||||
"""
|
"""
|
||||||
|
if self.library is None:
|
||||||
|
return {}
|
||||||
return {
|
return {
|
||||||
"": f"{format.format_library_name(self.library)}/dist/index.css",
|
"": f"{format.format_library_name(self.library)}/dist/index.css",
|
||||||
self.library: "GridCellKind",
|
self.library: "GridCellKind",
|
||||||
@ -343,7 +345,7 @@ class DataEditor(NoSSRComponent):
|
|||||||
data_callback = self.get_cell_content._js_expr
|
data_callback = self.get_cell_content._js_expr
|
||||||
else:
|
else:
|
||||||
data_callback = f"getData_{editor_id}"
|
data_callback = f"getData_{editor_id}"
|
||||||
self.get_cell_content = Var(_js_expr=data_callback) # type: ignore
|
self.get_cell_content = Var(_js_expr=data_callback)
|
||||||
|
|
||||||
code = [f"function {data_callback}([col, row])" "{"]
|
code = [f"function {data_callback}([col, row])" "{"]
|
||||||
|
|
||||||
|
@ -15,10 +15,8 @@ def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "whi
|
|||||||
The Reflex logo SVG.
|
The Reflex logo SVG.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def logo_path(d):
|
def logo_path(d: str):
|
||||||
return rx.el.svg.path(
|
return rx.el.svg.path(d=d)
|
||||||
d=d,
|
|
||||||
)
|
|
||||||
|
|
||||||
paths = [
|
paths = [
|
||||||
"M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z",
|
"M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z",
|
||||||
|
@ -602,7 +602,7 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
|
|||||||
|
|
||||||
transformer_styles = {}
|
transformer_styles = {}
|
||||||
# Collect styles from transformers and wrapper
|
# Collect styles from transformers and wrapper
|
||||||
for transformer in code_block.transformers._var_value: # type: ignore
|
for transformer in code_block.transformers._var_value: # pyright: ignore [reportAttributeAccessIssue]
|
||||||
if isinstance(transformer, ShikiBaseTransformers) and transformer.style:
|
if isinstance(transformer, ShikiBaseTransformers) and transformer.style:
|
||||||
transformer_styles.update(transformer.style)
|
transformer_styles.update(transformer.style)
|
||||||
transformer_styles.update(code_wrapper_props.pop("style", {}))
|
transformer_styles.update(code_wrapper_props.pop("style", {}))
|
||||||
@ -653,8 +653,9 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"the function names should be str names of functions in the specified transformer: {library!r}"
|
f"the function names should be str names of functions in the specified transformer: {library!r}"
|
||||||
)
|
)
|
||||||
return ShikiBaseTransformers( # type: ignore
|
return ShikiBaseTransformers(
|
||||||
library=library, fns=[FunctionStringVar.create(fn) for fn in fns]
|
library=library,
|
||||||
|
fns=[FunctionStringVar.create(fn) for fn in fns], # pyright: ignore [reportCallIssue]
|
||||||
)
|
)
|
||||||
|
|
||||||
def _render(self, props: dict[str, Any] | None = None):
|
def _render(self, props: dict[str, Any] | None = None):
|
||||||
@ -757,13 +758,13 @@ class ShikiHighLevelCodeBlock(ShikiCodeBlock):
|
|||||||
|
|
||||||
if can_copy:
|
if can_copy:
|
||||||
code = children[0]
|
code = children[0]
|
||||||
copy_button = ( # type: ignore
|
copy_button = (
|
||||||
copy_button
|
copy_button
|
||||||
if copy_button is not None
|
if copy_button is not None
|
||||||
else Button.create(
|
else Button.create(
|
||||||
Icon.create(tag="copy", size=16, color=color("gray", 11)),
|
Icon.create(tag="copy", size=16, color=color("gray", 11)),
|
||||||
on_click=[
|
on_click=[
|
||||||
set_clipboard(cls._strip_transformer_triggers(code)), # type: ignore
|
set_clipboard(cls._strip_transformer_triggers(code)),
|
||||||
copy_script(),
|
copy_script(),
|
||||||
],
|
],
|
||||||
style=Style(
|
style=Style(
|
||||||
|
@ -48,4 +48,4 @@ PROP_TO_ELEMENTS = {
|
|||||||
ELEMENT_TO_PROPS = defaultdict(list)
|
ELEMENT_TO_PROPS = defaultdict(list)
|
||||||
for prop, elements in PROP_TO_ELEMENTS.items():
|
for prop, elements in PROP_TO_ELEMENTS.items():
|
||||||
for el in elements:
|
for el in elements:
|
||||||
ELEMENT_TO_PROPS[el].append(prop) # type: ignore
|
ELEMENT_TO_PROPS[el].append(prop)
|
||||||
|
@ -6,7 +6,7 @@ from reflex.components.component import Component
|
|||||||
class Element(Component):
|
class Element(Component):
|
||||||
"""The base class for all raw HTML elements."""
|
"""The base class for all raw HTML elements."""
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other: object):
|
||||||
"""Two elements are equal if they have the same tag.
|
"""Two elements are equal if they have the same tag.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -153,7 +153,7 @@ class Form(BaseHTML):
|
|||||||
target: Var[Union[str, int, bool]]
|
target: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
# If true, the form will be cleared after submit.
|
# If true, the form will be cleared after submit.
|
||||||
reset_on_submit: Var[bool] = False # type: ignore
|
reset_on_submit: Var[bool] = Var.create(False)
|
||||||
|
|
||||||
# The name used to make this form's submit handler function unique.
|
# The name used to make this form's submit handler function unique.
|
||||||
handle_submit_unique_name: Var[str]
|
handle_submit_unique_name: Var[str]
|
||||||
@ -405,7 +405,7 @@ class Input(BaseHTML):
|
|||||||
(value_var := Var.create(value))._var_type
|
(value_var := Var.create(value))._var_type
|
||||||
):
|
):
|
||||||
props["value"] = ternary_operation(
|
props["value"] = ternary_operation(
|
||||||
(value_var != Var.create(None)) # pyright: ignore [reportGeneralTypeIssues]
|
(value_var != Var.create(None)) # pyright: ignore [reportArgumentType]
|
||||||
& (value_var != Var(_js_expr="undefined")),
|
& (value_var != Var(_js_expr="undefined")),
|
||||||
value,
|
value,
|
||||||
Var.create(""),
|
Var.create(""),
|
||||||
|
@ -8,7 +8,7 @@ from functools import lru_cache
|
|||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from typing import Any, Callable, Dict, Sequence, Union
|
from typing import Any, Callable, Dict, Sequence, Union
|
||||||
|
|
||||||
from reflex.components.component import Component, CustomComponent
|
from reflex.components.component import BaseComponent, Component, CustomComponent
|
||||||
from reflex.components.tags.tag import Tag
|
from reflex.components.tags.tag import Tag
|
||||||
from reflex.utils import types
|
from reflex.utils import types
|
||||||
from reflex.utils.imports import ImportDict, ImportVar
|
from reflex.utils.imports import ImportDict, ImportVar
|
||||||
@ -65,8 +65,8 @@ def get_base_component_map() -> dict[str, Callable]:
|
|||||||
"h5": lambda value: Heading.create(value, as_="h5", size="2", margin_y="0.5em"),
|
"h5": lambda value: Heading.create(value, as_="h5", size="2", margin_y="0.5em"),
|
||||||
"h6": lambda value: Heading.create(value, as_="h6", size="1", margin_y="0.5em"),
|
"h6": lambda value: Heading.create(value, as_="h6", size="1", margin_y="0.5em"),
|
||||||
"p": lambda value: Text.create(value, margin_y="1em"),
|
"p": lambda value: Text.create(value, margin_y="1em"),
|
||||||
"ul": lambda value: UnorderedList.create(value, margin_y="1em"), # type: ignore
|
"ul": lambda value: UnorderedList.create(value, margin_y="1em"),
|
||||||
"ol": lambda value: OrderedList.create(value, margin_y="1em"), # type: ignore
|
"ol": lambda value: OrderedList.create(value, margin_y="1em"),
|
||||||
"li": lambda value: ListItem.create(value, margin_y="0.5em"),
|
"li": lambda value: ListItem.create(value, margin_y="0.5em"),
|
||||||
"a": lambda value: Link.create(value),
|
"a": lambda value: Link.create(value),
|
||||||
"code": lambda value: Code.create(value),
|
"code": lambda value: Code.create(value),
|
||||||
@ -236,7 +236,7 @@ class Markdown(Component):
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
*[
|
*[
|
||||||
component(_MOCK_ARG)._get_all_imports() # type: ignore
|
component(_MOCK_ARG)._get_all_imports()
|
||||||
for component in self.component_map.values()
|
for component in self.component_map.values()
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
@ -327,7 +327,7 @@ const {_LANGUAGE!s} = match ? match[1] : '';
|
|||||||
if tag != "codeblock"
|
if tag != "codeblock"
|
||||||
# For codeblock, the mapping for some cases returns an array of elements. Let's join them into a string.
|
# For codeblock, the mapping for some cases returns an array of elements. Let's join them into a string.
|
||||||
else ternary_operation(
|
else ternary_operation(
|
||||||
ARRAY_ISARRAY.call(_CHILDREN), # type: ignore
|
ARRAY_ISARRAY.call(_CHILDREN), # pyright: ignore [reportArgumentType]
|
||||||
_CHILDREN.to(list).join("\n"),
|
_CHILDREN.to(list).join("\n"),
|
||||||
_CHILDREN,
|
_CHILDREN,
|
||||||
).to(str)
|
).to(str)
|
||||||
@ -379,7 +379,9 @@ const {_LANGUAGE!s} = match ? match[1] : '';
|
|||||||
# fallback to the default fn Var creation if the component is not a MarkdownComponentMap.
|
# fallback to the default fn Var creation if the component is not a MarkdownComponentMap.
|
||||||
return MarkdownComponentMap.create_map_fn_var(fn_body=formatted_component)
|
return MarkdownComponentMap.create_map_fn_var(fn_body=formatted_component)
|
||||||
|
|
||||||
def _get_map_fn_custom_code_from_children(self, component) -> list[str]:
|
def _get_map_fn_custom_code_from_children(
|
||||||
|
self, component: BaseComponent
|
||||||
|
) -> list[str]:
|
||||||
"""Recursively get markdown custom code from children components.
|
"""Recursively get markdown custom code from children components.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -409,7 +411,7 @@ const {_LANGUAGE!s} = match ? match[1] : '';
|
|||||||
return custom_code_list
|
return custom_code_list
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _component_map_hash(component_map) -> str:
|
def _component_map_hash(component_map: dict) -> str:
|
||||||
inp = str(
|
inp = str(
|
||||||
{tag: component(_MOCK_ARG) for tag, component in component_map.items()}
|
{tag: component(_MOCK_ARG) for tag, component in component_map.items()}
|
||||||
).encode()
|
).encode()
|
||||||
@ -425,7 +427,7 @@ const {_LANGUAGE!s} = match ? match[1] : '';
|
|||||||
for _component in self.component_map.values():
|
for _component in self.component_map.values():
|
||||||
comp = _component(_MOCK_ARG)
|
comp = _component(_MOCK_ARG)
|
||||||
hooks.update(comp._get_all_hooks())
|
hooks.update(comp._get_all_hooks())
|
||||||
formatted_hooks = MACROS.module.renderHooks(hooks) # type: ignore
|
formatted_hooks = MACROS.module.renderHooks(hooks) # pyright: ignore [reportAttributeAccessIssue]
|
||||||
return f"""
|
return f"""
|
||||||
function {self._get_component_map_name()} () {{
|
function {self._get_component_map_name()} () {{
|
||||||
{formatted_hooks}
|
{formatted_hooks}
|
||||||
|
@ -28,9 +28,9 @@ class MomentDelta:
|
|||||||
class Moment(NoSSRComponent):
|
class Moment(NoSSRComponent):
|
||||||
"""The Moment component."""
|
"""The Moment component."""
|
||||||
|
|
||||||
tag: str = "Moment"
|
tag: str | None = "Moment"
|
||||||
is_default = True
|
is_default = True
|
||||||
library: str = "react-moment"
|
library: str | None = "react-moment"
|
||||||
lib_dependencies: List[str] = ["moment"]
|
lib_dependencies: List[str] = ["moment"]
|
||||||
|
|
||||||
# How often the date update (how often time update / 0 to disable).
|
# How often the date update (how often time update / 0 to disable).
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""Image component from next/image."""
|
"""Image component from next/image."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Literal, Optional, Union
|
from typing import Any, Literal, Optional, Union
|
||||||
|
|
||||||
from reflex.event import EventHandler, no_args_event_spec
|
from reflex.event import EventHandler, no_args_event_spec
|
||||||
@ -93,7 +95,7 @@ class Image(NextComponent):
|
|||||||
|
|
||||||
style = props.get("style", {})
|
style = props.get("style", {})
|
||||||
|
|
||||||
def check_prop_type(prop_name, prop_value):
|
def check_prop_type(prop_name: str, prop_value: int | str | None):
|
||||||
if types.check_prop_in_allowed_types(prop_value, allowed_types=[int]):
|
if types.check_prop_in_allowed_types(prop_value, allowed_types=[int]):
|
||||||
props[prop_name] = prop_value
|
props[prop_name] = prop_value
|
||||||
|
|
||||||
|
@ -17,4 +17,4 @@ class NextLink(Component):
|
|||||||
href: Var[str]
|
href: Var[str]
|
||||||
|
|
||||||
# Whether to pass the href prop to the child.
|
# Whether to pass the href prop to the child.
|
||||||
pass_href: Var[bool] = True # type: ignore
|
pass_href: Var[bool] = Var.create(True)
|
||||||
|
@ -18,8 +18,8 @@ try:
|
|||||||
Template = layout.Template
|
Template = layout.Template
|
||||||
except ImportError:
|
except ImportError:
|
||||||
console.warn("Plotly is not installed. Please run `pip install plotly`.")
|
console.warn("Plotly is not installed. Please run `pip install plotly`.")
|
||||||
Figure = Any # type: ignore
|
Figure = Any
|
||||||
Template = Any # type: ignore
|
Template = Any
|
||||||
|
|
||||||
|
|
||||||
def _event_points_data_signature(e0: Var) -> Tuple[Var[List[Point]]]:
|
def _event_points_data_signature(e0: Var) -> Tuple[Var[List[Point]]]:
|
||||||
@ -102,13 +102,13 @@ class Plotly(NoSSRComponent):
|
|||||||
is_default = True
|
is_default = True
|
||||||
|
|
||||||
# The figure to display. This can be a plotly figure or a plotly data json.
|
# The figure to display. This can be a plotly figure or a plotly data json.
|
||||||
data: Var[Figure] # type: ignore
|
data: Var[Figure] # pyright: ignore [reportInvalidTypeForm]
|
||||||
|
|
||||||
# The layout of the graph.
|
# The layout of the graph.
|
||||||
layout: Var[Dict]
|
layout: Var[Dict]
|
||||||
|
|
||||||
# The template for visual appearance of the graph.
|
# The template for visual appearance of the graph.
|
||||||
template: Var[Template] # type: ignore
|
template: Var[Template] # pyright: ignore [reportInvalidTypeForm]
|
||||||
|
|
||||||
# The config of the graph.
|
# The config of the graph.
|
||||||
config: Var[Dict]
|
config: Var[Dict]
|
||||||
|
@ -48,7 +48,7 @@ class PropsBase(Base):
|
|||||||
class NoExtrasAllowedProps(Base):
|
class NoExtrasAllowedProps(Base):
|
||||||
"""A class that holds props to be passed or applied to a component with no extra props allowed."""
|
"""A class that holds props to be passed or applied to a component with no extra props allowed."""
|
||||||
|
|
||||||
def __init__(self, component_name=None, **kwargs):
|
def __init__(self, component_name: str | None = None, **kwargs):
|
||||||
"""Initialize the props.
|
"""Initialize the props.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -62,13 +62,13 @@ class NoExtrasAllowedProps(Base):
|
|||||||
try:
|
try:
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
invalid_fields = ", ".join([error["loc"][0] for error in e.errors()]) # type: ignore
|
invalid_fields = ", ".join([error["loc"][0] for error in e.errors()]) # pyright: ignore [reportCallIssue, reportArgumentType]
|
||||||
supported_props_str = ", ".join(f'"{field}"' for field in self.get_fields())
|
supported_props_str = ", ".join(f'"{field}"' for field in self.get_fields())
|
||||||
raise InvalidPropValueError(
|
raise InvalidPropValueError(
|
||||||
f"Invalid prop(s) {invalid_fields} for {component_name!r}. Supported props are {supported_props_str}"
|
f"Invalid prop(s) {invalid_fields} for {component_name!r}. Supported props are {supported_props_str}"
|
||||||
) from None
|
) from None
|
||||||
|
|
||||||
class Config:
|
class Config: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
"""Pydantic config."""
|
"""Pydantic config."""
|
||||||
|
|
||||||
arbitrary_types_allowed = True
|
arbitrary_types_allowed = True
|
||||||
|
@ -55,7 +55,7 @@ from .themes.layout.container import container as container
|
|||||||
from .themes.layout.flex import flex as flex
|
from .themes.layout.flex import flex as flex
|
||||||
from .themes.layout.grid import grid as grid
|
from .themes.layout.grid import grid as grid
|
||||||
from .themes.layout.list import list_item as list_item
|
from .themes.layout.list import list_item as list_item
|
||||||
from .themes.layout.list import list_ns as list # noqa
|
from .themes.layout.list import list_ns as list # noqa: F401
|
||||||
from .themes.layout.list import ordered_list as ordered_list
|
from .themes.layout.list import ordered_list as ordered_list
|
||||||
from .themes.layout.list import unordered_list as unordered_list
|
from .themes.layout.list import unordered_list as unordered_list
|
||||||
from .themes.layout.section import section as section
|
from .themes.layout.section import section as section
|
||||||
|
@ -196,8 +196,9 @@ class AccordionItem(AccordionComponent):
|
|||||||
|
|
||||||
# The header of the accordion item.
|
# The header of the accordion item.
|
||||||
header: Var[Union[Component, str]]
|
header: Var[Union[Component, str]]
|
||||||
|
|
||||||
# The content of the accordion item.
|
# The content of the accordion item.
|
||||||
content: Var[Union[Component, str]] = Var.create(None)
|
content: Var[Union[Component, str, None]] = Var.create(None)
|
||||||
|
|
||||||
_valid_children: List[str] = [
|
_valid_children: List[str] = [
|
||||||
"AccordionHeader",
|
"AccordionHeader",
|
||||||
|
@ -308,7 +308,9 @@ class AccordionItem(AccordionComponent):
|
|||||||
value: Optional[Union[Var[str], str]] = None,
|
value: Optional[Union[Var[str], str]] = None,
|
||||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||||
header: Optional[Union[Component, Var[Union[Component, str]], str]] = None,
|
header: Optional[Union[Component, Var[Union[Component, str]], str]] = None,
|
||||||
content: Optional[Union[Component, Var[Union[Component, str]], str]] = None,
|
content: Optional[
|
||||||
|
Union[Component, Var[Optional[Union[Component, str]]], str]
|
||||||
|
] = None,
|
||||||
color_scheme: Optional[
|
color_scheme: Optional[
|
||||||
Union[
|
Union[
|
||||||
Literal[
|
Literal[
|
||||||
|
@ -83,7 +83,7 @@ class DrawerTrigger(DrawerComponent):
|
|||||||
alias = "Vaul" + tag
|
alias = "Vaul" + tag
|
||||||
|
|
||||||
# Defaults to true, if the first child acts as the trigger.
|
# Defaults to true, if the first child acts as the trigger.
|
||||||
as_child: Var[bool] = True # type: ignore
|
as_child: Var[bool] = Var.create(True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children: Any, **props: Any) -> Component:
|
def create(cls, *children: Any, **props: Any) -> Component:
|
||||||
|
@ -83,7 +83,7 @@ class ProgressIndicator(ProgressComponent):
|
|||||||
"&[data_state='loading']": {
|
"&[data_state='loading']": {
|
||||||
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
||||||
},
|
},
|
||||||
"transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))", # type: ignore
|
"transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))",
|
||||||
"boxShadow": "inset 0 0 0 1px var(--gray-a5)",
|
"boxShadow": "inset 0 0 0 1px var(--gray-a5)",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ def on_value_event_spec(
|
|||||||
Returns:
|
Returns:
|
||||||
The event handler spec.
|
The event handler spec.
|
||||||
"""
|
"""
|
||||||
return (value,) # type: ignore
|
return (value,)
|
||||||
|
|
||||||
|
|
||||||
class SliderRoot(SliderComponent):
|
class SliderRoot(SliderComponent):
|
||||||
|
@ -17,7 +17,7 @@ rx.text(
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Dict, List, Literal, Optional, Union, get_args
|
from typing import Any, Dict, List, Literal, Optional, Union, get_args
|
||||||
|
|
||||||
from reflex.components.component import BaseComponent
|
from reflex.components.component import BaseComponent
|
||||||
from reflex.components.core.cond import Cond, color_mode_cond, cond
|
from reflex.components.core.cond import Cond, color_mode_cond, cond
|
||||||
@ -78,17 +78,19 @@ position_map: Dict[str, List[str]] = {
|
|||||||
|
|
||||||
|
|
||||||
# needed to inverse contains for find
|
# needed to inverse contains for find
|
||||||
def _find(const: List[str], var):
|
def _find(const: List[str], var: Any):
|
||||||
return LiteralArrayVar.create(const).contains(var)
|
return LiteralArrayVar.create(const).contains(var)
|
||||||
|
|
||||||
|
|
||||||
def _set_var_default(props, position, prop, default1, default2=""):
|
def _set_var_default(
|
||||||
|
props: dict, position: Any, prop: str, default1: str, default2: str = ""
|
||||||
|
):
|
||||||
props.setdefault(
|
props.setdefault(
|
||||||
prop, cond(_find(position_map[prop], position), default1, default2)
|
prop, cond(_find(position_map[prop], position), default1, default2)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _set_static_default(props, position, prop, default):
|
def _set_static_default(props: dict, position: Any, prop: str, default: str):
|
||||||
if prop in position:
|
if prop in position:
|
||||||
props.setdefault(prop, default)
|
props.setdefault(prop, default)
|
||||||
|
|
||||||
@ -115,12 +117,12 @@ class ColorModeIconButton(IconButton):
|
|||||||
Returns:
|
Returns:
|
||||||
The button component.
|
The button component.
|
||||||
"""
|
"""
|
||||||
position = props.pop("position", None)
|
position: str | Var = props.pop("position", None)
|
||||||
allow_system = props.pop("allow_system", False)
|
allow_system = props.pop("allow_system", False)
|
||||||
|
|
||||||
# position is used to set nice defaults for positioning the icon button
|
# position is used to set nice defaults for positioning the icon button
|
||||||
if isinstance(position, Var):
|
if isinstance(position, Var):
|
||||||
_set_var_default(props, position, "position", "fixed", position) # type: ignore
|
_set_var_default(props, position, "position", "fixed", position) # pyright: ignore [reportArgumentType]
|
||||||
_set_var_default(props, position, "bottom", "2rem")
|
_set_var_default(props, position, "bottom", "2rem")
|
||||||
_set_var_default(props, position, "top", "2rem")
|
_set_var_default(props, position, "top", "2rem")
|
||||||
_set_var_default(props, position, "left", "2rem")
|
_set_var_default(props, position, "left", "2rem")
|
||||||
@ -142,7 +144,7 @@ class ColorModeIconButton(IconButton):
|
|||||||
|
|
||||||
if allow_system:
|
if allow_system:
|
||||||
|
|
||||||
def color_mode_item(_color_mode):
|
def color_mode_item(_color_mode: str):
|
||||||
return dropdown_menu.item(
|
return dropdown_menu.item(
|
||||||
_color_mode.title(), on_click=set_color_mode(_color_mode)
|
_color_mode.title(), on_click=set_color_mode(_color_mode)
|
||||||
)
|
)
|
||||||
|
@ -85,6 +85,8 @@ class RadioCardsItem(RadixThemesComponent):
|
|||||||
# When true, indicates that the user must check the radio item before the owning form can be submitted.
|
# When true, indicates that the user must check the radio item before the owning form can be submitted.
|
||||||
required: Var[bool]
|
required: Var[bool]
|
||||||
|
|
||||||
|
_valid_parents: list[str] = ["RadioCardsRoot"]
|
||||||
|
|
||||||
|
|
||||||
class RadioCards(SimpleNamespace):
|
class RadioCards(SimpleNamespace):
|
||||||
"""RadioCards components namespace."""
|
"""RadioCards components namespace."""
|
||||||
|
@ -155,7 +155,7 @@ class HighLevelRadioGroup(RadixThemesComponent):
|
|||||||
if isinstance(default_value, str) or (
|
if isinstance(default_value, str) or (
|
||||||
isinstance(default_value, Var) and default_value._var_type is str
|
isinstance(default_value, Var) and default_value._var_type is str
|
||||||
):
|
):
|
||||||
default_value = LiteralVar.create(default_value) # type: ignore
|
default_value = LiteralVar.create(default_value)
|
||||||
else:
|
else:
|
||||||
default_value = LiteralVar.create(default_value).to_string()
|
default_value = LiteralVar.create(default_value).to_string()
|
||||||
|
|
||||||
|
@ -96,5 +96,17 @@ class TextArea(RadixThemesComponent, elements.Textarea):
|
|||||||
return DebounceInput.create(super().create(*children, **props))
|
return DebounceInput.create(super().create(*children, **props))
|
||||||
return super().create(*children, **props)
|
return super().create(*children, **props)
|
||||||
|
|
||||||
|
def add_style(self):
|
||||||
|
"""Add the style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
added_style: dict[str, dict] = {}
|
||||||
|
added_style.setdefault("& textarea", {})
|
||||||
|
if "padding" in self.style:
|
||||||
|
added_style["& textarea"]["padding"] = self.style.pop("padding")
|
||||||
|
return added_style
|
||||||
|
|
||||||
|
|
||||||
text_area = TextArea.create
|
text_area = TextArea.create
|
||||||
|
@ -268,4 +268,6 @@ class TextArea(RadixThemesComponent, elements.Textarea):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
def add_style(self): ...
|
||||||
|
|
||||||
text_area = TextArea.create
|
text_area = TextArea.create
|
||||||
|
@ -105,7 +105,7 @@ class TextFieldRoot(elements.Input, RadixThemesComponent):
|
|||||||
(value_var := Var.create(value))._var_type
|
(value_var := Var.create(value))._var_type
|
||||||
):
|
):
|
||||||
props["value"] = ternary_operation(
|
props["value"] = ternary_operation(
|
||||||
(value_var != Var.create(None)) # pyright: ignore [reportGeneralTypeIssues]
|
(value_var != Var.create(None)) # pyright: ignore [reportArgumentType]
|
||||||
& (value_var != Var(_js_expr="undefined")),
|
& (value_var != Var(_js_expr="undefined")),
|
||||||
value,
|
value,
|
||||||
Var.create(""),
|
Var.create(""),
|
||||||
|
@ -9,7 +9,7 @@ from .container import container as container
|
|||||||
from .flex import flex as flex
|
from .flex import flex as flex
|
||||||
from .grid import grid as grid
|
from .grid import grid as grid
|
||||||
from .list import list_item as list_item
|
from .list import list_item as list_item
|
||||||
from .list import list_ns as list # noqa
|
from .list import list_ns as list # noqa: F401
|
||||||
from .list import ordered_list as ordered_list
|
from .list import ordered_list as ordered_list
|
||||||
from .list import unordered_list as unordered_list
|
from .list import unordered_list as unordered_list
|
||||||
from .section import section as section
|
from .section import section as section
|
||||||
|
@ -72,7 +72,7 @@ class BaseList(Component, MarkdownComponentMap):
|
|||||||
if isinstance(items, Var):
|
if isinstance(items, Var):
|
||||||
children = [Foreach.create(items, ListItem.create)]
|
children = [Foreach.create(items, ListItem.create)]
|
||||||
else:
|
else:
|
||||||
children = [ListItem.create(item) for item in items] # type: ignore
|
children = [ListItem.create(item) for item in items]
|
||||||
props["direction"] = "column"
|
props["direction"] = "column"
|
||||||
style = props.setdefault("style", {})
|
style = props.setdefault("style", {})
|
||||||
style["list_style_type"] = list_style_type
|
style["list_style_type"] = list_style_type
|
||||||
@ -189,7 +189,7 @@ ordered_list = list_ns.ordered
|
|||||||
unordered_list = list_ns.unordered
|
unordered_list = list_ns.unordered
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name: Any):
|
||||||
# special case for when accessing list to avoid shadowing
|
# special case for when accessing list to avoid shadowing
|
||||||
# python's built in list object.
|
# python's built in list object.
|
||||||
if name == "list":
|
if name == "list":
|
||||||
|
@ -49,14 +49,14 @@ class VStack(Stack):
|
|||||||
"""A vertical stack component."""
|
"""A vertical stack component."""
|
||||||
|
|
||||||
# The direction of the stack.
|
# The direction of the stack.
|
||||||
direction: Var[LiteralFlexDirection] = "column" # type: ignore
|
direction: Var[LiteralFlexDirection] = Var.create("column")
|
||||||
|
|
||||||
|
|
||||||
class HStack(Stack):
|
class HStack(Stack):
|
||||||
"""A horizontal stack component."""
|
"""A horizontal stack component."""
|
||||||
|
|
||||||
# The direction of the stack.
|
# The direction of the stack.
|
||||||
direction: Var[LiteralFlexDirection] = "row" # type: ignore
|
direction: Var[LiteralFlexDirection] = Var.create("row")
|
||||||
|
|
||||||
|
|
||||||
stack = Stack.create
|
stack = Stack.create
|
||||||
|
@ -60,7 +60,7 @@ class Link(RadixThemesComponent, A, MemoizationLeaf, MarkdownComponentMap):
|
|||||||
Returns:
|
Returns:
|
||||||
The import dict.
|
The import dict.
|
||||||
"""
|
"""
|
||||||
return next_link._get_imports() # type: ignore
|
return next_link._get_imports() # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props) -> Component:
|
def create(cls, *children, **props) -> Component:
|
||||||
|
@ -47,7 +47,7 @@ class Text(elements.Span, RadixThemesComponent, MarkdownComponentMap):
|
|||||||
as_child: Var[bool]
|
as_child: Var[bool]
|
||||||
|
|
||||||
# Change the default rendered element into a semantically appropriate alternative (cannot be used with asChild)
|
# Change the default rendered element into a semantically appropriate alternative (cannot be used with asChild)
|
||||||
as_: Var[LiteralType] = "p" # type: ignore
|
as_: Var[LiteralType] = Var.create("p")
|
||||||
|
|
||||||
# Text size: "1" - "9"
|
# Text size: "1" - "9"
|
||||||
size: Var[Responsive[LiteralTextSize]]
|
size: Var[Responsive[LiteralTextSize]]
|
||||||
@ -71,7 +71,7 @@ class Text(elements.Span, RadixThemesComponent, MarkdownComponentMap):
|
|||||||
class Span(Text):
|
class Span(Text):
|
||||||
"""A variant of text rendering as <span> element."""
|
"""A variant of text rendering as <span> element."""
|
||||||
|
|
||||||
as_: Var[LiteralType] = "span" # type: ignore
|
as_: Var[LiteralType] = Var.create("span")
|
||||||
|
|
||||||
|
|
||||||
class Em(elements.Em, RadixThemesComponent):
|
class Em(elements.Em, RadixThemesComponent):
|
||||||
|
@ -39,7 +39,7 @@ class ReactPlayer(NoSSRComponent):
|
|||||||
loop: Var[bool]
|
loop: Var[bool]
|
||||||
|
|
||||||
# Set to true or false to display native player controls.
|
# Set to true or false to display native player controls.
|
||||||
controls: Var[bool] = True # type: ignore
|
controls: Var[bool] = Var.create(True)
|
||||||
|
|
||||||
# Set to true to show just the video thumbnail, which loads the full player on click
|
# Set to true to show just the video thumbnail, which loads the full player on click
|
||||||
light: Var[bool]
|
light: Var[bool]
|
||||||
|
@ -25,10 +25,10 @@ class ChartBase(RechartsCharts):
|
|||||||
"""A component that wraps a Recharts charts."""
|
"""A component that wraps a Recharts charts."""
|
||||||
|
|
||||||
# The width of chart container. String or Integer
|
# The width of chart container. String or Integer
|
||||||
width: Var[Union[str, int]] = "100%" # type: ignore
|
width: Var[Union[str, int]] = Var.create("100%")
|
||||||
|
|
||||||
# The height of chart container.
|
# The height of chart container.
|
||||||
height: Var[Union[str, int]] = "100%" # type: ignore
|
height: Var[Union[str, int]] = Var.create("100%")
|
||||||
|
|
||||||
# The customized event handler of click on the component in this chart
|
# The customized event handler of click on the component in this chart
|
||||||
on_click: EventHandler[no_args_event_spec]
|
on_click: EventHandler[no_args_event_spec]
|
||||||
@ -69,7 +69,7 @@ class ChartBase(RechartsCharts):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props) -> Component:
|
def create(cls, *children: Any, **props: Any) -> Component:
|
||||||
"""Create a chart component.
|
"""Create a chart component.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -84,21 +84,19 @@ class ChartBase(RechartsCharts):
|
|||||||
cls._ensure_valid_dimension("width", width)
|
cls._ensure_valid_dimension("width", width)
|
||||||
cls._ensure_valid_dimension("height", height)
|
cls._ensure_valid_dimension("height", height)
|
||||||
|
|
||||||
dim_props = {
|
|
||||||
"width": width if width is not None else "100%",
|
|
||||||
"height": height if height is not None else "100%",
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ensure that the min_height and min_width are set to prevent the chart from collapsing.
|
# Ensure that the min_height and min_width are set to prevent the chart from collapsing.
|
||||||
# We are using small values so that height and width can still be used over min_height and min_width.
|
# We are using small values so that height and width can still be used over min_height and min_width.
|
||||||
# Without this, sometimes the chart will not be visible. Causing confusion to the user.
|
# Without this, sometimes the chart will not be visible. Causing confusion to the user.
|
||||||
# With this, the user will see a small chart and can adjust the height and width and can figure out that the issue is with the size.
|
# With this, the user will see a small chart and can adjust the height and width and can figure out that the issue is with the size.
|
||||||
dim_props["min_height"] = props.pop("min_height", 10)
|
min_height = props.pop("min_height", 10)
|
||||||
dim_props["min_width"] = props.pop("min_width", 10)
|
min_width = props.pop("min_width", 10)
|
||||||
|
|
||||||
return ResponsiveContainer.create(
|
return ResponsiveContainer.create(
|
||||||
super().create(*children, **props),
|
super().create(*children, **props),
|
||||||
**dim_props, # type: ignore
|
width=width if width is not None else "100%",
|
||||||
|
height=height if height is not None else "100%",
|
||||||
|
min_width=min_width,
|
||||||
|
min_height=min_height,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -460,10 +458,10 @@ class Treemap(RechartsCharts):
|
|||||||
alias = "RechartsTreemap"
|
alias = "RechartsTreemap"
|
||||||
|
|
||||||
# The width of chart container. String or Integer. Default: "100%"
|
# The width of chart container. String or Integer. Default: "100%"
|
||||||
width: Var[Union[str, int]] = "100%" # type: ignore
|
width: Var[Union[str, int]] = Var.create("100%")
|
||||||
|
|
||||||
# The height of chart container. String or Integer. Default: "100%"
|
# The height of chart container. String or Integer. Default: "100%"
|
||||||
height: Var[Union[str, int]] = "100%" # type: ignore
|
height: Var[Union[str, int]] = Var.create("100%")
|
||||||
|
|
||||||
# data of treemap. Array
|
# data of treemap. Array
|
||||||
data: Var[List[Dict[str, Any]]]
|
data: Var[List[Dict[str, Any]]]
|
||||||
|
@ -64,7 +64,7 @@ class Pie(Recharts):
|
|||||||
legend_type: Var[LiteralLegendType]
|
legend_type: Var[LiteralLegendType]
|
||||||
|
|
||||||
# If false set, labels will not be drawn. If true set, labels will be drawn which have the props calculated internally. Default: False
|
# If false set, labels will not be drawn. If true set, labels will be drawn which have the props calculated internally. Default: False
|
||||||
label: Var[bool] = False # type: ignore
|
label: Var[bool] = Var.create(False)
|
||||||
|
|
||||||
# If false set, label lines will not be drawn. If true set, label lines will be drawn which have the props calculated internally. Default: False
|
# If false set, label lines will not be drawn. If true set, label lines will be drawn which have the props calculated internally. Default: False
|
||||||
label_line: Var[bool]
|
label_line: Var[bool]
|
||||||
|
@ -132,7 +132,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps):
|
|||||||
# Function that gets called when the toast disappears automatically after it's timeout (duration` prop).
|
# Function that gets called when the toast disappears automatically after it's timeout (duration` prop).
|
||||||
on_auto_close: Optional[Any]
|
on_auto_close: Optional[Any]
|
||||||
|
|
||||||
def dict(self, *args, **kwargs) -> dict[str, Any]:
|
def dict(self, *args: Any, **kwargs: Any) -> dict[str, Any]:
|
||||||
"""Convert the object to a dictionary.
|
"""Convert the object to a dictionary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -142,7 +142,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps):
|
|||||||
Returns:
|
Returns:
|
||||||
The object as a dictionary with ToastAction fields intact.
|
The object as a dictionary with ToastAction fields intact.
|
||||||
"""
|
"""
|
||||||
kwargs.setdefault("exclude_none", True) # type: ignore
|
kwargs.setdefault("exclude_none", True)
|
||||||
d = super().dict(*args, **kwargs)
|
d = super().dict(*args, **kwargs)
|
||||||
# Keep these fields as ToastAction so they can be serialized specially
|
# Keep these fields as ToastAction so they can be serialized specially
|
||||||
if "action" in d:
|
if "action" in d:
|
||||||
@ -167,7 +167,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps):
|
|||||||
class Toaster(Component):
|
class Toaster(Component):
|
||||||
"""A Toaster Component for displaying toast notifications."""
|
"""A Toaster Component for displaying toast notifications."""
|
||||||
|
|
||||||
library: str = "sonner@1.7.2"
|
library: str | None = "sonner@1.7.2"
|
||||||
|
|
||||||
tag = "Toaster"
|
tag = "Toaster"
|
||||||
|
|
||||||
@ -222,6 +222,8 @@ class Toaster(Component):
|
|||||||
Returns:
|
Returns:
|
||||||
The hooks for the toaster component.
|
The hooks for the toaster component.
|
||||||
"""
|
"""
|
||||||
|
if self.library is None:
|
||||||
|
return []
|
||||||
hook = Var(
|
hook = Var(
|
||||||
_js_expr=f"{toast_ref} = toast",
|
_js_expr=f"{toast_ref} = toast",
|
||||||
_var_data=VarData(
|
_var_data=VarData(
|
||||||
@ -266,7 +268,7 @@ class Toaster(Component):
|
|||||||
raise ValueError("Toast message or title or description must be provided.")
|
raise ValueError("Toast message or title or description must be provided.")
|
||||||
|
|
||||||
if props:
|
if props:
|
||||||
args = LiteralVar.create(ToastProps(component_name="rx.toast", **props)) # pyright: ignore [reportCallIssue, reportGeneralTypeIssues]
|
args = LiteralVar.create(ToastProps(component_name="rx.toast", **props)) # pyright: ignore [reportCallIssue]
|
||||||
toast = toast_command.call(message, args)
|
toast = toast_command.call(message, args)
|
||||||
else:
|
else:
|
||||||
toast = toast_command.call(message)
|
toast = toast_command.call(message)
|
||||||
@ -274,12 +276,12 @@ class Toaster(Component):
|
|||||||
return run_script(toast)
|
return run_script(toast)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_info(message: str | Var = "", **kwargs):
|
def toast_info(message: str | Var = "", **kwargs: Any):
|
||||||
"""Display an info toast message.
|
"""Display an info toast message.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The message to display.
|
message: The message to display.
|
||||||
kwargs: Additional toast props.
|
**kwargs: Additional toast props.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The toast event.
|
The toast event.
|
||||||
@ -287,12 +289,12 @@ class Toaster(Component):
|
|||||||
return Toaster.send_toast(message, level="info", **kwargs)
|
return Toaster.send_toast(message, level="info", **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_warning(message: str | Var = "", **kwargs):
|
def toast_warning(message: str | Var = "", **kwargs: Any):
|
||||||
"""Display a warning toast message.
|
"""Display a warning toast message.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The message to display.
|
message: The message to display.
|
||||||
kwargs: Additional toast props.
|
**kwargs: Additional toast props.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The toast event.
|
The toast event.
|
||||||
@ -300,12 +302,12 @@ class Toaster(Component):
|
|||||||
return Toaster.send_toast(message, level="warning", **kwargs)
|
return Toaster.send_toast(message, level="warning", **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_error(message: str | Var = "", **kwargs):
|
def toast_error(message: str | Var = "", **kwargs: Any):
|
||||||
"""Display an error toast message.
|
"""Display an error toast message.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The message to display.
|
message: The message to display.
|
||||||
kwargs: Additional toast props.
|
**kwargs: Additional toast props.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The toast event.
|
The toast event.
|
||||||
@ -313,12 +315,12 @@ class Toaster(Component):
|
|||||||
return Toaster.send_toast(message, level="error", **kwargs)
|
return Toaster.send_toast(message, level="error", **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_success(message: str | Var = "", **kwargs):
|
def toast_success(message: str | Var = "", **kwargs: Any):
|
||||||
"""Display a success toast message.
|
"""Display a success toast message.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The message to display.
|
message: The message to display.
|
||||||
kwargs: Additional toast props.
|
**kwargs: Additional toast props.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The toast event.
|
The toast event.
|
||||||
@ -350,7 +352,7 @@ class Toaster(Component):
|
|||||||
return run_script(dismiss_action)
|
return run_script(dismiss_action)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props) -> Component:
|
def create(cls, *children: Any, **props: Any) -> Component:
|
||||||
"""Create a toaster component.
|
"""Create a toaster component.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -51,7 +51,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps):
|
|||||||
on_dismiss: Optional[Any]
|
on_dismiss: Optional[Any]
|
||||||
on_auto_close: Optional[Any]
|
on_auto_close: Optional[Any]
|
||||||
|
|
||||||
def dict(self, *args, **kwargs) -> dict[str, Any]: ...
|
def dict(self, *args: Any, **kwargs: Any) -> dict[str, Any]: ...
|
||||||
|
|
||||||
class Toaster(Component):
|
class Toaster(Component):
|
||||||
is_used: ClassVar[bool] = False
|
is_used: ClassVar[bool] = False
|
||||||
@ -62,13 +62,13 @@ class Toaster(Component):
|
|||||||
message: str | Var = "", level: str | None = None, **props
|
message: str | Var = "", level: str | None = None, **props
|
||||||
) -> EventSpec: ...
|
) -> EventSpec: ...
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_info(message: str | Var = "", **kwargs): ...
|
def toast_info(message: str | Var = "", **kwargs: Any): ...
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_warning(message: str | Var = "", **kwargs): ...
|
def toast_warning(message: str | Var = "", **kwargs: Any): ...
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_error(message: str | Var = "", **kwargs): ...
|
def toast_error(message: str | Var = "", **kwargs: Any): ...
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_success(message: str | Var = "", **kwargs): ...
|
def toast_success(message: str | Var = "", **kwargs: Any): ...
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def toast_dismiss(id: Var | str | None = None): ...
|
def toast_dismiss(id: Var | str | None = None): ...
|
||||||
@overload
|
@overload
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import enum
|
import enum
|
||||||
from typing import Dict, List, Literal, Optional, Tuple, Union
|
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
||||||
|
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
from reflex.components.component import Component, NoSSRComponent
|
from reflex.components.component import Component, NoSSRComponent
|
||||||
@ -115,7 +115,7 @@ class Editor(NoSSRComponent):
|
|||||||
# Alternatively to a string, a dict of your language can be passed to this prop.
|
# Alternatively to a string, a dict of your language can be passed to this prop.
|
||||||
# Please refer to the library docs for this.
|
# Please refer to the library docs for this.
|
||||||
# options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" |
|
# options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" |
|
||||||
# "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it"
|
# "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it"
|
||||||
# default: "en".
|
# default: "en".
|
||||||
lang: Var[
|
lang: Var[
|
||||||
Union[
|
Union[
|
||||||
@ -244,11 +244,13 @@ class Editor(NoSSRComponent):
|
|||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, set_options: Optional[EditorOptions] = None, **props) -> Component:
|
def create(
|
||||||
|
cls, set_options: Optional[EditorOptions] = None, **props: Any
|
||||||
|
) -> Component:
|
||||||
"""Create an instance of Editor. No children allowed.
|
"""Create an instance of Editor. No children allowed.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
set_options(Optional[EditorOptions]): Configuration object to further configure the instance.
|
set_options: Configuration object to further configure the instance.
|
||||||
**props: Any properties to be passed to the Editor
|
**props: Any properties to be passed to the Editor
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -171,8 +171,8 @@ class Editor(NoSSRComponent):
|
|||||||
"""Create an instance of Editor. No children allowed.
|
"""Create an instance of Editor. No children allowed.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
set_options(Optional[EditorOptions]): Configuration object to further configure the instance.
|
set_options: Configuration object to further configure the instance.
|
||||||
lang: Language of the editor. Alternatively to a string, a dict of your language can be passed to this prop. Please refer to the library docs for this. options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" | "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it" default: "en".
|
lang: Language of the editor. Alternatively to a string, a dict of your language can be passed to this prop. Please refer to the library docs for this. options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" | "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it" default: "en".
|
||||||
name: This is used to set the HTML form name of the editor. This means on HTML form submission, it will be submitted together with contents of the editor by the name provided.
|
name: This is used to set the HTML form name of the editor. This means on HTML form submission, it will be submitted together with contents of the editor by the name provided.
|
||||||
default_value: Sets the default value of the editor. This is useful if you don't want the on_change method to be called on render. If you want the on_change method to be called on render please use the set_contents prop
|
default_value: Sets the default value of the editor. This is useful if you don't want the on_change method to be called on render. If you want the on_change method to be called on render please use the set_contents prop
|
||||||
width: Sets the width of the editor. px and percentage values are accepted, eg width="100%" or width="500px" default: 100%
|
width: Sets the width of the editor. px and percentage values are accepted, eg width="100%" or width="500px" default: 100%
|
||||||
|
@ -41,14 +41,14 @@ class IterTag(Tag):
|
|||||||
try:
|
try:
|
||||||
if iterable._var_type.mro()[0] is dict:
|
if iterable._var_type.mro()[0] is dict:
|
||||||
# Arg is a tuple of (key, value).
|
# Arg is a tuple of (key, value).
|
||||||
return Tuple[get_args(iterable._var_type)] # type: ignore
|
return Tuple[get_args(iterable._var_type)] # pyright: ignore [reportReturnType]
|
||||||
elif iterable._var_type.mro()[0] is tuple:
|
elif iterable._var_type.mro()[0] is tuple:
|
||||||
# Arg is a union of any possible values in the tuple.
|
# Arg is a union of any possible values in the tuple.
|
||||||
return Union[get_args(iterable._var_type)] # type: ignore
|
return Union[get_args(iterable._var_type)] # pyright: ignore [reportReturnType]
|
||||||
else:
|
else:
|
||||||
return get_args(iterable._var_type)[0]
|
return get_args(iterable._var_type)[0]
|
||||||
except Exception:
|
except Exception:
|
||||||
return Any
|
return Any # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
def get_index_var(self) -> Var:
|
def get_index_var(self) -> Var:
|
||||||
"""Get the index var for the tag (with curly braces).
|
"""Get the index var for the tag (with curly braces).
|
||||||
|
@ -49,7 +49,7 @@ class Tag:
|
|||||||
"""Set the tag's fields.
|
"""Set the tag's fields.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
kwargs: The fields to set.
|
**kwargs: The fields to set.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The tag with the fields
|
The tag with the fields
|
||||||
@ -65,7 +65,24 @@ class Tag:
|
|||||||
Yields:
|
Yields:
|
||||||
Tuple[str, Any]: The field name and value.
|
Tuple[str, Any]: The field name and value.
|
||||||
"""
|
"""
|
||||||
|
from reflex.components.component import BaseComponent
|
||||||
|
|
||||||
for field in dataclasses.fields(self):
|
for field in dataclasses.fields(self):
|
||||||
|
value = getattr(self, field.name)
|
||||||
|
if isinstance(value, list):
|
||||||
|
children = []
|
||||||
|
for child in value:
|
||||||
|
if isinstance(child, BaseComponent):
|
||||||
|
children.append(child.render())
|
||||||
|
else:
|
||||||
|
children.append(child)
|
||||||
|
yield field.name, children
|
||||||
|
continue
|
||||||
|
if isinstance(value, BaseComponent):
|
||||||
|
yield field.name, value.render()
|
||||||
|
continue
|
||||||
|
if callable(value) and not isinstance(value, Var):
|
||||||
|
continue
|
||||||
yield field.name, getattr(self, field.name)
|
yield field.name, getattr(self, field.name)
|
||||||
|
|
||||||
def add_props(self, **kwargs: Optional[Any]) -> Tag:
|
def add_props(self, **kwargs: Optional[Any]) -> Tag:
|
||||||
|
@ -390,7 +390,7 @@ class EnvVar(Generic[T]):
|
|||||||
os.environ[self.name] = str(value)
|
os.environ[self.name] = str(value)
|
||||||
|
|
||||||
|
|
||||||
class env_var: # type: ignore # noqa: N801
|
class env_var: # noqa: N801 # pyright: ignore [reportRedeclaration]
|
||||||
"""Descriptor for environment variables."""
|
"""Descriptor for environment variables."""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
@ -407,7 +407,7 @@ class env_var: # type: ignore # noqa: N801
|
|||||||
self.default = default
|
self.default = default
|
||||||
self.internal = internal
|
self.internal = internal
|
||||||
|
|
||||||
def __set_name__(self, owner, name):
|
def __set_name__(self, owner: Any, name: str):
|
||||||
"""Set the name of the descriptor.
|
"""Set the name of the descriptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -416,7 +416,7 @@ class env_var: # type: ignore # noqa: N801
|
|||||||
"""
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance: Any, owner: Any):
|
||||||
"""Get the EnvVar instance.
|
"""Get the EnvVar instance.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -435,7 +435,7 @@ class env_var: # type: ignore # noqa: N801
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
||||||
def env_var(default, internal=False) -> EnvVar:
|
def env_var(default: Any, internal: bool = False) -> EnvVar:
|
||||||
"""Typing helper for the env_var descriptor.
|
"""Typing helper for the env_var descriptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -600,7 +600,7 @@ class Config(Base):
|
|||||||
See the [configuration](https://reflex.dev/docs/getting-started/configuration/) docs for more info.
|
See the [configuration](https://reflex.dev/docs/getting-started/configuration/) docs for more info.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Config:
|
class Config: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
"""Pydantic config for the config."""
|
"""Pydantic config for the config."""
|
||||||
|
|
||||||
validate_assignment = True
|
validate_assignment = True
|
||||||
@ -766,7 +766,7 @@ class Config(Base):
|
|||||||
"""
|
"""
|
||||||
if self.env_file:
|
if self.env_file:
|
||||||
try:
|
try:
|
||||||
from dotenv import load_dotenv # type: ignore
|
from dotenv import load_dotenv # pyright: ignore [reportMissingImports]
|
||||||
|
|
||||||
# load env file if exists
|
# load env file if exists
|
||||||
load_dotenv(self.env_file, override=True)
|
load_dotenv(self.env_file, override=True)
|
||||||
|
@ -75,6 +75,8 @@ class Reflex(SimpleNamespace):
|
|||||||
# If user sets REFLEX_DIR envroment variable use that instead.
|
# If user sets REFLEX_DIR envroment variable use that instead.
|
||||||
DIR = PlatformDirs(MODULE_NAME, False).user_data_path
|
DIR = PlatformDirs(MODULE_NAME, False).user_data_path
|
||||||
|
|
||||||
|
LOGS_DIR = DIR / "logs"
|
||||||
|
|
||||||
# The root directory of the reflex library.
|
# The root directory of the reflex library.
|
||||||
ROOT_DIR = Path(__file__).parents[2]
|
ROOT_DIR = Path(__file__).parents[2]
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ def _get_package_config(exit_on_fail: bool = True) -> dict:
|
|||||||
The package configuration.
|
The package configuration.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
Exit: If the pyproject.toml file is not found.
|
Exit: If the pyproject.toml file is not found and exit_on_fail is True.
|
||||||
"""
|
"""
|
||||||
pyproject = Path(CustomComponents.PYPROJECT_TOML)
|
pyproject = Path(CustomComponents.PYPROJECT_TOML)
|
||||||
try:
|
try:
|
||||||
@ -925,7 +925,7 @@ def _get_file_from_prompt_in_loop() -> Tuple[bytes, str] | None:
|
|||||||
image_file = file_extension = None
|
image_file = file_extension = None
|
||||||
while image_file is None:
|
while image_file is None:
|
||||||
image_filepath = Path(
|
image_filepath = Path(
|
||||||
console.ask("Upload a preview image of your demo app (enter to skip)")
|
console.ask("Upload a preview image of your demo app (enter to skip)") # pyright: ignore [reportArgumentType]
|
||||||
)
|
)
|
||||||
if not image_filepath:
|
if not image_filepath:
|
||||||
break
|
break
|
||||||
|
@ -243,7 +243,7 @@ class EventHandler(EventActionsMixin):
|
|||||||
raise EventHandlerTypeError(
|
raise EventHandlerTypeError(
|
||||||
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
||||||
) from e
|
) from e
|
||||||
payload = tuple(zip(fn_args, values))
|
payload = tuple(zip(fn_args, values, strict=False))
|
||||||
|
|
||||||
# Return the event spec.
|
# Return the event spec.
|
||||||
return EventSpec(
|
return EventSpec(
|
||||||
@ -263,7 +263,7 @@ class EventSpec(EventActionsMixin):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# The event handler.
|
# The event handler.
|
||||||
handler: EventHandler = dataclasses.field(default=None) # type: ignore
|
handler: EventHandler = dataclasses.field(default=None) # pyright: ignore [reportAssignmentType]
|
||||||
|
|
||||||
# The handler on the client to process event.
|
# The handler on the client to process event.
|
||||||
client_handler_name: str = dataclasses.field(default="")
|
client_handler_name: str = dataclasses.field(default="")
|
||||||
@ -337,7 +337,7 @@ class EventSpec(EventActionsMixin):
|
|||||||
raise EventHandlerTypeError(
|
raise EventHandlerTypeError(
|
||||||
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
||||||
) from e
|
) from e
|
||||||
new_payload = tuple(zip(fn_args, values))
|
new_payload = tuple(zip(fn_args, values, strict=False))
|
||||||
return self.with_args(self.args + new_payload)
|
return self.with_args(self.args + new_payload)
|
||||||
|
|
||||||
|
|
||||||
@ -589,7 +589,7 @@ def no_args_event_spec() -> Tuple[()]:
|
|||||||
Returns:
|
Returns:
|
||||||
An empty tuple.
|
An empty tuple.
|
||||||
"""
|
"""
|
||||||
return () # type: ignore
|
return ()
|
||||||
|
|
||||||
|
|
||||||
# These chains can be used for their side effects when no other events are desired.
|
# These chains can be used for their side effects when no other events are desired.
|
||||||
@ -617,9 +617,9 @@ class IdentityEventReturn(Generic[T], Protocol):
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def passthrough_event_spec(
|
def passthrough_event_spec( # pyright: ignore [reportOverlappingOverload]
|
||||||
event_type: Type[T], /
|
event_type: Type[T], /
|
||||||
) -> Callable[[Var[T]], Tuple[Var[T]]]: ... # type: ignore
|
) -> Callable[[Var[T]], Tuple[Var[T]]]: ...
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -632,7 +632,7 @@ def passthrough_event_spec(
|
|||||||
def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: ...
|
def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: ...
|
||||||
|
|
||||||
|
|
||||||
def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: # type: ignore
|
def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: # pyright: ignore [reportInconsistentOverload]
|
||||||
"""A helper function that returns the input event as output.
|
"""A helper function that returns the input event as output.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -646,9 +646,9 @@ def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: #
|
|||||||
return values
|
return values
|
||||||
|
|
||||||
inner_type = tuple(Var[event_type] for event_type in event_types)
|
inner_type = tuple(Var[event_type] for event_type in event_types)
|
||||||
return_annotation = Tuple[inner_type] # type: ignore
|
return_annotation = Tuple[inner_type]
|
||||||
|
|
||||||
inner.__signature__ = inspect.signature(inner).replace( # type: ignore
|
inner.__signature__ = inspect.signature(inner).replace( # pyright: ignore [reportFunctionMemberAccess]
|
||||||
parameters=[
|
parameters=[
|
||||||
inspect.Parameter(
|
inspect.Parameter(
|
||||||
f"ev_{i}",
|
f"ev_{i}",
|
||||||
@ -730,7 +730,7 @@ class FileUpload:
|
|||||||
# Call the lambda to get the event chain.
|
# Call the lambda to get the event chain.
|
||||||
events = call_event_fn(
|
events = call_event_fn(
|
||||||
on_upload_progress, self.on_upload_progress_args_spec
|
on_upload_progress, self.on_upload_progress_args_spec
|
||||||
) # type: ignore
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"{on_upload_progress} is not a valid event handler.")
|
raise ValueError(f"{on_upload_progress} is not a valid event handler.")
|
||||||
if isinstance(events, Var):
|
if isinstance(events, Var):
|
||||||
@ -777,7 +777,7 @@ def server_side(name: str, sig: inspect.Signature, **kwargs) -> EventSpec:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
fn.__qualname__ = name
|
fn.__qualname__ = name
|
||||||
fn.__signature__ = sig
|
fn.__signature__ = sig # pyright: ignore [reportFunctionMemberAccess]
|
||||||
return EventSpec(
|
return EventSpec(
|
||||||
handler=EventHandler(fn=fn, state_full_name=FRONTEND_EVENT_STATE),
|
handler=EventHandler(fn=fn, state_full_name=FRONTEND_EVENT_STATE),
|
||||||
args=tuple(
|
args=tuple(
|
||||||
@ -1050,13 +1050,13 @@ def download(
|
|||||||
|
|
||||||
is_data_url = (data.js_type() == "string") & (
|
is_data_url = (data.js_type() == "string") & (
|
||||||
data.to(str).startswith("data:")
|
data.to(str).startswith("data:")
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
# If it's a data: URI, use it as is, otherwise convert the Var to JSON in a data: URI.
|
# If it's a data: URI, use it as is, otherwise convert the Var to JSON in a data: URI.
|
||||||
url = cond( # type: ignore
|
url = cond(
|
||||||
is_data_url,
|
is_data_url,
|
||||||
data.to(str),
|
data.to(str),
|
||||||
"data:text/plain," + data.to_string(), # type: ignore
|
"data:text/plain," + data.to_string(),
|
||||||
)
|
)
|
||||||
elif isinstance(data, bytes):
|
elif isinstance(data, bytes):
|
||||||
# Caller provided bytes, so base64 encode it as a data: URI.
|
# Caller provided bytes, so base64 encode it as a data: URI.
|
||||||
@ -1075,7 +1075,8 @@ def download(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _callback_arg_spec(eval_result):
|
# This function seems unused. Check if we still need it. If not, remove in 0.7.0
|
||||||
|
def _callback_arg_spec(eval_result: Any):
|
||||||
"""ArgSpec for call_script callback function.
|
"""ArgSpec for call_script callback function.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1180,7 +1181,7 @@ def run_script(
|
|||||||
return call_function(ArgsFunctionOperation.create((), javascript_code), callback)
|
return call_function(ArgsFunctionOperation.create((), javascript_code), callback)
|
||||||
|
|
||||||
|
|
||||||
def get_event(state, event):
|
def get_event(state: BaseState, event: str):
|
||||||
"""Get the event from the given state.
|
"""Get the event from the given state.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1193,7 +1194,7 @@ def get_event(state, event):
|
|||||||
return f"{state.get_name()}.{event}"
|
return f"{state.get_name()}.{event}"
|
||||||
|
|
||||||
|
|
||||||
def get_hydrate_event(state) -> str:
|
def get_hydrate_event(state: BaseState) -> str:
|
||||||
"""Get the name of the hydrate event for the state.
|
"""Get the name of the hydrate event for the state.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1230,7 +1231,7 @@ def call_event_handler(
|
|||||||
|
|
||||||
#noqa: DAR401
|
#noqa: DAR401
|
||||||
"""
|
"""
|
||||||
event_spec_args = parse_args_spec(event_spec) # type: ignore
|
event_spec_args = parse_args_spec(event_spec)
|
||||||
|
|
||||||
if isinstance(event_callback, EventSpec):
|
if isinstance(event_callback, EventSpec):
|
||||||
check_fn_match_arg_spec(
|
check_fn_match_arg_spec(
|
||||||
@ -1340,7 +1341,7 @@ def call_event_handler(
|
|||||||
if delayed_exceptions:
|
if delayed_exceptions:
|
||||||
raise delayed_exceptions[0]
|
raise delayed_exceptions[0]
|
||||||
|
|
||||||
return event_callback(*event_spec_args) # type: ignore
|
return event_callback(*event_spec_args)
|
||||||
|
|
||||||
|
|
||||||
def unwrap_var_annotation(annotation: GenericType):
|
def unwrap_var_annotation(annotation: GenericType):
|
||||||
@ -1574,7 +1575,7 @@ def fix_events(
|
|||||||
if not isinstance(e, EventSpec):
|
if not isinstance(e, EventSpec):
|
||||||
raise ValueError(f"Unexpected event type, {type(e)}.")
|
raise ValueError(f"Unexpected event type, {type(e)}.")
|
||||||
name = format.format_event_handler(e.handler)
|
name = format.format_event_handler(e.handler)
|
||||||
payload = {k._js_expr: v._decode() for k, v in e.args} # type: ignore
|
payload = {k._js_expr: v._decode() for k, v in e.args}
|
||||||
|
|
||||||
# Filter router_data to reduce payload size
|
# Filter router_data to reduce payload size
|
||||||
event_router_data = {
|
event_router_data = {
|
||||||
@ -1623,7 +1624,7 @@ class EventVar(ObjectVar, python_types=EventSpec):
|
|||||||
class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
|
class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
|
||||||
"""A literal event var."""
|
"""A literal event var."""
|
||||||
|
|
||||||
_var_value: EventSpec = dataclasses.field(default=None) # type: ignore
|
_var_value: EventSpec = dataclasses.field(default=None) # pyright: ignore [reportAssignmentType]
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
"""Get the hash of the var.
|
"""Get the hash of the var.
|
||||||
@ -1687,7 +1688,7 @@ class EventChainVar(BuilderFunctionVar, python_types=EventChain):
|
|||||||
class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainVar):
|
class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainVar):
|
||||||
"""A literal event chain var."""
|
"""A literal event chain var."""
|
||||||
|
|
||||||
_var_value: EventChain = dataclasses.field(default=None) # type: ignore
|
_var_value: EventChain = dataclasses.field(default=None) # pyright: ignore [reportAssignmentType]
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
"""Get the hash of the var.
|
"""Get the hash of the var.
|
||||||
@ -1717,7 +1718,7 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
|
|||||||
if isinstance(value.args_spec, Sequence)
|
if isinstance(value.args_spec, Sequence)
|
||||||
else value.args_spec
|
else value.args_spec
|
||||||
)
|
)
|
||||||
sig = inspect.signature(arg_spec) # type: ignore
|
sig = inspect.signature(arg_spec) # pyright: ignore [reportArgumentType]
|
||||||
if sig.parameters:
|
if sig.parameters:
|
||||||
arg_def = tuple((f"_{p}" for p in sig.parameters))
|
arg_def = tuple((f"_{p}" for p in sig.parameters))
|
||||||
arg_def_expr = LiteralVar.create([Var(_js_expr=arg) for arg in arg_def])
|
arg_def_expr = LiteralVar.create([Var(_js_expr=arg) for arg in arg_def])
|
||||||
@ -1819,7 +1820,7 @@ class EventCallback(Generic[P, T]):
|
|||||||
value4: V4 | Var[V4],
|
value4: V4 | Var[V4],
|
||||||
) -> EventCallback[Q, T]: ...
|
) -> EventCallback[Q, T]: ...
|
||||||
|
|
||||||
def __call__(self, *values) -> EventCallback: # type: ignore
|
def __call__(self, *values) -> EventCallback: # pyright: ignore [reportInconsistentOverload]
|
||||||
"""Call the function with the values.
|
"""Call the function with the values.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1828,17 +1829,17 @@ class EventCallback(Generic[P, T]):
|
|||||||
Returns:
|
Returns:
|
||||||
The function with the values.
|
The function with the values.
|
||||||
"""
|
"""
|
||||||
return self.func(*values) # type: ignore
|
return self.func(*values) # pyright: ignore [reportCallIssue, reportReturnType]
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(
|
def __get__(
|
||||||
self: EventCallback[P, T], instance: None, owner
|
self: EventCallback[P, T], instance: None, owner: Any
|
||||||
) -> EventCallback[P, T]: ...
|
) -> EventCallback[P, T]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(self, instance, owner) -> Callable[P, T]: ...
|
def __get__(self, instance: Any, owner: Any) -> Callable[P, T]: ...
|
||||||
|
|
||||||
def __get__(self, instance, owner) -> Callable: # type: ignore
|
def __get__(self, instance: Any, owner: Any) -> Callable:
|
||||||
"""Get the function with the instance bound to it.
|
"""Get the function with the instance bound to it.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1849,9 +1850,9 @@ class EventCallback(Generic[P, T]):
|
|||||||
The function with the instance bound to it
|
The function with the instance bound to it
|
||||||
"""
|
"""
|
||||||
if instance is None:
|
if instance is None:
|
||||||
return self.func # type: ignore
|
return self.func
|
||||||
|
|
||||||
return partial(self.func, instance) # type: ignore
|
return partial(self.func, instance)
|
||||||
|
|
||||||
|
|
||||||
G = ParamSpec("G")
|
G = ParamSpec("G")
|
||||||
@ -1902,7 +1903,7 @@ class EventNamespace(types.SimpleNamespace):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def __call__(
|
def __call__(
|
||||||
func: None = None, *, background: bool | None = None
|
func: None = None, *, background: bool | None = None
|
||||||
) -> Callable[[Callable[Concatenate[BASE_STATE, P], T]], EventCallback[P, T]]: ...
|
) -> Callable[[Callable[Concatenate[BASE_STATE, P], T]], EventCallback[P, T]]: ... # pyright: ignore [reportInvalidTypeVarUse]
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -1945,7 +1946,7 @@ class EventNamespace(types.SimpleNamespace):
|
|||||||
"Background task must be async function or generator."
|
"Background task must be async function or generator."
|
||||||
)
|
)
|
||||||
setattr(func, BACKGROUND_TASK_MARKER, True)
|
setattr(func, BACKGROUND_TASK_MARKER, True)
|
||||||
return func # type: ignore
|
return func # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
if func is not None:
|
if func is not None:
|
||||||
return wrapper(func)
|
return wrapper(func)
|
||||||
|
@ -201,9 +201,7 @@ class ClientStateVar(Var):
|
|||||||
)
|
)
|
||||||
.to(self._var_type)
|
.to(self._var_type)
|
||||||
._replace(
|
._replace(
|
||||||
merge_var_data=VarData( # type: ignore
|
merge_var_data=VarData(imports=_refs_import if self._global_ref else {})
|
||||||
imports=_refs_import if self._global_ref else {}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ def _compose_react_imports(tags: list[str]) -> dict[str, list[ImportVar]]:
|
|||||||
return {"react": [ImportVar(tag=tag) for tag in tags]}
|
return {"react": [ImportVar(tag=tag) for tag in tags]}
|
||||||
|
|
||||||
|
|
||||||
def const(name, value) -> Var:
|
def const(name: str | list[str], value: str | Var) -> Var:
|
||||||
"""Create a constant Var.
|
"""Create a constant Var.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -26,7 +26,7 @@ def const(name, value) -> Var:
|
|||||||
return Var(_js_expr=f"const {name} = {value}")
|
return Var(_js_expr=f"const {name} = {value}")
|
||||||
|
|
||||||
|
|
||||||
def useCallback(func, deps) -> Var: # noqa: N802
|
def useCallback(func: str, deps: list) -> Var: # noqa: N802
|
||||||
"""Create a useCallback hook with a function and dependencies.
|
"""Create a useCallback hook with a function and dependencies.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -42,7 +42,7 @@ def useCallback(func, deps) -> Var: # noqa: N802
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def useContext(context) -> Var: # noqa: N802
|
def useContext(context: str) -> Var: # noqa: N802
|
||||||
"""Create a useContext hook with a context.
|
"""Create a useContext hook with a context.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -57,7 +57,7 @@ def useContext(context) -> Var: # noqa: N802
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def useRef(default) -> Var: # noqa: N802
|
def useRef(default: str) -> Var: # noqa: N802
|
||||||
"""Create a useRef hook with a default value.
|
"""Create a useRef hook with a default value.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -72,7 +72,7 @@ def useRef(default) -> Var: # noqa: N802
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def useState(var_name, default=None) -> Var: # noqa: N802
|
def useState(var_name: str, default: str | None = None) -> Var: # noqa: N802
|
||||||
"""Create a useState hook with a variable name and setter name.
|
"""Create a useState hook with a variable name and setter name.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -44,10 +44,10 @@ class Sidebar(Box, MemoizationLeaf):
|
|||||||
Returns:
|
Returns:
|
||||||
The style of the component.
|
The style of the component.
|
||||||
"""
|
"""
|
||||||
sidebar: Component = self.children[-2] # type: ignore
|
sidebar: Component = self.children[-2] # pyright: ignore [reportAssignmentType]
|
||||||
spacer: Component = self.children[-1] # type: ignore
|
spacer: Component = self.children[-1] # pyright: ignore [reportAssignmentType]
|
||||||
open = (
|
open = (
|
||||||
self.State.open # type: ignore
|
self.State.open # pyright: ignore [reportAttributeAccessIssue]
|
||||||
if self.State
|
if self.State
|
||||||
else Var(_js_expr="open")
|
else Var(_js_expr="open")
|
||||||
)
|
)
|
||||||
@ -159,11 +159,11 @@ class SidebarTrigger(Fragment):
|
|||||||
"""
|
"""
|
||||||
trigger_props = {**props, **sidebar_trigger_style}
|
trigger_props = {**props, **sidebar_trigger_style}
|
||||||
|
|
||||||
inner_sidebar: Component = sidebar.children[0] # type: ignore
|
inner_sidebar: Component = sidebar.children[0] # pyright: ignore [reportAssignmentType]
|
||||||
sidebar_width = inner_sidebar.style.get("width")
|
sidebar_width = inner_sidebar.style.get("width")
|
||||||
|
|
||||||
if sidebar.State:
|
if sidebar.State:
|
||||||
open, toggle = sidebar.State.open, sidebar.State.toggle # type: ignore
|
open, toggle = sidebar.State.open, sidebar.State.toggle # pyright: ignore [reportAttributeAccessIssue]
|
||||||
else:
|
else:
|
||||||
open, toggle = (
|
open, toggle = (
|
||||||
Var(_js_expr="open"),
|
Var(_js_expr="open"),
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
"""Miscellaneous functions for the experimental package."""
|
"""Miscellaneous functions for the experimental package."""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Any
|
from typing import Any, Callable
|
||||||
|
|
||||||
|
|
||||||
async def run_in_thread(func) -> Any:
|
async def run_in_thread(func: Callable) -> Any:
|
||||||
"""Run a function in a separate thread.
|
"""Run a function in a separate thread.
|
||||||
|
|
||||||
To not block the UI event queue, run_in_thread must be inside inside a rx.event(background=True) decorated method.
|
To not block the UI event queue, run_in_thread must be inside inside a rx.event(background=True) decorated method.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
func (callable): The non-async function to run.
|
func: The non-async function to run.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If the function is an async function.
|
ValueError: If the function is an async function.
|
||||||
|
@ -6,7 +6,7 @@ from reflex.istate.proxy import ReadOnlyStateProxy
|
|||||||
from reflex.state import _split_substate_key, _substate_key, get_state_manager
|
from reflex.state import _split_substate_key, _substate_key, get_state_manager
|
||||||
|
|
||||||
|
|
||||||
async def get_state(token, state_cls: Any | None = None) -> ReadOnlyStateProxy:
|
async def get_state(token: str, state_cls: Any | None = None) -> ReadOnlyStateProxy:
|
||||||
"""Get the instance of a state for a token.
|
"""Get the instance of a state for a token.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -18,6 +18,7 @@ import sqlalchemy
|
|||||||
import sqlalchemy.exc
|
import sqlalchemy.exc
|
||||||
import sqlalchemy.ext.asyncio
|
import sqlalchemy.ext.asyncio
|
||||||
import sqlalchemy.orm
|
import sqlalchemy.orm
|
||||||
|
from alembic.runtime.migration import MigrationContext
|
||||||
|
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
from reflex.config import environment, get_config
|
from reflex.config import environment, get_config
|
||||||
@ -242,7 +243,7 @@ class ModelRegistry:
|
|||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssues]
|
class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssues,reportIncompatibleVariableOverride]
|
||||||
"""Base class to define a table in the database."""
|
"""Base class to define a table in the database."""
|
||||||
|
|
||||||
# The primary key for the table.
|
# The primary key for the table.
|
||||||
@ -261,7 +262,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
|||||||
super().__init_subclass__()
|
super().__init_subclass__()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _dict_recursive(cls, value):
|
def _dict_recursive(cls, value: Any):
|
||||||
"""Recursively serialize the relationship object(s).
|
"""Recursively serialize the relationship object(s).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -393,7 +394,11 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
|||||||
writer = alembic.autogenerate.rewriter.Rewriter()
|
writer = alembic.autogenerate.rewriter.Rewriter()
|
||||||
|
|
||||||
@writer.rewrites(alembic.operations.ops.AddColumnOp)
|
@writer.rewrites(alembic.operations.ops.AddColumnOp)
|
||||||
def render_add_column_with_server_default(context, revision, op):
|
def render_add_column_with_server_default(
|
||||||
|
context: MigrationContext,
|
||||||
|
revision: str | None,
|
||||||
|
op: Any,
|
||||||
|
):
|
||||||
# Carry the sqlmodel default as server_default so that newly added
|
# Carry the sqlmodel default as server_default so that newly added
|
||||||
# columns get the desired default value in existing rows.
|
# columns get the desired default value in existing rows.
|
||||||
if op.column.default is not None and op.column.server_default is None:
|
if op.column.default is not None and op.column.server_default is None:
|
||||||
@ -402,7 +407,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
|||||||
)
|
)
|
||||||
return op
|
return op
|
||||||
|
|
||||||
def run_autogenerate(rev, context):
|
def run_autogenerate(rev: str, context: MigrationContext):
|
||||||
revision_context.run_autogenerate(rev, context)
|
revision_context.run_autogenerate(rev, context)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -415,7 +420,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
|||||||
connection=connection,
|
connection=connection,
|
||||||
target_metadata=ModelRegistry.get_metadata(),
|
target_metadata=ModelRegistry.get_metadata(),
|
||||||
render_item=cls._alembic_render_item,
|
render_item=cls._alembic_render_item,
|
||||||
process_revision_directives=writer, # type: ignore
|
process_revision_directives=writer,
|
||||||
compare_type=False,
|
compare_type=False,
|
||||||
render_as_batch=True, # for sqlite compatibility
|
render_as_batch=True, # for sqlite compatibility
|
||||||
)
|
)
|
||||||
@ -444,7 +449,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
|||||||
"""
|
"""
|
||||||
config, script_directory = cls._alembic_config()
|
config, script_directory = cls._alembic_config()
|
||||||
|
|
||||||
def run_upgrade(rev, context):
|
def run_upgrade(rev: str, context: MigrationContext):
|
||||||
return script_directory._upgrade_revs(to_rev, rev)
|
return script_directory._upgrade_revs(to_rev, rev)
|
||||||
|
|
||||||
with alembic.runtime.environment.EnvironmentContext(
|
with alembic.runtime.environment.EnvironmentContext(
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Callable, Dict, List
|
||||||
|
|
||||||
from reflex.config import get_config
|
from reflex.config import get_config
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import BASE_STATE, EventType
|
||||||
@ -42,7 +42,7 @@ def page(
|
|||||||
The decorated function.
|
The decorated function.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def decorator(render_fn):
|
def decorator(render_fn: Callable):
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if route:
|
if route:
|
||||||
kwargs["route"] = route
|
kwargs["route"] = route
|
||||||
@ -66,7 +66,7 @@ def page(
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def get_decorated_pages(omit_implicit_routes=True) -> list[dict[str, Any]]:
|
def get_decorated_pages(omit_implicit_routes: bool = True) -> list[dict[str, Any]]:
|
||||||
"""Get the decorated pages.
|
"""Get the decorated pages.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -17,7 +17,7 @@ from reflex.state import reset_disk_state_manager
|
|||||||
from reflex.utils import console, telemetry
|
from reflex.utils import console, telemetry
|
||||||
|
|
||||||
# Disable typer+rich integration for help panels
|
# Disable typer+rich integration for help panels
|
||||||
typer.core.rich = None # type: ignore
|
typer.core.rich = None # pyright: ignore [reportPrivateImportUsage]
|
||||||
|
|
||||||
# Create the app.
|
# Create the app.
|
||||||
try:
|
try:
|
||||||
@ -125,8 +125,8 @@ def _run(
|
|||||||
env: constants.Env = constants.Env.DEV,
|
env: constants.Env = constants.Env.DEV,
|
||||||
frontend: bool = True,
|
frontend: bool = True,
|
||||||
backend: bool = True,
|
backend: bool = True,
|
||||||
frontend_port: str = str(config.frontend_port),
|
frontend_port: int = config.frontend_port,
|
||||||
backend_port: str = str(config.backend_port),
|
backend_port: int = config.backend_port,
|
||||||
backend_host: str = config.backend_host,
|
backend_host: str = config.backend_host,
|
||||||
loglevel: constants.LogLevel = config.loglevel,
|
loglevel: constants.LogLevel = config.loglevel,
|
||||||
):
|
):
|
||||||
@ -160,18 +160,22 @@ def _run(
|
|||||||
# Find the next available open port if applicable.
|
# Find the next available open port if applicable.
|
||||||
if frontend:
|
if frontend:
|
||||||
frontend_port = processes.handle_port(
|
frontend_port = processes.handle_port(
|
||||||
"frontend", frontend_port, str(constants.DefaultPorts.FRONTEND_PORT)
|
"frontend",
|
||||||
|
frontend_port,
|
||||||
|
constants.DefaultPorts.FRONTEND_PORT,
|
||||||
)
|
)
|
||||||
|
|
||||||
if backend:
|
if backend:
|
||||||
backend_port = processes.handle_port(
|
backend_port = processes.handle_port(
|
||||||
"backend", backend_port, str(constants.DefaultPorts.BACKEND_PORT)
|
"backend",
|
||||||
|
backend_port,
|
||||||
|
constants.DefaultPorts.BACKEND_PORT,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Apply the new ports to the config.
|
# Apply the new ports to the config.
|
||||||
if frontend_port != str(config.frontend_port):
|
if frontend_port != config.frontend_port:
|
||||||
config._set_persistent(frontend_port=frontend_port)
|
config._set_persistent(frontend_port=frontend_port)
|
||||||
if backend_port != str(config.backend_port):
|
if backend_port != config.backend_port:
|
||||||
config._set_persistent(backend_port=backend_port)
|
config._set_persistent(backend_port=backend_port)
|
||||||
|
|
||||||
# Reload the config to make sure the env vars are persistent.
|
# Reload the config to make sure the env vars are persistent.
|
||||||
@ -262,10 +266,10 @@ def run(
|
|||||||
help="Execute only backend.",
|
help="Execute only backend.",
|
||||||
envvar=environment.REFLEX_BACKEND_ONLY.name,
|
envvar=environment.REFLEX_BACKEND_ONLY.name,
|
||||||
),
|
),
|
||||||
frontend_port: str = typer.Option(
|
frontend_port: int = typer.Option(
|
||||||
config.frontend_port, help="Specify a different frontend port."
|
config.frontend_port, help="Specify a different frontend port."
|
||||||
),
|
),
|
||||||
backend_port: str = typer.Option(
|
backend_port: int = typer.Option(
|
||||||
config.backend_port, help="Specify a different backend port."
|
config.backend_port, help="Specify a different backend port."
|
||||||
),
|
),
|
||||||
backend_host: str = typer.Option(
|
backend_host: str = typer.Option(
|
||||||
@ -355,7 +359,7 @@ def logout(
|
|||||||
|
|
||||||
check_version()
|
check_version()
|
||||||
|
|
||||||
logout(loglevel) # type: ignore
|
logout(loglevel) # pyright: ignore [reportArgumentType]
|
||||||
|
|
||||||
|
|
||||||
db_cli = typer.Typer()
|
db_cli = typer.Typer()
|
||||||
|
@ -103,7 +103,7 @@ def catchall_prefix(route: str) -> str:
|
|||||||
return route.replace(pattern, "") if pattern else ""
|
return route.replace(pattern, "") if pattern else ""
|
||||||
|
|
||||||
|
|
||||||
def replace_brackets_with_keywords(input_string):
|
def replace_brackets_with_keywords(input_string: str) -> str:
|
||||||
"""Replace brackets and everything inside it in a string with a keyword.
|
"""Replace brackets and everything inside it in a string with a keyword.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -30,6 +30,7 @@ from typing import (
|
|||||||
Optional,
|
Optional,
|
||||||
Sequence,
|
Sequence,
|
||||||
Set,
|
Set,
|
||||||
|
SupportsIndex,
|
||||||
Tuple,
|
Tuple,
|
||||||
Type,
|
Type,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
@ -606,7 +607,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
if cls._item_is_event_handler(name, fn)
|
if cls._item_is_event_handler(name, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
for mixin in cls._mixins():
|
for mixin in cls._mixins(): # pyright: ignore [reportAssignmentType]
|
||||||
for name, value in mixin.__dict__.items():
|
for name, value in mixin.__dict__.items():
|
||||||
if name in cls.inherited_vars:
|
if name in cls.inherited_vars:
|
||||||
continue
|
continue
|
||||||
@ -618,7 +619,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
cls.computed_vars[newcv._js_expr] = newcv
|
cls.computed_vars[newcv._js_expr] = newcv
|
||||||
cls.vars[newcv._js_expr] = newcv
|
cls.vars[newcv._js_expr] = newcv
|
||||||
continue
|
continue
|
||||||
if types.is_backend_base_variable(name, mixin):
|
if types.is_backend_base_variable(name, mixin): # pyright: ignore [reportArgumentType]
|
||||||
cls.backend_vars[name] = copy.deepcopy(value)
|
cls.backend_vars[name] = copy.deepcopy(value)
|
||||||
continue
|
continue
|
||||||
if events.get(name) is not None:
|
if events.get(name) is not None:
|
||||||
@ -918,7 +919,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
]
|
]
|
||||||
if len(parent_states) >= 2:
|
if len(parent_states) >= 2:
|
||||||
raise ValueError(f"Only one parent state is allowed {parent_states}.")
|
raise ValueError(f"Only one parent state is allowed {parent_states}.")
|
||||||
return parent_states[0] if len(parent_states) == 1 else None # type: ignore
|
return parent_states[0] if len(parent_states) == 1 else None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@functools.lru_cache()
|
@functools.lru_cache()
|
||||||
@ -1088,7 +1089,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
setattr(cls, prop._var_field_name, prop)
|
setattr(cls, prop._var_field_name, prop)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _create_event_handler(cls, fn):
|
def _create_event_handler(cls, fn: Any):
|
||||||
"""Create an event handler for the given function.
|
"""Create an event handler for the given function.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1206,14 +1207,14 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
|
|
||||||
cls._check_overwritten_dynamic_args(list(args.keys()))
|
cls._check_overwritten_dynamic_args(list(args.keys()))
|
||||||
|
|
||||||
def argsingle_factory(param):
|
def argsingle_factory(param: str):
|
||||||
def inner_func(self) -> str:
|
def inner_func(self: BaseState) -> str:
|
||||||
return self.router.page.params.get(param, "")
|
return self.router.page.params.get(param, "")
|
||||||
|
|
||||||
return inner_func
|
return inner_func
|
||||||
|
|
||||||
def arglist_factory(param):
|
def arglist_factory(param: str):
|
||||||
def inner_func(self) -> List[str]:
|
def inner_func(self: BaseState) -> List[str]:
|
||||||
return self.router.page.params.get(param, [])
|
return self.router.page.params.get(param, [])
|
||||||
|
|
||||||
return inner_func
|
return inner_func
|
||||||
@ -1298,8 +1299,8 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
fn = _no_chain_background_task(type(self), name, handler.fn)
|
fn = _no_chain_background_task(type(self), name, handler.fn)
|
||||||
else:
|
else:
|
||||||
fn = functools.partial(handler.fn, self)
|
fn = functools.partial(handler.fn, self)
|
||||||
fn.__module__ = handler.fn.__module__ # type: ignore
|
fn.__module__ = handler.fn.__module__
|
||||||
fn.__qualname__ = handler.fn.__qualname__ # type: ignore
|
fn.__qualname__ = handler.fn.__qualname__
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
backend_vars = super().__getattribute__("_backend_vars")
|
backend_vars = super().__getattribute__("_backend_vars")
|
||||||
@ -1566,7 +1567,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
"""
|
"""
|
||||||
# Oopsie case: you didn't give me a Var... so get what you give.
|
# Oopsie case: you didn't give me a Var... so get what you give.
|
||||||
if not isinstance(var, Var):
|
if not isinstance(var, Var):
|
||||||
return var # type: ignore
|
return var
|
||||||
|
|
||||||
# Fast case: this is a literal var and the value is known.
|
# Fast case: this is a literal var and the value is known.
|
||||||
if hasattr(var, "_var_value"):
|
if hasattr(var, "_var_value"):
|
||||||
@ -2357,7 +2358,7 @@ class OnLoadInternalState(State):
|
|||||||
self.router.session.client_token,
|
self.router.session.client_token,
|
||||||
router_data=self.router_data,
|
router_data=self.router_data,
|
||||||
),
|
),
|
||||||
State.set_is_hydrated(True), # type: ignore
|
State.set_is_hydrated(True), # pyright: ignore [reportAttributeAccessIssue]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -2498,7 +2499,9 @@ class StateProxy(wrapt.ObjectProxy):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, state_instance, parent_state_proxy: Optional["StateProxy"] = None
|
self,
|
||||||
|
state_instance: BaseState,
|
||||||
|
parent_state_proxy: Optional["StateProxy"] = None,
|
||||||
):
|
):
|
||||||
"""Create a proxy for a state instance.
|
"""Create a proxy for a state instance.
|
||||||
|
|
||||||
@ -2641,7 +2644,7 @@ class StateProxy(wrapt.ObjectProxy):
|
|||||||
# ensure mutations to these containers are blocked unless proxy is _mutable
|
# ensure mutations to these containers are blocked unless proxy is _mutable
|
||||||
return ImmutableMutableProxy(
|
return ImmutableMutableProxy(
|
||||||
wrapped=value.__wrapped__,
|
wrapped=value.__wrapped__,
|
||||||
state=self, # type: ignore
|
state=self,
|
||||||
field_name=value._self_field_name,
|
field_name=value._self_field_name,
|
||||||
)
|
)
|
||||||
if isinstance(value, functools.partial) and value.args[0] is self.__wrapped__:
|
if isinstance(value, functools.partial) and value.args[0] is self.__wrapped__:
|
||||||
@ -2654,7 +2657,7 @@ class StateProxy(wrapt.ObjectProxy):
|
|||||||
)
|
)
|
||||||
if isinstance(value, MethodType) and value.__self__ is self.__wrapped__:
|
if isinstance(value, MethodType) and value.__self__ is self.__wrapped__:
|
||||||
# Rebind methods to the proxy instance
|
# Rebind methods to the proxy instance
|
||||||
value = type(value)(value.__func__, self) # type: ignore
|
value = type(value)(value.__func__, self)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def __setattr__(self, name: str, value: Any) -> None:
|
def __setattr__(self, name: str, value: Any) -> None:
|
||||||
@ -2854,7 +2857,7 @@ class StateManagerMemory(StateManager):
|
|||||||
# The dict of mutexes for each client
|
# The dict of mutexes for each client
|
||||||
_states_locks: Dict[str, asyncio.Lock] = pydantic.PrivateAttr({})
|
_states_locks: Dict[str, asyncio.Lock] = pydantic.PrivateAttr({})
|
||||||
|
|
||||||
class Config:
|
class Config: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
"""The Pydantic config."""
|
"""The Pydantic config."""
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
@ -2972,7 +2975,7 @@ class StateManagerDisk(StateManager):
|
|||||||
# The token expiration time (s).
|
# The token expiration time (s).
|
||||||
token_expiration: int = pydantic.Field(default_factory=_default_token_expiration)
|
token_expiration: int = pydantic.Field(default_factory=_default_token_expiration)
|
||||||
|
|
||||||
class Config:
|
class Config: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
"""The Pydantic config."""
|
"""The Pydantic config."""
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
@ -3339,6 +3342,7 @@ class StateManagerRedis(StateManager):
|
|||||||
for state_cls, redis_state in zip(
|
for state_cls, redis_state in zip(
|
||||||
required_state_classes,
|
required_state_classes,
|
||||||
await redis_pipeline.execute(),
|
await redis_pipeline.execute(),
|
||||||
|
strict=False,
|
||||||
):
|
):
|
||||||
state = None
|
state = None
|
||||||
|
|
||||||
@ -3462,7 +3466,9 @@ class StateManagerRedis(StateManager):
|
|||||||
|
|
||||||
@validator("lock_warning_threshold")
|
@validator("lock_warning_threshold")
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_lock_warning_threshold(cls, lock_warning_threshold: int, values):
|
def validate_lock_warning_threshold(
|
||||||
|
cls, lock_warning_threshold: int, values: dict[str, int]
|
||||||
|
):
|
||||||
"""Validate the lock warning threshold.
|
"""Validate the lock warning threshold.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3698,9 +3704,9 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
wrapper_cls_name,
|
wrapper_cls_name,
|
||||||
(cls,),
|
(cls,),
|
||||||
{
|
{
|
||||||
dataclasses._FIELDS: getattr( # pyright: ignore [reportGeneralTypeIssues]
|
dataclasses._FIELDS: getattr( # pyright: ignore [reportAttributeAccessIssue]
|
||||||
wrapped_cls,
|
wrapped_cls,
|
||||||
dataclasses._FIELDS, # pyright: ignore [reportGeneralTypeIssues]
|
dataclasses._FIELDS, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -3730,10 +3736,10 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
|
|
||||||
def _mark_dirty(
|
def _mark_dirty(
|
||||||
self,
|
self,
|
||||||
wrapped=None,
|
wrapped: Callable | None = None,
|
||||||
instance=None,
|
instance: BaseState | None = None,
|
||||||
args=(),
|
args: tuple = (),
|
||||||
kwargs=None,
|
kwargs: dict | None = None,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""Mark the state as dirty, then call a wrapped function.
|
"""Mark the state as dirty, then call a wrapped function.
|
||||||
|
|
||||||
@ -3807,7 +3813,9 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _wrap_recursive_decorator(self, wrapped, instance, args, kwargs) -> Any:
|
def _wrap_recursive_decorator(
|
||||||
|
self, wrapped: Callable, instance: BaseState, args: list, kwargs: dict
|
||||||
|
) -> Any:
|
||||||
"""Wrap a function that returns a possibly mutable value.
|
"""Wrap a function that returns a possibly mutable value.
|
||||||
|
|
||||||
Intended for use with `FunctionWrapper` from the `wrapt` library.
|
Intended for use with `FunctionWrapper` from the `wrapt` library.
|
||||||
@ -3853,7 +3861,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
):
|
):
|
||||||
# Wrap methods called on Base subclasses, which might do _anything_
|
# Wrap methods called on Base subclasses, which might do _anything_
|
||||||
return wrapt.FunctionWrapper(
|
return wrapt.FunctionWrapper(
|
||||||
functools.partial(value.__func__, self),
|
functools.partial(value.__func__, self), # pyright: ignore [reportFunctionMemberAccess]
|
||||||
self._wrap_recursive_decorator,
|
self._wrap_recursive_decorator,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -3866,7 +3874,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def __getitem__(self, key) -> Any:
|
def __getitem__(self, key: Any) -> Any:
|
||||||
"""Get the item on the proxied object and return a proxy if mutable.
|
"""Get the item on the proxied object and return a proxy if mutable.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3889,7 +3897,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
# Recursively wrap mutable items retrieved through this proxy.
|
# Recursively wrap mutable items retrieved through this proxy.
|
||||||
yield self._wrap_recursive(value)
|
yield self._wrap_recursive(value)
|
||||||
|
|
||||||
def __delattr__(self, name):
|
def __delattr__(self, name: str):
|
||||||
"""Delete the attribute on the proxied object and mark state dirty.
|
"""Delete the attribute on the proxied object and mark state dirty.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3897,7 +3905,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
"""
|
"""
|
||||||
self._mark_dirty(super().__delattr__, args=(name,))
|
self._mark_dirty(super().__delattr__, args=(name,))
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key: str):
|
||||||
"""Delete the item on the proxied object and mark state dirty.
|
"""Delete the item on the proxied object and mark state dirty.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3905,7 +3913,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
"""
|
"""
|
||||||
self._mark_dirty(super().__delitem__, args=(key,))
|
self._mark_dirty(super().__delitem__, args=(key,))
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key: str, value: Any):
|
||||||
"""Set the item on the proxied object and mark state dirty.
|
"""Set the item on the proxied object and mark state dirty.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3914,7 +3922,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
"""
|
"""
|
||||||
self._mark_dirty(super().__setitem__, args=(key, value))
|
self._mark_dirty(super().__setitem__, args=(key, value))
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name: str, value: Any):
|
||||||
"""Set the attribute on the proxied object and mark state dirty.
|
"""Set the attribute on the proxied object and mark state dirty.
|
||||||
|
|
||||||
If the attribute starts with "_self_", then the state is NOT marked
|
If the attribute starts with "_self_", then the state is NOT marked
|
||||||
@ -3938,7 +3946,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
"""
|
"""
|
||||||
return copy.copy(self.__wrapped__)
|
return copy.copy(self.__wrapped__)
|
||||||
|
|
||||||
def __deepcopy__(self, memo=None) -> Any:
|
def __deepcopy__(self, memo: dict[int, Any] | None = None) -> Any:
|
||||||
"""Return a deepcopy of the proxy.
|
"""Return a deepcopy of the proxy.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3949,7 +3957,7 @@ class MutableProxy(wrapt.ObjectProxy):
|
|||||||
"""
|
"""
|
||||||
return copy.deepcopy(self.__wrapped__, memo=memo)
|
return copy.deepcopy(self.__wrapped__, memo=memo)
|
||||||
|
|
||||||
def __reduce_ex__(self, protocol_version):
|
def __reduce_ex__(self, protocol_version: SupportsIndex):
|
||||||
"""Get the state for redis serialization.
|
"""Get the state for redis serialization.
|
||||||
|
|
||||||
This method is called by cloudpickle to serialize the object.
|
This method is called by cloudpickle to serialize the object.
|
||||||
@ -4013,10 +4021,10 @@ class ImmutableMutableProxy(MutableProxy):
|
|||||||
|
|
||||||
def _mark_dirty(
|
def _mark_dirty(
|
||||||
self,
|
self,
|
||||||
wrapped=None,
|
wrapped: Callable | None = None,
|
||||||
instance=None,
|
instance: BaseState | None = None,
|
||||||
args=(),
|
args: tuple = (),
|
||||||
kwargs=None,
|
kwargs: dict | None = None,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""Raise an exception when an attempt is made to modify the object.
|
"""Raise an exception when an attempt is made to modify the object.
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ def set_color_mode(
|
|||||||
_var_data=VarData.merge(
|
_var_data=VarData.merge(
|
||||||
base_setter._get_all_var_data(), new_color_mode._get_all_var_data()
|
base_setter._get_all_var_data(), new_color_mode._get_all_var_data()
|
||||||
),
|
),
|
||||||
).to(FunctionVar, EventChain) # type: ignore
|
).to(FunctionVar, EventChain)
|
||||||
|
|
||||||
|
|
||||||
# Var resolves to the current color mode for the app ("light", "dark" or "system")
|
# Var resolves to the current color mode for the app ("light", "dark" or "system")
|
||||||
@ -182,7 +182,9 @@ def convert(
|
|||||||
var_data = None # Track import/hook data from any Vars in the style dict.
|
var_data = None # Track import/hook data from any Vars in the style dict.
|
||||||
out = {}
|
out = {}
|
||||||
|
|
||||||
def update_out_dict(return_value, keys_to_update):
|
def update_out_dict(
|
||||||
|
return_value: Var | dict | list | str, keys_to_update: tuple[str, ...]
|
||||||
|
):
|
||||||
for k in keys_to_update:
|
for k in keys_to_update:
|
||||||
out[k] = return_value
|
out[k] = return_value
|
||||||
|
|
||||||
@ -292,6 +294,18 @@ class Style(dict):
|
|||||||
)
|
)
|
||||||
super().__setitem__(key, value)
|
super().__setitem__(key, value)
|
||||||
|
|
||||||
|
def __or__(self, other: Style | dict) -> Style:
|
||||||
|
"""Combine two styles.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
other: The other style to combine.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The combined style.
|
||||||
|
"""
|
||||||
|
_var_data = VarData.merge(self._var_data, getattr(other, "_var_data", None))
|
||||||
|
return Style(super().__or__(self, other), _var_data=_var_data) # pyright: ignore [reportGeneralTypeIssues, reportCallIssue]
|
||||||
|
|
||||||
|
|
||||||
def _format_emotion_style_pseudo_selector(key: str) -> str:
|
def _format_emotion_style_pseudo_selector(key: str) -> str:
|
||||||
"""Format a pseudo selector for emotion CSS-in-JS.
|
"""Format a pseudo selector for emotion CSS-in-JS.
|
||||||
|
@ -80,7 +80,7 @@ T = TypeVar("T")
|
|||||||
TimeoutType = Optional[Union[int, float]]
|
TimeoutType = Optional[Union[int, float]]
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
FRONTEND_POPEN_ARGS["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore
|
FRONTEND_POPEN_ARGS["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # pyright: ignore [reportAttributeAccessIssue]
|
||||||
FRONTEND_POPEN_ARGS["shell"] = True
|
FRONTEND_POPEN_ARGS["shell"] = True
|
||||||
else:
|
else:
|
||||||
FRONTEND_POPEN_ARGS["start_new_session"] = True
|
FRONTEND_POPEN_ARGS["start_new_session"] = True
|
||||||
@ -90,7 +90,7 @@ else:
|
|||||||
class chdir(contextlib.AbstractContextManager): # noqa: N801
|
class chdir(contextlib.AbstractContextManager): # noqa: N801
|
||||||
"""Non thread-safe context manager to change the current working directory."""
|
"""Non thread-safe context manager to change the current working directory."""
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path: str | Path):
|
||||||
"""Prepare contextmanager.
|
"""Prepare contextmanager.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -258,7 +258,7 @@ class AppHarness:
|
|||||||
if self.app_source is not None:
|
if self.app_source is not None:
|
||||||
app_globals = self._get_globals_from_signature(self.app_source)
|
app_globals = self._get_globals_from_signature(self.app_source)
|
||||||
if isinstance(self.app_source, functools.partial):
|
if isinstance(self.app_source, functools.partial):
|
||||||
self.app_source = self.app_source.func # type: ignore
|
self.app_source = self.app_source.func
|
||||||
# get the source from a function or module object
|
# get the source from a function or module object
|
||||||
source_code = "\n".join(
|
source_code = "\n".join(
|
||||||
[
|
[
|
||||||
@ -294,11 +294,15 @@ class AppHarness:
|
|||||||
if p not in before_decorated_pages
|
if p not in before_decorated_pages
|
||||||
]
|
]
|
||||||
self.app_instance = self.app_module.app
|
self.app_instance = self.app_module.app
|
||||||
if isinstance(self.app_instance._state_manager, StateManagerRedis):
|
if self.app_instance and isinstance(
|
||||||
|
self.app_instance._state_manager, StateManagerRedis
|
||||||
|
):
|
||||||
# Create our own redis connection for testing.
|
# Create our own redis connection for testing.
|
||||||
self.state_manager = StateManagerRedis.create(self.app_instance._state)
|
self.state_manager = StateManagerRedis.create(self.app_instance._state) # pyright: ignore [reportArgumentType]
|
||||||
else:
|
else:
|
||||||
self.state_manager = self.app_instance._state_manager
|
self.state_manager = (
|
||||||
|
self.app_instance._state_manager if self.app_instance else None
|
||||||
|
)
|
||||||
|
|
||||||
def _reload_state_module(self):
|
def _reload_state_module(self):
|
||||||
"""Reload the rx.State module to avoid conflict when reloading."""
|
"""Reload the rx.State module to avoid conflict when reloading."""
|
||||||
@ -323,7 +327,7 @@ class AppHarness:
|
|||||||
|
|
||||||
return _shutdown_redis
|
return _shutdown_redis
|
||||||
|
|
||||||
def _start_backend(self, port=0):
|
def _start_backend(self, port: int = 0):
|
||||||
if self.app_instance is None or self.app_instance.api is None:
|
if self.app_instance is None or self.app_instance.api is None:
|
||||||
raise RuntimeError("App was not initialized.")
|
raise RuntimeError("App was not initialized.")
|
||||||
self.backend = uvicorn.Server(
|
self.backend = uvicorn.Server(
|
||||||
@ -426,7 +430,7 @@ class AppHarness:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_app_global_source(key, value):
|
def get_app_global_source(key: str, value: Any):
|
||||||
"""Get the source code of a global object.
|
"""Get the source code of a global object.
|
||||||
If value is a function or class we render the actual
|
If value is a function or class we render the actual
|
||||||
source of value otherwise we assign value to key.
|
source of value otherwise we assign value to key.
|
||||||
@ -621,23 +625,23 @@ class AppHarness:
|
|||||||
want_headless = True
|
want_headless = True
|
||||||
if driver_clz is None:
|
if driver_clz is None:
|
||||||
requested_driver = environment.APP_HARNESS_DRIVER.get()
|
requested_driver = environment.APP_HARNESS_DRIVER.get()
|
||||||
driver_clz = getattr(webdriver, requested_driver)
|
driver_clz = getattr(webdriver, requested_driver) # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
if driver_options is None:
|
if driver_options is None:
|
||||||
driver_options = getattr(webdriver, f"{requested_driver}Options")()
|
driver_options = getattr(webdriver, f"{requested_driver}Options")() # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
if driver_clz is webdriver.Chrome:
|
if driver_clz is webdriver.Chrome: # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
if driver_options is None:
|
if driver_options is None:
|
||||||
driver_options = webdriver.ChromeOptions()
|
driver_options = webdriver.ChromeOptions() # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
driver_options.add_argument("--class=AppHarness")
|
driver_options.add_argument("--class=AppHarness")
|
||||||
if want_headless:
|
if want_headless:
|
||||||
driver_options.add_argument("--headless=new")
|
driver_options.add_argument("--headless=new")
|
||||||
elif driver_clz is webdriver.Firefox:
|
elif driver_clz is webdriver.Firefox: # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
if driver_options is None:
|
if driver_options is None:
|
||||||
driver_options = webdriver.FirefoxOptions()
|
driver_options = webdriver.FirefoxOptions() # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
if want_headless:
|
if want_headless:
|
||||||
driver_options.add_argument("-headless")
|
driver_options.add_argument("-headless")
|
||||||
elif driver_clz is webdriver.Edge:
|
elif driver_clz is webdriver.Edge: # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
if driver_options is None:
|
if driver_options is None:
|
||||||
driver_options = webdriver.EdgeOptions()
|
driver_options = webdriver.EdgeOptions() # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
if want_headless:
|
if want_headless:
|
||||||
driver_options.add_argument("headless")
|
driver_options.add_argument("headless")
|
||||||
if driver_options is None:
|
if driver_options is None:
|
||||||
@ -653,7 +657,7 @@ class AppHarness:
|
|||||||
driver_options.set_capability(key, value)
|
driver_options.set_capability(key, value)
|
||||||
if driver_kwargs is None:
|
if driver_kwargs is None:
|
||||||
driver_kwargs = {}
|
driver_kwargs = {}
|
||||||
driver = driver_clz(options=driver_options, **driver_kwargs) # type: ignore
|
driver = driver_clz(options=driver_options, **driver_kwargs) # pyright: ignore [reportOptionalCall, reportArgumentType]
|
||||||
driver.get(self.frontend_url)
|
driver.get(self.frontend_url)
|
||||||
self._frontends.append(driver)
|
self._frontends.append(driver)
|
||||||
return driver
|
return driver
|
||||||
@ -885,8 +889,8 @@ class Subdir404TCPServer(socketserver.TCPServer):
|
|||||||
request,
|
request,
|
||||||
client_address,
|
client_address,
|
||||||
self,
|
self,
|
||||||
directory=str(self.root), # type: ignore
|
directory=str(self.root), # pyright: ignore [reportCallIssue]
|
||||||
error_page_map=self.error_page_map, # type: ignore
|
error_page_map=self.error_page_map, # pyright: ignore [reportCallIssue]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ def set_env_json():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def generate_sitemap_config(deploy_url: str, export=False):
|
def generate_sitemap_config(deploy_url: str, export: bool = False):
|
||||||
"""Generate the sitemap config file.
|
"""Generate the sitemap config file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import sys
|
import sys
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
async def windows_hot_reload_lifespan_hack():
|
async def windows_hot_reload_lifespan_hack():
|
||||||
@ -50,11 +51,11 @@ def pydantic_v1_patch():
|
|||||||
]
|
]
|
||||||
originals = {module: sys.modules.get(module) for module in patched_modules}
|
originals = {module: sys.modules.get(module) for module in patched_modules}
|
||||||
try:
|
try:
|
||||||
import pydantic.v1 # type: ignore
|
import pydantic.v1
|
||||||
|
|
||||||
sys.modules["pydantic.fields"] = pydantic.v1.fields # type: ignore
|
sys.modules["pydantic.fields"] = pydantic.v1.fields # pyright: ignore [reportAttributeAccessIssue]
|
||||||
sys.modules["pydantic.main"] = pydantic.v1.main # type: ignore
|
sys.modules["pydantic.main"] = pydantic.v1.main # pyright: ignore [reportAttributeAccessIssue]
|
||||||
sys.modules["pydantic.errors"] = pydantic.v1.errors # type: ignore
|
sys.modules["pydantic.errors"] = pydantic.v1.errors # pyright: ignore [reportAttributeAccessIssue]
|
||||||
sys.modules["pydantic"] = pydantic.v1
|
sys.modules["pydantic"] = pydantic.v1
|
||||||
yield
|
yield
|
||||||
except (ImportError, AttributeError):
|
except (ImportError, AttributeError):
|
||||||
@ -74,7 +75,7 @@ with pydantic_v1_patch():
|
|||||||
import sqlmodel as sqlmodel
|
import sqlmodel as sqlmodel
|
||||||
|
|
||||||
|
|
||||||
def sqlmodel_field_has_primary_key(field) -> bool:
|
def sqlmodel_field_has_primary_key(field: Any) -> bool:
|
||||||
"""Determines if a field is a priamary.
|
"""Determines if a field is a priamary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -196,7 +196,7 @@ def _get_first_non_framework_frame() -> FrameType | None:
|
|||||||
exclude_modules = [click, rx, typer, typing_extensions]
|
exclude_modules = [click, rx, typer, typing_extensions]
|
||||||
exclude_roots = [
|
exclude_roots = [
|
||||||
p.parent.resolve()
|
p.parent.resolve()
|
||||||
if (p := Path(m.__file__)).name == "__init__.py"
|
if (p := Path(m.__file__)).name == "__init__.py" # pyright: ignore [reportArgumentType]
|
||||||
else p.resolve()
|
else p.resolve()
|
||||||
for m in exclude_modules
|
for m in exclude_modules
|
||||||
]
|
]
|
||||||
@ -275,7 +275,7 @@ def ask(
|
|||||||
choices: list[str] | None = None,
|
choices: list[str] | None = None,
|
||||||
default: str | None = None,
|
default: str | None = None,
|
||||||
show_choices: bool = True,
|
show_choices: bool = True,
|
||||||
) -> str:
|
) -> str | None:
|
||||||
"""Takes a prompt question and optionally a list of choices
|
"""Takes a prompt question and optionally a list of choices
|
||||||
and returns the user input.
|
and returns the user input.
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ def ask(
|
|||||||
"""
|
"""
|
||||||
return Prompt.ask(
|
return Prompt.ask(
|
||||||
question, choices=choices, default=default, show_choices=show_choices
|
question, choices=choices, default=default, show_choices=show_choices
|
||||||
) # type: ignore
|
)
|
||||||
|
|
||||||
|
|
||||||
def progress():
|
def progress():
|
||||||
|
@ -78,7 +78,7 @@ class VarAttributeError(ReflexError, AttributeError):
|
|||||||
class UntypedComputedVarError(ReflexError, TypeError):
|
class UntypedComputedVarError(ReflexError, TypeError):
|
||||||
"""Custom TypeError for untyped computed var errors."""
|
"""Custom TypeError for untyped computed var errors."""
|
||||||
|
|
||||||
def __init__(self, var_name):
|
def __init__(self, var_name: str):
|
||||||
"""Initialize the UntypedComputedVarError.
|
"""Initialize the UntypedComputedVarError.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -90,7 +90,7 @@ class UntypedComputedVarError(ReflexError, TypeError):
|
|||||||
class MissingAnnotationError(ReflexError, TypeError):
|
class MissingAnnotationError(ReflexError, TypeError):
|
||||||
"""Custom TypeError for missing annotations."""
|
"""Custom TypeError for missing annotations."""
|
||||||
|
|
||||||
def __init__(self, var_name):
|
def __init__(self, var_name: str):
|
||||||
"""Initialize the MissingAnnotationError.
|
"""Initialize the MissingAnnotationError.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -71,7 +71,9 @@ def notify_backend():
|
|||||||
# run_process_and_launch_url is assumed to be used
|
# run_process_and_launch_url is assumed to be used
|
||||||
# only to launch the frontend
|
# only to launch the frontend
|
||||||
# If this is not the case, might have to change the logic
|
# If this is not the case, might have to change the logic
|
||||||
def run_process_and_launch_url(run_command: list[str], backend_present=True):
|
def run_process_and_launch_url(
|
||||||
|
run_command: list[str | None], backend_present: bool = True
|
||||||
|
):
|
||||||
"""Run the process and launch the URL.
|
"""Run the process and launch the URL.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -89,7 +91,7 @@ def run_process_and_launch_url(run_command: list[str], backend_present=True):
|
|||||||
if process is None:
|
if process is None:
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if constants.IS_WINDOWS and backend_present:
|
if constants.IS_WINDOWS and backend_present:
|
||||||
kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore
|
kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # pyright: ignore [reportAttributeAccessIssue]
|
||||||
process = processes.new_process(
|
process = processes.new_process(
|
||||||
run_command,
|
run_command,
|
||||||
cwd=get_web_dir(),
|
cwd=get_web_dir(),
|
||||||
@ -134,7 +136,7 @@ def run_process_and_launch_url(run_command: list[str], backend_present=True):
|
|||||||
break # while True
|
break # while True
|
||||||
|
|
||||||
|
|
||||||
def run_frontend(root: Path, port: str, backend_present=True):
|
def run_frontend(root: Path, port: str, backend_present: bool = True):
|
||||||
"""Run the frontend.
|
"""Run the frontend.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -151,12 +153,12 @@ def run_frontend(root: Path, port: str, backend_present=True):
|
|||||||
console.rule("[bold green]App Running")
|
console.rule("[bold green]App Running")
|
||||||
os.environ["PORT"] = str(get_config().frontend_port if port is None else port)
|
os.environ["PORT"] = str(get_config().frontend_port if port is None else port)
|
||||||
run_process_and_launch_url(
|
run_process_and_launch_url(
|
||||||
[prerequisites.get_package_manager(), "run", "dev"], # type: ignore
|
[prerequisites.get_package_manager(), "run", "dev"],
|
||||||
backend_present,
|
backend_present,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_frontend_prod(root: Path, port: str, backend_present=True):
|
def run_frontend_prod(root: Path, port: str, backend_present: bool = True):
|
||||||
"""Run the frontend.
|
"""Run the frontend.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -173,7 +175,7 @@ def run_frontend_prod(root: Path, port: str, backend_present=True):
|
|||||||
# Run the frontend in production mode.
|
# Run the frontend in production mode.
|
||||||
console.rule("[bold green]App Running")
|
console.rule("[bold green]App Running")
|
||||||
run_process_and_launch_url(
|
run_process_and_launch_url(
|
||||||
[prerequisites.get_package_manager(), "run", "prod"], # type: ignore
|
[prerequisites.get_package_manager(), "run", "prod"],
|
||||||
backend_present,
|
backend_present,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -265,7 +267,7 @@ def get_reload_dirs() -> list[Path]:
|
|||||||
return reload_dirs
|
return reload_dirs
|
||||||
|
|
||||||
|
|
||||||
def run_uvicorn_backend(host, port, loglevel: LogLevel):
|
def run_uvicorn_backend(host: str, port: int, loglevel: LogLevel):
|
||||||
"""Run the backend in development mode using Uvicorn.
|
"""Run the backend in development mode using Uvicorn.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -285,7 +287,7 @@ def run_uvicorn_backend(host, port, loglevel: LogLevel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_granian_backend(host, port, loglevel: LogLevel):
|
def run_granian_backend(host: str, port: int, loglevel: LogLevel):
|
||||||
"""Run the backend in development mode using Granian.
|
"""Run the backend in development mode using Granian.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -295,9 +297,11 @@ def run_granian_backend(host, port, loglevel: LogLevel):
|
|||||||
"""
|
"""
|
||||||
console.debug("Using Granian for backend")
|
console.debug("Using Granian for backend")
|
||||||
try:
|
try:
|
||||||
from granian import Granian # type: ignore
|
from granian import Granian # pyright: ignore [reportMissingImports]
|
||||||
from granian.constants import Interfaces # type: ignore
|
from granian.constants import ( # pyright: ignore [reportMissingImports]
|
||||||
from granian.log import LogLevels # type: ignore
|
Interfaces,
|
||||||
|
)
|
||||||
|
from granian.log import LogLevels # pyright: ignore [reportMissingImports]
|
||||||
|
|
||||||
Granian(
|
Granian(
|
||||||
target=get_granian_target(),
|
target=get_granian_target(),
|
||||||
@ -350,7 +354,7 @@ def run_backend_prod(
|
|||||||
run_uvicorn_backend_prod(host, port, loglevel)
|
run_uvicorn_backend_prod(host, port, loglevel)
|
||||||
|
|
||||||
|
|
||||||
def run_uvicorn_backend_prod(host, port, loglevel):
|
def run_uvicorn_backend_prod(host: str, port: int, loglevel: LogLevel):
|
||||||
"""Run the backend in production mode using Uvicorn.
|
"""Run the backend in production mode using Uvicorn.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -402,7 +406,7 @@ def run_uvicorn_backend_prod(host, port, loglevel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_granian_backend_prod(host, port, loglevel):
|
def run_granian_backend_prod(host: str, port: int, loglevel: LogLevel):
|
||||||
"""Run the backend in production mode using Granian.
|
"""Run the backend in production mode using Granian.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -413,7 +417,9 @@ def run_granian_backend_prod(host, port, loglevel):
|
|||||||
from reflex.utils import processes
|
from reflex.utils import processes
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from granian.constants import Interfaces # type: ignore
|
from granian.constants import ( # pyright: ignore [reportMissingImports]
|
||||||
|
Interfaces,
|
||||||
|
)
|
||||||
|
|
||||||
command = [
|
command = [
|
||||||
"granian",
|
"granian",
|
||||||
@ -467,22 +473,22 @@ def output_system_info():
|
|||||||
|
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
|
|
||||||
|
fnm_info = f"[FNM {prerequisites.get_fnm_version()} (Expected: {constants.Fnm.VERSION}) (PATH: {constants.Fnm.EXE})]"
|
||||||
|
|
||||||
if system != "Windows" or (
|
if system != "Windows" or (
|
||||||
system == "Windows" and prerequisites.is_windows_bun_supported()
|
system == "Windows" and prerequisites.is_windows_bun_supported()
|
||||||
):
|
):
|
||||||
dependencies.extend(
|
dependencies.extend(
|
||||||
[
|
[
|
||||||
f"[FNM {prerequisites.get_fnm_version()} (Expected: {constants.Fnm.VERSION}) (PATH: {constants.Fnm.EXE})]",
|
fnm_info,
|
||||||
f"[Bun {prerequisites.get_bun_version()} (Expected: {constants.Bun.VERSION}) (PATH: {config.bun_path})]",
|
f"[Bun {prerequisites.get_bun_version()} (Expected: {constants.Bun.VERSION}) (PATH: {path_ops.get_bun_path()})]",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
dependencies.append(
|
dependencies.append(fnm_info)
|
||||||
f"[FNM {prerequisites.get_fnm_version()} (Expected: {constants.Fnm.VERSION}) (PATH: {constants.Fnm.EXE})]",
|
|
||||||
)
|
|
||||||
|
|
||||||
if system == "Linux":
|
if system == "Linux":
|
||||||
import distro # type: ignore
|
import distro
|
||||||
|
|
||||||
os_version = distro.name(pretty=True)
|
os_version = distro.name(pretty=True)
|
||||||
else:
|
else:
|
||||||
@ -494,11 +500,11 @@ def output_system_info():
|
|||||||
console.debug(f"{dep}")
|
console.debug(f"{dep}")
|
||||||
|
|
||||||
console.debug(
|
console.debug(
|
||||||
f"Using package installer at: {prerequisites.get_install_package_manager(on_failure_return_none=True)}" # type: ignore
|
f"Using package installer at: {prerequisites.get_install_package_manager(on_failure_return_none=True)}"
|
||||||
)
|
)
|
||||||
console.debug(
|
console.debug(
|
||||||
f"Using package executer at: {prerequisites.get_package_manager(on_failure_return_none=True)}"
|
f"Using package executer at: {prerequisites.get_package_manager(on_failure_return_none=True)}"
|
||||||
) # type: ignore
|
)
|
||||||
if system != "Windows":
|
if system != "Windows":
|
||||||
console.debug(f"Unzip path: {path_ops.which('unzip')}")
|
console.debug(f"Unzip path: {path_ops.which('unzip')}")
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ def _escape_js_string(string: str) -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: we may need to re-vist this logic after new Var API is implemented.
|
# TODO: we may need to re-vist this logic after new Var API is implemented.
|
||||||
def escape_outside_segments(segment):
|
def escape_outside_segments(segment: str):
|
||||||
"""Escape backticks in segments outside of `${}`.
|
"""Escape backticks in segments outside of `${}`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -283,7 +283,7 @@ def format_var(var: Var) -> str:
|
|||||||
return str(var)
|
return str(var)
|
||||||
|
|
||||||
|
|
||||||
def format_route(route: str, format_case=True) -> str:
|
def format_route(route: str, format_case: bool = True) -> str:
|
||||||
"""Format the given route.
|
"""Format the given route.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -377,7 +377,7 @@ def format_prop(
|
|||||||
|
|
||||||
# For dictionaries, convert any properties to strings.
|
# For dictionaries, convert any properties to strings.
|
||||||
elif isinstance(prop, dict):
|
elif isinstance(prop, dict):
|
||||||
prop = serializers.serialize_dict(prop) # type: ignore
|
prop = serializers.serialize_dict(prop) # pyright: ignore [reportAttributeAccessIssue]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Dump the prop as JSON.
|
# Dump the prop as JSON.
|
||||||
@ -533,14 +533,14 @@ def format_queue_events(
|
|||||||
from reflex.vars import FunctionVar, Var
|
from reflex.vars import FunctionVar, Var
|
||||||
|
|
||||||
if not events:
|
if not events:
|
||||||
return Var("(() => null)").to(FunctionVar, EventChain) # type: ignore
|
return Var("(() => null)").to(FunctionVar, EventChain)
|
||||||
|
|
||||||
# If no spec is provided, the function will take no arguments.
|
# If no spec is provided, the function will take no arguments.
|
||||||
def _default_args_spec():
|
def _default_args_spec():
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Construct the arguments that the function accepts.
|
# Construct the arguments that the function accepts.
|
||||||
sig = inspect.signature(args_spec or _default_args_spec) # type: ignore
|
sig = inspect.signature(args_spec or _default_args_spec)
|
||||||
if sig.parameters:
|
if sig.parameters:
|
||||||
arg_def = ",".join(f"_{p}" for p in sig.parameters)
|
arg_def = ",".join(f"_{p}" for p in sig.parameters)
|
||||||
arg_def = f"({arg_def})"
|
arg_def = f"({arg_def})"
|
||||||
@ -557,7 +557,7 @@ def format_queue_events(
|
|||||||
if isinstance(spec, (EventHandler, EventSpec)):
|
if isinstance(spec, (EventHandler, EventSpec)):
|
||||||
specs = [call_event_handler(spec, args_spec or _default_args_spec)]
|
specs = [call_event_handler(spec, args_spec or _default_args_spec)]
|
||||||
elif isinstance(spec, type(lambda: None)):
|
elif isinstance(spec, type(lambda: None)):
|
||||||
specs = call_event_fn(spec, args_spec or _default_args_spec) # type: ignore
|
specs = call_event_fn(spec, args_spec or _default_args_spec) # pyright: ignore [reportAssignmentType, reportArgumentType]
|
||||||
if isinstance(specs, Var):
|
if isinstance(specs, Var):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Invalid event spec: {specs}. Expected a list of EventSpecs."
|
f"Invalid event spec: {specs}. Expected a list of EventSpecs."
|
||||||
@ -569,7 +569,7 @@ def format_queue_events(
|
|||||||
return Var(
|
return Var(
|
||||||
f"{arg_def} => {{queueEvents([{','.join(payloads)}], {constants.CompileVars.SOCKET}); "
|
f"{arg_def} => {{queueEvents([{','.join(payloads)}], {constants.CompileVars.SOCKET}); "
|
||||||
f"processEvent({constants.CompileVars.SOCKET})}}",
|
f"processEvent({constants.CompileVars.SOCKET})}}",
|
||||||
).to(FunctionVar, EventChain) # type: ignore
|
).to(FunctionVar, EventChain)
|
||||||
|
|
||||||
|
|
||||||
def format_query_params(router_data: dict[str, Any]) -> dict[str, str]:
|
def format_query_params(router_data: dict[str, Any]) -> dict[str, str]:
|
||||||
|
@ -90,7 +90,7 @@ def collapse_imports(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(order=True, frozen=True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
class ImportVar:
|
class ImportVar:
|
||||||
"""An import var."""
|
"""An import var."""
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ class ImportVar:
|
|||||||
"""
|
"""
|
||||||
if self.alias:
|
if self.alias:
|
||||||
return (
|
return (
|
||||||
self.alias if self.is_default else " as ".join([self.tag, self.alias]) # type: ignore
|
self.alias if self.is_default else " as ".join([self.tag, self.alias]) # pyright: ignore [reportCallIssue,reportArgumentType]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return self.tag or ""
|
return self.tag or ""
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
"""Module to implement lazy loading in reflex."""
|
"""Module to implement lazy loading in reflex."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
import lazy_loader as lazy
|
import lazy_loader as lazy
|
||||||
|
|
||||||
|
|
||||||
def attach(package_name, submodules=None, submod_attrs=None):
|
def attach(
|
||||||
|
package_name: str,
|
||||||
|
submodules: set | None = None,
|
||||||
|
submod_attrs: dict | None = None,
|
||||||
|
):
|
||||||
"""Replaces a package's __getattr__, __dir__, and __all__ attributes using lazy.attach.
|
"""Replaces a package's __getattr__, __dir__, and __all__ attributes using lazy.attach.
|
||||||
The lazy loader __getattr__ doesn't support tuples as list values. We needed to add
|
The lazy loader __getattr__ doesn't support tuples as list values. We needed to add
|
||||||
this functionality (tuples) in Reflex to support 'import as _' statements. This function
|
this functionality (tuples) in Reflex to support 'import as _' statements. This function
|
||||||
|
@ -9,7 +9,7 @@ import shutil
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.config import environment
|
from reflex.config import environment, get_config
|
||||||
|
|
||||||
# Shorthand for join.
|
# Shorthand for join.
|
||||||
join = os.linesep.join
|
join = os.linesep.join
|
||||||
@ -118,7 +118,7 @@ def ln(src: str | Path, dest: str | Path, overwrite: bool = False) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def which(program: str | Path) -> str | Path | None:
|
def which(program: str | Path) -> Path | None:
|
||||||
"""Find the path to an executable.
|
"""Find the path to an executable.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -127,7 +127,8 @@ def which(program: str | Path) -> str | Path | None:
|
|||||||
Returns:
|
Returns:
|
||||||
The path to the executable.
|
The path to the executable.
|
||||||
"""
|
"""
|
||||||
return shutil.which(str(program))
|
which_result = shutil.which(program)
|
||||||
|
return Path(which_result) if which_result else None
|
||||||
|
|
||||||
|
|
||||||
def use_system_node() -> bool:
|
def use_system_node() -> bool:
|
||||||
@ -156,12 +157,12 @@ def get_node_bin_path() -> Path | None:
|
|||||||
"""
|
"""
|
||||||
bin_path = Path(constants.Node.BIN_PATH)
|
bin_path = Path(constants.Node.BIN_PATH)
|
||||||
if not bin_path.exists():
|
if not bin_path.exists():
|
||||||
str_path = which("node")
|
path = which("node")
|
||||||
return Path(str_path).parent.resolve() if str_path else None
|
return path.parent.absolute() if path else None
|
||||||
return bin_path.resolve()
|
return bin_path.absolute()
|
||||||
|
|
||||||
|
|
||||||
def get_node_path() -> str | None:
|
def get_node_path() -> Path | None:
|
||||||
"""Get the node binary path.
|
"""Get the node binary path.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -169,9 +170,8 @@ def get_node_path() -> str | None:
|
|||||||
"""
|
"""
|
||||||
node_path = Path(constants.Node.PATH)
|
node_path = Path(constants.Node.PATH)
|
||||||
if use_system_node() or not node_path.exists():
|
if use_system_node() or not node_path.exists():
|
||||||
system_node_path = which("node")
|
node_path = which("node")
|
||||||
return str(system_node_path) if system_node_path else None
|
return node_path
|
||||||
return str(node_path)
|
|
||||||
|
|
||||||
|
|
||||||
def get_npm_path() -> Path | None:
|
def get_npm_path() -> Path | None:
|
||||||
@ -182,11 +182,22 @@ def get_npm_path() -> Path | None:
|
|||||||
"""
|
"""
|
||||||
npm_path = Path(constants.Node.NPM_PATH)
|
npm_path = Path(constants.Node.NPM_PATH)
|
||||||
if use_system_node() or not npm_path.exists():
|
if use_system_node() or not npm_path.exists():
|
||||||
system_npm_path = which("npm")
|
npm_path = which("npm")
|
||||||
npm_path = Path(system_npm_path) if system_npm_path else None
|
|
||||||
return npm_path.absolute() if npm_path else None
|
return npm_path.absolute() if npm_path else None
|
||||||
|
|
||||||
|
|
||||||
|
def get_bun_path() -> Path | None:
|
||||||
|
"""Get bun binary path.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The path to the bun binary file.
|
||||||
|
"""
|
||||||
|
bun_path = get_config().bun_path
|
||||||
|
if use_system_bun() or not bun_path.exists():
|
||||||
|
bun_path = which("bun")
|
||||||
|
return bun_path.absolute() if bun_path else None
|
||||||
|
|
||||||
|
|
||||||
def update_json_file(file_path: str | Path, update_dict: dict[str, int | str]):
|
def update_json_file(file_path: str | Path, update_dict: dict[str, int | str]):
|
||||||
"""Update the contents of a json file.
|
"""Update the contents of a json file.
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ def get_node_version() -> version.Version | None:
|
|||||||
try:
|
try:
|
||||||
result = processes.new_process([node_path, "-v"], run=True)
|
result = processes.new_process([node_path, "-v"], run=True)
|
||||||
# The output will be in the form "vX.Y.Z", but version.parse() can handle it
|
# The output will be in the form "vX.Y.Z", but version.parse() can handle it
|
||||||
return version.parse(result.stdout) # type: ignore
|
return version.parse(result.stdout) # pyright: ignore [reportArgumentType]
|
||||||
except (FileNotFoundError, TypeError):
|
except (FileNotFoundError, TypeError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ def get_fnm_version() -> version.Version | None:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
result = processes.new_process([constants.Fnm.EXE, "--version"], run=True)
|
result = processes.new_process([constants.Fnm.EXE, "--version"], run=True)
|
||||||
return version.parse(result.stdout.split(" ")[1]) # type: ignore
|
return version.parse(result.stdout.split(" ")[1]) # pyright: ignore [reportOptionalMemberAccess, reportAttributeAccessIssue]
|
||||||
except (FileNotFoundError, TypeError):
|
except (FileNotFoundError, TypeError):
|
||||||
return None
|
return None
|
||||||
except version.InvalidVersion as e:
|
except version.InvalidVersion as e:
|
||||||
@ -205,10 +205,13 @@ def get_bun_version() -> version.Version | None:
|
|||||||
Returns:
|
Returns:
|
||||||
The version of bun.
|
The version of bun.
|
||||||
"""
|
"""
|
||||||
|
bun_path = path_ops.get_bun_path()
|
||||||
|
if bun_path is None:
|
||||||
|
return None
|
||||||
try:
|
try:
|
||||||
# Run the bun -v command and capture the output
|
# Run the bun -v command and capture the output
|
||||||
result = processes.new_process([str(get_config().bun_path), "-v"], run=True)
|
result = processes.new_process([str(bun_path), "-v"], run=True)
|
||||||
return version.parse(result.stdout) # type: ignore
|
return version.parse(str(result.stdout)) # pyright: ignore [reportArgumentType]
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return None
|
return None
|
||||||
except version.InvalidVersion as e:
|
except version.InvalidVersion as e:
|
||||||
@ -881,7 +884,9 @@ def init_reflex_json(project_hash: int | None):
|
|||||||
path_ops.update_json_file(get_web_dir() / constants.Reflex.JSON, reflex_json)
|
path_ops.update_json_file(get_web_dir() / constants.Reflex.JSON, reflex_json)
|
||||||
|
|
||||||
|
|
||||||
def update_next_config(export=False, transpile_packages: Optional[List[str]] = None):
|
def update_next_config(
|
||||||
|
export: bool = False, transpile_packages: Optional[List[str]] = None
|
||||||
|
):
|
||||||
"""Update Next.js config from Reflex config.
|
"""Update Next.js config from Reflex config.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1062,9 +1067,7 @@ def install_bun():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Skip if bun is already installed.
|
# Skip if bun is already installed.
|
||||||
if Path(get_config().bun_path).exists() and get_bun_version() == version.parse(
|
if get_bun_version() == version.parse(constants.Bun.VERSION):
|
||||||
constants.Bun.VERSION
|
|
||||||
):
|
|
||||||
console.debug("Skipping bun installation as it is already installed.")
|
console.debug("Skipping bun installation as it is already installed.")
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1085,8 +1088,7 @@ def install_bun():
|
|||||||
show_logs=console.is_debug(),
|
show_logs=console.is_debug(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
unzip_path = path_ops.which("unzip")
|
if path_ops.which("unzip") is None:
|
||||||
if unzip_path is None:
|
|
||||||
raise SystemPackageMissingError("unzip")
|
raise SystemPackageMissingError("unzip")
|
||||||
|
|
||||||
# Run the bun install script.
|
# Run the bun install script.
|
||||||
@ -1128,7 +1130,7 @@ def cached_procedure(cache_file: str, payload_fn: Callable[..., str]):
|
|||||||
The decorated function.
|
The decorated function.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _inner_decorator(func):
|
def _inner_decorator(func: Callable):
|
||||||
def _inner(*args, **kwargs):
|
def _inner(*args, **kwargs):
|
||||||
payload = _read_cached_procedure_file(cache_file)
|
payload = _read_cached_procedure_file(cache_file)
|
||||||
new_payload = payload_fn(*args, **kwargs)
|
new_payload = payload_fn(*args, **kwargs)
|
||||||
@ -1188,7 +1190,7 @@ def install_frontend_packages(packages: set[str], config: Config):
|
|||||||
)
|
)
|
||||||
|
|
||||||
processes.run_process_with_fallback(
|
processes.run_process_with_fallback(
|
||||||
[install_package_manager, "install"], # type: ignore
|
[install_package_manager, "install"],
|
||||||
fallback=fallback_command,
|
fallback=fallback_command,
|
||||||
analytics_enabled=True,
|
analytics_enabled=True,
|
||||||
show_status_message="Installing base frontend packages",
|
show_status_message="Installing base frontend packages",
|
||||||
@ -1290,12 +1292,9 @@ def validate_bun():
|
|||||||
Raises:
|
Raises:
|
||||||
Exit: If custom specified bun does not exist or does not meet requirements.
|
Exit: If custom specified bun does not exist or does not meet requirements.
|
||||||
"""
|
"""
|
||||||
# if a custom bun path is provided, make sure its valid
|
bun_path = path_ops.get_bun_path()
|
||||||
# This is specific to non-FHS OS
|
|
||||||
bun_path = get_config().bun_path
|
if bun_path and bun_path.samefile(constants.Bun.DEFAULT_PATH):
|
||||||
if path_ops.use_system_bun():
|
|
||||||
bun_path = path_ops.which("bun")
|
|
||||||
if bun_path != constants.Bun.DEFAULT_PATH:
|
|
||||||
console.info(f"Using custom Bun path: {bun_path}")
|
console.info(f"Using custom Bun path: {bun_path}")
|
||||||
bun_version = get_bun_version()
|
bun_version = get_bun_version()
|
||||||
if not bun_version:
|
if not bun_version:
|
||||||
@ -1313,7 +1312,7 @@ def validate_bun():
|
|||||||
raise typer.Exit(1)
|
raise typer.Exit(1)
|
||||||
|
|
||||||
|
|
||||||
def validate_frontend_dependencies(init=True):
|
def validate_frontend_dependencies(init: bool = True):
|
||||||
"""Validate frontend dependencies to ensure they meet requirements.
|
"""Validate frontend dependencies to ensure they meet requirements.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1484,7 +1483,7 @@ def prompt_for_template_options(templates: list[Template]) -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Return the template.
|
# Return the template.
|
||||||
return templates[int(template)].name
|
return templates[int(template)].name # pyright: ignore [reportArgumentType]
|
||||||
|
|
||||||
|
|
||||||
def fetch_app_templates(version: str) -> dict[str, Template]:
|
def fetch_app_templates(version: str) -> dict[str, Template]:
|
||||||
@ -1637,7 +1636,9 @@ def initialize_default_app(app_name: str):
|
|||||||
initialize_app_directory(app_name)
|
initialize_app_directory(app_name)
|
||||||
|
|
||||||
|
|
||||||
def validate_and_create_app_using_remote_template(app_name, template, templates):
|
def validate_and_create_app_using_remote_template(
|
||||||
|
app_name: str, template: str, templates: dict[str, Template]
|
||||||
|
):
|
||||||
"""Validate and create an app using a remote template.
|
"""Validate and create an app using a remote template.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1849,7 +1850,7 @@ def initialize_main_module_index_from_generation(app_name: str, generation_hash:
|
|||||||
)
|
)
|
||||||
render_func_name = defined_funcs[-1]
|
render_func_name = defined_funcs[-1]
|
||||||
|
|
||||||
def replace_content(_match):
|
def replace_content(_match: re.Match) -> str:
|
||||||
return "\n".join(
|
return "\n".join(
|
||||||
[
|
[
|
||||||
resp.text,
|
resp.text,
|
||||||
@ -1879,7 +1880,7 @@ def initialize_main_module_index_from_generation(app_name: str, generation_hash:
|
|||||||
main_module_path.write_text(main_module_code)
|
main_module_path.write_text(main_module_code)
|
||||||
|
|
||||||
|
|
||||||
def format_address_width(address_width) -> int | None:
|
def format_address_width(address_width: str | None) -> int | None:
|
||||||
"""Cast address width to an int.
|
"""Cast address width to an int.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -9,18 +9,20 @@ import os
|
|||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
from concurrent import futures
|
from concurrent import futures
|
||||||
|
from pathlib import Path
|
||||||
from typing import Callable, Generator, List, Optional, Tuple, Union
|
from typing import Callable, Generator, List, Optional, Tuple, Union
|
||||||
|
|
||||||
import psutil
|
import psutil
|
||||||
import typer
|
import typer
|
||||||
from redis.exceptions import RedisError
|
from redis.exceptions import RedisError
|
||||||
|
from rich.progress import Progress
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.config import environment
|
from reflex.config import environment
|
||||||
from reflex.utils import console, path_ops, prerequisites
|
from reflex.utils import console, path_ops, prerequisites
|
||||||
|
|
||||||
|
|
||||||
def kill(pid):
|
def kill(pid: int):
|
||||||
"""Kill a process.
|
"""Kill a process.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -48,7 +50,7 @@ def get_num_workers() -> int:
|
|||||||
return (os.cpu_count() or 1) * 2 + 1
|
return (os.cpu_count() or 1) * 2 + 1
|
||||||
|
|
||||||
|
|
||||||
def get_process_on_port(port) -> Optional[psutil.Process]:
|
def get_process_on_port(port: int) -> Optional[psutil.Process]:
|
||||||
"""Get the process on the given port.
|
"""Get the process on the given port.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -62,7 +64,7 @@ def get_process_on_port(port) -> Optional[psutil.Process]:
|
|||||||
psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess
|
psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess
|
||||||
):
|
):
|
||||||
if importlib.metadata.version("psutil") >= "6.0.0":
|
if importlib.metadata.version("psutil") >= "6.0.0":
|
||||||
conns = proc.net_connections(kind="inet") # type: ignore
|
conns = proc.net_connections(kind="inet")
|
||||||
else:
|
else:
|
||||||
conns = proc.connections(kind="inet")
|
conns = proc.connections(kind="inet")
|
||||||
for conn in conns:
|
for conn in conns:
|
||||||
@ -71,7 +73,7 @@ def get_process_on_port(port) -> Optional[psutil.Process]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def is_process_on_port(port) -> bool:
|
def is_process_on_port(port: int) -> bool:
|
||||||
"""Check if a process is running on the given port.
|
"""Check if a process is running on the given port.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -83,7 +85,7 @@ def is_process_on_port(port) -> bool:
|
|||||||
return get_process_on_port(port) is not None
|
return get_process_on_port(port) is not None
|
||||||
|
|
||||||
|
|
||||||
def kill_process_on_port(port):
|
def kill_process_on_port(port: int):
|
||||||
"""Kill the process on the given port.
|
"""Kill the process on the given port.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -91,10 +93,10 @@ def kill_process_on_port(port):
|
|||||||
"""
|
"""
|
||||||
if get_process_on_port(port) is not None:
|
if get_process_on_port(port) is not None:
|
||||||
with contextlib.suppress(psutil.AccessDenied):
|
with contextlib.suppress(psutil.AccessDenied):
|
||||||
get_process_on_port(port).kill() # type: ignore
|
get_process_on_port(port).kill() # pyright: ignore [reportOptionalMemberAccess]
|
||||||
|
|
||||||
|
|
||||||
def change_port(port: str, _type: str) -> str:
|
def change_port(port: int, _type: str) -> int:
|
||||||
"""Change the port.
|
"""Change the port.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -105,7 +107,7 @@ def change_port(port: str, _type: str) -> str:
|
|||||||
The new port.
|
The new port.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
new_port = str(int(port) + 1)
|
new_port = port + 1
|
||||||
if is_process_on_port(new_port):
|
if is_process_on_port(new_port):
|
||||||
return change_port(new_port, _type)
|
return change_port(new_port, _type)
|
||||||
console.info(
|
console.info(
|
||||||
@ -114,7 +116,7 @@ def change_port(port: str, _type: str) -> str:
|
|||||||
return new_port
|
return new_port
|
||||||
|
|
||||||
|
|
||||||
def handle_port(service_name: str, port: str, default_port: str) -> str:
|
def handle_port(service_name: str, port: int, default_port: int) -> int:
|
||||||
"""Change port if the specified port is in use and is not explicitly specified as a CLI arg or config arg.
|
"""Change port if the specified port is in use and is not explicitly specified as a CLI arg or config arg.
|
||||||
otherwise tell the user the port is in use and exit the app.
|
otherwise tell the user the port is in use and exit the app.
|
||||||
|
|
||||||
@ -133,7 +135,7 @@ def handle_port(service_name: str, port: str, default_port: str) -> str:
|
|||||||
Exit:when the port is in use.
|
Exit:when the port is in use.
|
||||||
"""
|
"""
|
||||||
if is_process_on_port(port):
|
if is_process_on_port(port):
|
||||||
if int(port) == int(default_port):
|
if port == int(default_port):
|
||||||
return change_port(port, service_name)
|
return change_port(port, service_name)
|
||||||
else:
|
else:
|
||||||
console.error(f"{service_name.capitalize()} port: {port} is already in use")
|
console.error(f"{service_name.capitalize()} port: {port} is already in use")
|
||||||
@ -141,7 +143,12 @@ def handle_port(service_name: str, port: str, default_port: str) -> str:
|
|||||||
return port
|
return port
|
||||||
|
|
||||||
|
|
||||||
def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
|
def new_process(
|
||||||
|
args: str | list[str] | list[str | None] | list[str | Path | None],
|
||||||
|
run: bool = False,
|
||||||
|
show_logs: bool = False,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
"""Wrapper over subprocess.Popen to unify the launch of child processes.
|
"""Wrapper over subprocess.Popen to unify the launch of child processes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -157,7 +164,7 @@ def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
|
|||||||
Exit: When attempting to run a command with a None value.
|
Exit: When attempting to run a command with a None value.
|
||||||
"""
|
"""
|
||||||
# Check for invalid command first.
|
# Check for invalid command first.
|
||||||
if None in args:
|
if isinstance(args, list) and None in args:
|
||||||
console.error(f"Invalid command: {args}")
|
console.error(f"Invalid command: {args}")
|
||||||
raise typer.Exit(1)
|
raise typer.Exit(1)
|
||||||
|
|
||||||
@ -191,7 +198,7 @@ def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
|
|||||||
}
|
}
|
||||||
console.debug(f"Running command: {args}")
|
console.debug(f"Running command: {args}")
|
||||||
fn = subprocess.run if run else subprocess.Popen
|
fn = subprocess.run if run else subprocess.Popen
|
||||||
return fn(args, **kwargs)
|
return fn(args, **kwargs) # pyright: ignore [reportCallIssue, reportArgumentType]
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
@ -212,14 +219,14 @@ def run_concurrently_context(
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Convert the functions to tuples.
|
# Convert the functions to tuples.
|
||||||
fns = [fn if isinstance(fn, tuple) else (fn,) for fn in fns] # type: ignore
|
fns = [fn if isinstance(fn, tuple) else (fn,) for fn in fns] # pyright: ignore [reportAssignmentType]
|
||||||
|
|
||||||
# Run the functions concurrently.
|
# Run the functions concurrently.
|
||||||
executor = None
|
executor = None
|
||||||
try:
|
try:
|
||||||
executor = futures.ThreadPoolExecutor(max_workers=len(fns))
|
executor = futures.ThreadPoolExecutor(max_workers=len(fns))
|
||||||
# Submit the tasks.
|
# Submit the tasks.
|
||||||
tasks = [executor.submit(*fn) for fn in fns] # type: ignore
|
tasks = [executor.submit(*fn) for fn in fns] # pyright: ignore [reportArgumentType]
|
||||||
|
|
||||||
# Yield control back to the main thread while tasks are running.
|
# Yield control back to the main thread while tasks are running.
|
||||||
yield tasks
|
yield tasks
|
||||||
@ -247,7 +254,7 @@ def run_concurrently(*fns: Union[Callable, Tuple]) -> None:
|
|||||||
def stream_logs(
|
def stream_logs(
|
||||||
message: str,
|
message: str,
|
||||||
process: subprocess.Popen,
|
process: subprocess.Popen,
|
||||||
progress=None,
|
progress: Progress | None = None,
|
||||||
suppress_errors: bool = False,
|
suppress_errors: bool = False,
|
||||||
analytics_enabled: bool = False,
|
analytics_enabled: bool = False,
|
||||||
):
|
):
|
||||||
@ -375,10 +382,10 @@ def get_command_with_loglevel(command: list[str]) -> list[str]:
|
|||||||
|
|
||||||
|
|
||||||
def run_process_with_fallback(
|
def run_process_with_fallback(
|
||||||
args,
|
args: list[str],
|
||||||
*,
|
*,
|
||||||
show_status_message,
|
show_status_message: str,
|
||||||
fallback=None,
|
fallback: str | list | None = None,
|
||||||
analytics_enabled: bool = False,
|
analytics_enabled: bool = False,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
@ -417,7 +424,7 @@ def run_process_with_fallback(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def execute_command_and_return_output(command) -> str | None:
|
def execute_command_and_return_output(command: str) -> str | None:
|
||||||
"""Execute a command and return the output.
|
"""Execute a command and return the output.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -83,7 +83,7 @@ DEFAULT_IMPORTS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _walk_files(path):
|
def _walk_files(path: str | Path):
|
||||||
"""Walk all files in a path.
|
"""Walk all files in a path.
|
||||||
This can be replaced with Path.walk() in python3.12.
|
This can be replaced with Path.walk() in python3.12.
|
||||||
|
|
||||||
@ -114,7 +114,9 @@ def _relative_to_pwd(path: Path) -> Path:
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
|
def _get_type_hint(
|
||||||
|
value: Any, type_hint_globals: dict, is_optional: bool = True
|
||||||
|
) -> str:
|
||||||
"""Resolve the type hint for value.
|
"""Resolve the type hint for value.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -229,7 +231,7 @@ def _generate_imports(
|
|||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
*[
|
*[
|
||||||
ast.ImportFrom(module=name, names=[ast.alias(name=val) for val in values])
|
ast.ImportFrom(module=name, names=[ast.alias(name=val) for val in values]) # pyright: ignore [reportCallIssue]
|
||||||
for name, values in DEFAULT_IMPORTS.items()
|
for name, values in DEFAULT_IMPORTS.items()
|
||||||
],
|
],
|
||||||
ast.Import([ast.alias("reflex")]),
|
ast.Import([ast.alias("reflex")]),
|
||||||
@ -367,7 +369,7 @@ def _extract_class_props_as_ast_nodes(
|
|||||||
# Try to get default from pydantic field definition.
|
# Try to get default from pydantic field definition.
|
||||||
default = target_class.__fields__[name].default
|
default = target_class.__fields__[name].default
|
||||||
if isinstance(default, Var):
|
if isinstance(default, Var):
|
||||||
default = default._decode() # type: ignore
|
default = default._decode()
|
||||||
|
|
||||||
kwargs.append(
|
kwargs.append(
|
||||||
(
|
(
|
||||||
@ -383,7 +385,7 @@ def _extract_class_props_as_ast_nodes(
|
|||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
def type_to_ast(typ, cls: type) -> ast.AST:
|
def type_to_ast(typ: Any, cls: type) -> ast.AST:
|
||||||
"""Converts any type annotation into its AST representation.
|
"""Converts any type annotation into its AST representation.
|
||||||
Handles nested generic types, unions, etc.
|
Handles nested generic types, unions, etc.
|
||||||
|
|
||||||
@ -434,14 +436,16 @@ def type_to_ast(typ, cls: type) -> ast.AST:
|
|||||||
if len(arg_nodes) == 1:
|
if len(arg_nodes) == 1:
|
||||||
slice_value = arg_nodes[0]
|
slice_value = arg_nodes[0]
|
||||||
else:
|
else:
|
||||||
slice_value = ast.Tuple(elts=arg_nodes, ctx=ast.Load())
|
slice_value = ast.Tuple(elts=arg_nodes, ctx=ast.Load()) # pyright: ignore [reportArgumentType]
|
||||||
|
|
||||||
return ast.Subscript(
|
return ast.Subscript(
|
||||||
value=ast.Name(id=base_name), slice=ast.Index(value=slice_value), ctx=ast.Load()
|
value=ast.Name(id=base_name),
|
||||||
|
slice=ast.Index(value=slice_value), # pyright: ignore [reportArgumentType]
|
||||||
|
ctx=ast.Load(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _get_parent_imports(func):
|
def _get_parent_imports(func: Callable):
|
||||||
_imports = {"reflex.vars": ["Var"]}
|
_imports = {"reflex.vars": ["Var"]}
|
||||||
for type_hint in inspect.get_annotations(func).values():
|
for type_hint in inspect.get_annotations(func).values():
|
||||||
try:
|
try:
|
||||||
@ -575,7 +579,7 @@ def _generate_component_create_functiondef(
|
|||||||
arg=trigger,
|
arg=trigger,
|
||||||
annotation=ast.Subscript(
|
annotation=ast.Subscript(
|
||||||
ast.Name("Optional"),
|
ast.Name("Optional"),
|
||||||
ast.Index( # type: ignore
|
ast.Index( # pyright: ignore [reportArgumentType]
|
||||||
value=ast.Name(
|
value=ast.Name(
|
||||||
id=ast.unparse(
|
id=ast.unparse(
|
||||||
figure_out_return_type(
|
figure_out_return_type(
|
||||||
@ -621,7 +625,7 @@ def _generate_component_create_functiondef(
|
|||||||
definition = ast.FunctionDef(
|
definition = ast.FunctionDef(
|
||||||
name="create",
|
name="create",
|
||||||
args=create_args,
|
args=create_args,
|
||||||
body=[
|
body=[ # pyright: ignore [reportArgumentType]
|
||||||
ast.Expr(
|
ast.Expr(
|
||||||
value=ast.Constant(
|
value=ast.Constant(
|
||||||
value=_generate_docstrings(
|
value=_generate_docstrings(
|
||||||
@ -630,7 +634,7 @@ def _generate_component_create_functiondef(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
ast.Expr(
|
ast.Expr(
|
||||||
value=ast.Ellipsis(),
|
value=ast.Constant(value=Ellipsis),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
decorator_list=[
|
decorator_list=[
|
||||||
@ -641,7 +645,7 @@ def _generate_component_create_functiondef(
|
|||||||
else [ast.Name(id="classmethod")]
|
else [ast.Name(id="classmethod")]
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
lineno=node.lineno if node is not None else None,
|
lineno=node.lineno if node is not None else None, # pyright: ignore [reportArgumentType]
|
||||||
returns=ast.Constant(value=clz.__name__),
|
returns=ast.Constant(value=clz.__name__),
|
||||||
)
|
)
|
||||||
return definition
|
return definition
|
||||||
@ -690,7 +694,7 @@ def _generate_staticmethod_call_functiondef(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
decorator_list=[ast.Name(id="staticmethod")],
|
decorator_list=[ast.Name(id="staticmethod")],
|
||||||
lineno=node.lineno if node is not None else None,
|
lineno=node.lineno if node is not None else None, # pyright: ignore [reportArgumentType]
|
||||||
returns=ast.Constant(
|
returns=ast.Constant(
|
||||||
value=_get_type_hint(
|
value=_get_type_hint(
|
||||||
typing.get_type_hints(clz.__call__).get("return", None),
|
typing.get_type_hints(clz.__call__).get("return", None),
|
||||||
@ -726,17 +730,17 @@ def _generate_namespace_call_functiondef(
|
|||||||
clz = classes[clz_name]
|
clz = classes[clz_name]
|
||||||
|
|
||||||
if not hasattr(clz.__call__, "__self__"):
|
if not hasattr(clz.__call__, "__self__"):
|
||||||
return _generate_staticmethod_call_functiondef(node, clz, type_hint_globals) # type: ignore
|
return _generate_staticmethod_call_functiondef(node, clz, type_hint_globals) # pyright: ignore [reportArgumentType]
|
||||||
|
|
||||||
# Determine which class is wrapped by the namespace __call__ method
|
# Determine which class is wrapped by the namespace __call__ method
|
||||||
component_clz = clz.__call__.__self__
|
component_clz = clz.__call__.__self__
|
||||||
|
|
||||||
if clz.__call__.__func__.__name__ != "create":
|
if clz.__call__.__func__.__name__ != "create": # pyright: ignore [reportFunctionMemberAccess]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
definition = _generate_component_create_functiondef(
|
definition = _generate_component_create_functiondef(
|
||||||
node=None,
|
node=None,
|
||||||
clz=component_clz, # type: ignore
|
clz=component_clz, # pyright: ignore [reportArgumentType]
|
||||||
type_hint_globals=type_hint_globals,
|
type_hint_globals=type_hint_globals,
|
||||||
)
|
)
|
||||||
definition.name = "__call__"
|
definition.name = "__call__"
|
||||||
@ -816,7 +820,7 @@ class StubGenerator(ast.NodeTransformer):
|
|||||||
The modified Module node.
|
The modified Module node.
|
||||||
"""
|
"""
|
||||||
self.generic_visit(node)
|
self.generic_visit(node)
|
||||||
return self._remove_docstring(node) # type: ignore
|
return self._remove_docstring(node) # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
def visit_Import(
|
def visit_Import(
|
||||||
self, node: ast.Import | ast.ImportFrom
|
self, node: ast.Import | ast.ImportFrom
|
||||||
@ -914,7 +918,7 @@ class StubGenerator(ast.NodeTransformer):
|
|||||||
node.body.append(call_definition)
|
node.body.append(call_definition)
|
||||||
if not node.body:
|
if not node.body:
|
||||||
# We should never return an empty body.
|
# We should never return an empty body.
|
||||||
node.body.append(ast.Expr(value=ast.Ellipsis()))
|
node.body.append(ast.Expr(value=ast.Constant(value=Ellipsis)))
|
||||||
self.current_class = None
|
self.current_class = None
|
||||||
return node
|
return node
|
||||||
|
|
||||||
@ -941,9 +945,9 @@ class StubGenerator(ast.NodeTransformer):
|
|||||||
if node.name.startswith("_") and node.name != "__call__":
|
if node.name.startswith("_") and node.name != "__call__":
|
||||||
return None # remove private methods
|
return None # remove private methods
|
||||||
|
|
||||||
if node.body[-1] != ast.Expr(value=ast.Ellipsis()):
|
if node.body[-1] != ast.Expr(value=ast.Constant(value=Ellipsis)):
|
||||||
# Blank out the function body for public functions.
|
# Blank out the function body for public functions.
|
||||||
node.body = [ast.Expr(value=ast.Ellipsis())]
|
node.body = [ast.Expr(value=ast.Constant(value=Ellipsis))]
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def visit_Assign(self, node: ast.Assign) -> ast.Assign | None:
|
def visit_Assign(self, node: ast.Assign) -> ast.Assign | None:
|
||||||
@ -1050,7 +1054,7 @@ class PyiGenerator:
|
|||||||
pyi_path.write_text(pyi_content)
|
pyi_path.write_text(pyi_content)
|
||||||
logger.info(f"Wrote {relpath}")
|
logger.info(f"Wrote {relpath}")
|
||||||
|
|
||||||
def _get_init_lazy_imports(self, mod, new_tree):
|
def _get_init_lazy_imports(self, mod: tuple | ModuleType, new_tree: ast.AST):
|
||||||
# retrieve the _SUBMODULES and _SUBMOD_ATTRS from an init file if present.
|
# retrieve the _SUBMODULES and _SUBMOD_ATTRS from an init file if present.
|
||||||
sub_mods = getattr(mod, "_SUBMODULES", None)
|
sub_mods = getattr(mod, "_SUBMODULES", None)
|
||||||
sub_mod_attrs = getattr(mod, "_SUBMOD_ATTRS", None)
|
sub_mod_attrs = getattr(mod, "_SUBMOD_ATTRS", None)
|
||||||
@ -1077,7 +1081,7 @@ class PyiGenerator:
|
|||||||
+ (
|
+ (
|
||||||
" # type: ignore"
|
" # type: ignore"
|
||||||
if mod in pyright_ignore_imports
|
if mod in pyright_ignore_imports
|
||||||
else " # noqa" # ignore ruff formatting here for cases like rx.list.
|
else " # noqa: F401" # ignore ruff formatting here for cases like rx.list.
|
||||||
if isinstance(mod, tuple)
|
if isinstance(mod, tuple)
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
@ -1136,7 +1140,7 @@ class PyiGenerator:
|
|||||||
if pyi_path:
|
if pyi_path:
|
||||||
self.written_files.append(pyi_path)
|
self.written_files.append(pyi_path)
|
||||||
|
|
||||||
def scan_all(self, targets, changed_files: list[Path] | None = None):
|
def scan_all(self, targets: list, changed_files: list[Path] | None = None):
|
||||||
"""Scan all targets for class inheriting Component and generate the .pyi files.
|
"""Scan all targets for class inheriting Component and generate the .pyi files.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -22,15 +22,15 @@ def latency(registry: str) -> int:
|
|||||||
return 10_000_000
|
return 10_000_000
|
||||||
|
|
||||||
|
|
||||||
def average_latency(registry, attempts: int = 3) -> int:
|
def average_latency(registry: str, attempts: int = 3) -> int:
|
||||||
"""Get the average latency of a registry.
|
"""Get the average latency of a registry.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
registry (str): The URL of the registry.
|
registry: The URL of the registry.
|
||||||
attempts (int): The number of attempts to make. Defaults to 10.
|
attempts: The number of attempts to make. Defaults to 10.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: The average latency of the registry in microseconds.
|
The average latency of the registry in microseconds.
|
||||||
"""
|
"""
|
||||||
return sum(latency(registry) for _ in range(attempts)) // attempts
|
return sum(latency(registry) for _ in range(attempts)) // attempts
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ try:
|
|||||||
base64_image = base64.b64encode(image_bytes).decode("utf-8")
|
base64_image = base64.b64encode(image_bytes).decode("utf-8")
|
||||||
try:
|
try:
|
||||||
# Newer method to get the mime type, but does not always work.
|
# Newer method to get the mime type, but does not always work.
|
||||||
mime_type = image.get_format_mimetype() # type: ignore
|
mime_type = image.get_format_mimetype() # pyright: ignore [reportAttributeAccessIssue]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
# Fallback method
|
# Fallback method
|
||||||
|
@ -162,7 +162,7 @@ def _send_event(event_data: dict) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _send(event, telemetry_enabled, **kwargs):
|
def _send(event: str, telemetry_enabled: bool | None, **kwargs):
|
||||||
from reflex.config import get_config
|
from reflex.config import get_config
|
||||||
|
|
||||||
# Get the telemetry_enabled from the config if it is not specified.
|
# Get the telemetry_enabled from the config if it is not specified.
|
||||||
@ -189,7 +189,7 @@ def send(event: str, telemetry_enabled: bool | None = None, **kwargs):
|
|||||||
kwargs: Additional data to send with the event.
|
kwargs: Additional data to send with the event.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def async_send(event, telemetry_enabled, **kwargs):
|
async def async_send(event: str, telemetry_enabled: bool | None, **kwargs):
|
||||||
return _send(event, telemetry_enabled, **kwargs)
|
return _send(event, telemetry_enabled, **kwargs)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -24,7 +24,7 @@ from typing import (
|
|||||||
Tuple,
|
Tuple,
|
||||||
Type,
|
Type,
|
||||||
Union,
|
Union,
|
||||||
_GenericAlias, # type: ignore
|
_GenericAlias, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
get_args,
|
get_args,
|
||||||
get_type_hints,
|
get_type_hints,
|
||||||
)
|
)
|
||||||
@ -39,7 +39,9 @@ from reflex.components.core.breakpoints import Breakpoints
|
|||||||
try:
|
try:
|
||||||
from pydantic.v1.fields import ModelField
|
from pydantic.v1.fields import ModelField
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
from pydantic.fields import ModelField # type: ignore
|
from pydantic.fields import (
|
||||||
|
ModelField, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
|
)
|
||||||
|
|
||||||
from sqlalchemy.ext.associationproxy import AssociationProxyInstance
|
from sqlalchemy.ext.associationproxy import AssociationProxyInstance
|
||||||
from sqlalchemy.ext.hybrid import hybrid_property
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
@ -70,13 +72,15 @@ GenericAliasTypes = [_GenericAlias]
|
|||||||
|
|
||||||
with contextlib.suppress(ImportError):
|
with contextlib.suppress(ImportError):
|
||||||
# For newer versions of Python.
|
# For newer versions of Python.
|
||||||
from types import GenericAlias # type: ignore
|
from types import GenericAlias
|
||||||
|
|
||||||
GenericAliasTypes.append(GenericAlias)
|
GenericAliasTypes.append(GenericAlias)
|
||||||
|
|
||||||
with contextlib.suppress(ImportError):
|
with contextlib.suppress(ImportError):
|
||||||
# For older versions of Python.
|
# For older versions of Python.
|
||||||
from typing import _SpecialGenericAlias # type: ignore
|
from typing import (
|
||||||
|
_SpecialGenericAlias, # pyright: ignore [reportAttributeAccessIssue]
|
||||||
|
)
|
||||||
|
|
||||||
GenericAliasTypes.append(_SpecialGenericAlias)
|
GenericAliasTypes.append(_SpecialGenericAlias)
|
||||||
|
|
||||||
@ -153,7 +157,7 @@ class Unset:
|
|||||||
|
|
||||||
|
|
||||||
@lru_cache()
|
@lru_cache()
|
||||||
def get_origin(tp):
|
def get_origin(tp: Any):
|
||||||
"""Get the origin of a class.
|
"""Get the origin of a class.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -175,7 +179,7 @@ def is_generic_alias(cls: GenericType) -> bool:
|
|||||||
Returns:
|
Returns:
|
||||||
Whether the class is a generic alias.
|
Whether the class is a generic alias.
|
||||||
"""
|
"""
|
||||||
return isinstance(cls, GenericAliasTypes)
|
return isinstance(cls, GenericAliasTypes) # pyright: ignore [reportArgumentType]
|
||||||
|
|
||||||
|
|
||||||
def unionize(*args: GenericType) -> Type:
|
def unionize(*args: GenericType) -> Type:
|
||||||
@ -188,14 +192,14 @@ def unionize(*args: GenericType) -> Type:
|
|||||||
The unionized types.
|
The unionized types.
|
||||||
"""
|
"""
|
||||||
if not args:
|
if not args:
|
||||||
return Any
|
return Any # pyright: ignore [reportReturnType]
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
return args[0]
|
return args[0]
|
||||||
# We are bisecting the args list here to avoid hitting the recursion limit
|
# We are bisecting the args list here to avoid hitting the recursion limit
|
||||||
# In Python versions >= 3.11, we can simply do `return Union[*args]`
|
# In Python versions >= 3.11, we can simply do `return Union[*args]`
|
||||||
midpoint = len(args) // 2
|
midpoint = len(args) // 2
|
||||||
first_half, second_half = args[:midpoint], args[midpoint:]
|
first_half, second_half = args[:midpoint], args[midpoint:]
|
||||||
return Union[unionize(*first_half), unionize(*second_half)]
|
return Union[unionize(*first_half), unionize(*second_half)] # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
|
|
||||||
def is_none(cls: GenericType) -> bool:
|
def is_none(cls: GenericType) -> bool:
|
||||||
@ -236,7 +240,7 @@ def is_literal(cls: GenericType) -> bool:
|
|||||||
return get_origin(cls) is Literal
|
return get_origin(cls) is Literal
|
||||||
|
|
||||||
|
|
||||||
def has_args(cls) -> bool:
|
def has_args(cls: Type) -> bool:
|
||||||
"""Check if the class has generic parameters.
|
"""Check if the class has generic parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -351,13 +355,13 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
|
|||||||
if type_ is not None:
|
if type_ is not None:
|
||||||
if hasattr(column_type, "item_type"):
|
if hasattr(column_type, "item_type"):
|
||||||
try:
|
try:
|
||||||
item_type = column_type.item_type.python_type # type: ignore
|
item_type = column_type.item_type.python_type # pyright: ignore [reportAttributeAccessIssue]
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
item_type = None
|
item_type = None
|
||||||
if item_type is not None:
|
if item_type is not None:
|
||||||
if type_ in PrimitiveToAnnotation:
|
if type_ in PrimitiveToAnnotation:
|
||||||
type_ = PrimitiveToAnnotation[type_] # type: ignore
|
type_ = PrimitiveToAnnotation[type_]
|
||||||
type_ = type_[item_type] # type: ignore
|
type_ = type_[item_type] # pyright: ignore [reportIndexIssue]
|
||||||
if column.nullable:
|
if column.nullable:
|
||||||
type_ = Optional[type_]
|
type_ = Optional[type_]
|
||||||
return type_
|
return type_
|
||||||
@ -432,7 +436,7 @@ def get_base_class(cls: GenericType) -> Type:
|
|||||||
return type(get_args(cls)[0])
|
return type(get_args(cls)[0])
|
||||||
|
|
||||||
if is_union(cls):
|
if is_union(cls):
|
||||||
return tuple(get_base_class(arg) for arg in get_args(cls))
|
return tuple(get_base_class(arg) for arg in get_args(cls)) # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
return get_base_class(cls.__origin__) if is_generic_alias(cls) else cls
|
return get_base_class(cls.__origin__) if is_generic_alias(cls) else cls
|
||||||
|
|
||||||
@ -605,7 +609,9 @@ def _isinstance(obj: Any, cls: GenericType, nested: bool = False) -> bool:
|
|||||||
return (
|
return (
|
||||||
isinstance(obj, tuple)
|
isinstance(obj, tuple)
|
||||||
and len(obj) == len(args)
|
and len(obj) == len(args)
|
||||||
and all(_isinstance(item, arg) for item, arg in zip(obj, args))
|
and all(
|
||||||
|
_isinstance(item, arg) for item, arg in zip(obj, args, strict=True)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if origin in (dict, Breakpoints):
|
if origin in (dict, Breakpoints):
|
||||||
return isinstance(obj, dict) and all(
|
return isinstance(obj, dict) and all(
|
||||||
@ -747,7 +753,7 @@ def check_prop_in_allowed_types(prop: Any, allowed_types: Iterable) -> bool:
|
|||||||
return type_ in allowed_types
|
return type_ in allowed_types
|
||||||
|
|
||||||
|
|
||||||
def is_encoded_fstring(value) -> bool:
|
def is_encoded_fstring(value: Any) -> bool:
|
||||||
"""Check if a value is an encoded Var f-string.
|
"""Check if a value is an encoded Var f-string.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -790,7 +796,7 @@ def validate_literal(key: str, value: Any, expected_type: Type, comp_name: str):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def validate_parameter_literals(func):
|
def validate_parameter_literals(func: Callable):
|
||||||
"""Decorator to check that the arguments passed to a function
|
"""Decorator to check that the arguments passed to a function
|
||||||
correspond to the correct function parameter if it (the parameter)
|
correspond to the correct function parameter if it (the parameter)
|
||||||
is a literal type.
|
is a literal type.
|
||||||
@ -808,7 +814,7 @@ def validate_parameter_literals(func):
|
|||||||
annotations = {param[0]: param[1].annotation for param in func_params}
|
annotations = {param[0]: param[1].annotation for param in func_params}
|
||||||
|
|
||||||
# validate args
|
# validate args
|
||||||
for param, arg in zip(annotations, args):
|
for param, arg in zip(annotations, args, strict=False):
|
||||||
if annotations[param] is inspect.Parameter.empty:
|
if annotations[param] is inspect.Parameter.empty:
|
||||||
continue
|
continue
|
||||||
validate_literal(param, arg, annotations[param], func.__name__)
|
validate_literal(param, arg, annotations[param], func.__name__)
|
||||||
@ -906,6 +912,8 @@ def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> boo
|
|||||||
# It also ignores when the length of the arguments is different
|
# It also ignores when the length of the arguments is different
|
||||||
return all(
|
return all(
|
||||||
typehint_issubclass(provided_arg, accepted_arg)
|
typehint_issubclass(provided_arg, accepted_arg)
|
||||||
for provided_arg, accepted_arg in zip(provided_args, accepted_args)
|
for provided_arg, accepted_arg in zip(
|
||||||
|
provided_args, accepted_args, strict=False
|
||||||
|
)
|
||||||
if accepted_arg is not Any
|
if accepted_arg is not Any
|
||||||
)
|
)
|
||||||
|
@ -79,6 +79,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
VAR_TYPE = TypeVar("VAR_TYPE", covariant=True)
|
VAR_TYPE = TypeVar("VAR_TYPE", covariant=True)
|
||||||
OTHER_VAR_TYPE = TypeVar("OTHER_VAR_TYPE")
|
OTHER_VAR_TYPE = TypeVar("OTHER_VAR_TYPE")
|
||||||
|
STRING_T = TypeVar("STRING_T", bound=str)
|
||||||
|
|
||||||
warnings.filterwarnings("ignore", message="fields may not start with an underscore")
|
warnings.filterwarnings("ignore", message="fields may not start with an underscore")
|
||||||
|
|
||||||
@ -144,9 +145,7 @@ class VarData:
|
|||||||
position: Position of the hook in the component.
|
position: Position of the hook in the component.
|
||||||
"""
|
"""
|
||||||
immutable_imports: ImmutableParsedImportDict = tuple(
|
immutable_imports: ImmutableParsedImportDict = tuple(
|
||||||
sorted(
|
(k, tuple(v)) for k, v in parse_imports(imports or {}).items()
|
||||||
((k, tuple(sorted(v))) for k, v in parse_imports(imports or {}).items())
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
object.__setattr__(self, "state", state)
|
object.__setattr__(self, "state", state)
|
||||||
object.__setattr__(self, "field_name", field_name)
|
object.__setattr__(self, "field_name", field_name)
|
||||||
@ -494,20 +493,30 @@ class Var(Generic[VAR_TYPE]):
|
|||||||
|
|
||||||
@overload
|
@overload
|
||||||
def _replace(
|
def _replace(
|
||||||
self, _var_type: Type[OTHER_VAR_TYPE], merge_var_data=None, **kwargs: Any
|
self,
|
||||||
|
_var_type: Type[OTHER_VAR_TYPE],
|
||||||
|
merge_var_data: VarData | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
) -> Var[OTHER_VAR_TYPE]: ...
|
) -> Var[OTHER_VAR_TYPE]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def _replace(
|
def _replace(
|
||||||
self, _var_type: GenericType | None = None, merge_var_data=None, **kwargs: Any
|
self,
|
||||||
|
_var_type: GenericType | None = None,
|
||||||
|
merge_var_data: VarData | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
) -> Self: ...
|
) -> Self: ...
|
||||||
|
|
||||||
def _replace(
|
def _replace(
|
||||||
self, _var_type: GenericType | None = None, merge_var_data=None, **kwargs: Any
|
self,
|
||||||
|
_var_type: GenericType | None = None,
|
||||||
|
merge_var_data: VarData | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
) -> Self | Var:
|
) -> Self | Var:
|
||||||
"""Make a copy of this Var with updated fields.
|
"""Make a copy of this Var with updated fields.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
_var_type: The new type of the Var.
|
||||||
merge_var_data: VarData to merge into the existing VarData.
|
merge_var_data: VarData to merge into the existing VarData.
|
||||||
**kwargs: Var fields to update.
|
**kwargs: Var fields to update.
|
||||||
|
|
||||||
@ -541,12 +550,60 @@ class Var(Generic[VAR_TYPE]):
|
|||||||
|
|
||||||
return value_with_replaced
|
return value_with_replaced
|
||||||
|
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create( # type: ignore[override]
|
||||||
|
cls,
|
||||||
|
value: bool,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> BooleanVar: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create( # type: ignore[override]
|
||||||
|
cls,
|
||||||
|
value: int,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> NumberVar[int]: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(
|
||||||
cls,
|
cls,
|
||||||
value: Any,
|
value: float,
|
||||||
_var_data: VarData | None = None,
|
_var_data: VarData | None = None,
|
||||||
) -> Var:
|
) -> NumberVar[float]: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: STRING_T,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> StringVar[STRING_T]: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: None,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> NoneVar: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: OTHER_VAR_TYPE,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> Var[OTHER_VAR_TYPE]: ...
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: OTHER_VAR_TYPE,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> Var[OTHER_VAR_TYPE]:
|
||||||
"""Create a var from a value.
|
"""Create a var from a value.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -663,7 +720,7 @@ class Var(Generic[VAR_TYPE]):
|
|||||||
return self.to(var_subclass.var_subclass, output)
|
return self.to(var_subclass.var_subclass, output)
|
||||||
|
|
||||||
if fixed_output_type is None:
|
if fixed_output_type is None:
|
||||||
return get_to_operation(NoneVar).create(self) # type: ignore
|
return get_to_operation(NoneVar).create(self) # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
# Handle fixed_output_type being Base or a dataclass.
|
# Handle fixed_output_type being Base or a dataclass.
|
||||||
if can_use_in_object_var(fixed_output_type):
|
if can_use_in_object_var(fixed_output_type):
|
||||||
@ -680,7 +737,7 @@ class Var(Generic[VAR_TYPE]):
|
|||||||
to_operation_return = var_subclass.to_var_subclass.create(
|
to_operation_return = var_subclass.to_var_subclass.create(
|
||||||
value=self, _var_type=new_var_type
|
value=self, _var_type=new_var_type
|
||||||
)
|
)
|
||||||
return to_operation_return # type: ignore
|
return to_operation_return # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
# If we can't determine the first argument, we just replace the _var_type.
|
# If we can't determine the first argument, we just replace the _var_type.
|
||||||
if not issubclass(output, Var) or var_type is None:
|
if not issubclass(output, Var) or var_type is None:
|
||||||
@ -1096,7 +1153,7 @@ class Var(Generic[VAR_TYPE]):
|
|||||||
The decoded value or the Var name.
|
The decoded value or the Var name.
|
||||||
"""
|
"""
|
||||||
if isinstance(self, LiteralVar):
|
if isinstance(self, LiteralVar):
|
||||||
return self._var_value # type: ignore
|
return self._var_value
|
||||||
try:
|
try:
|
||||||
return json.loads(str(self))
|
return json.loads(str(self))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -1223,7 +1280,7 @@ class ToOperation:
|
|||||||
"""
|
"""
|
||||||
return VarData.merge(
|
return VarData.merge(
|
||||||
self._original._get_all_var_data(),
|
self._original._get_all_var_data(),
|
||||||
self._var_data, # type: ignore
|
self._var_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -1244,10 +1301,10 @@ class ToOperation:
|
|||||||
The ToOperation.
|
The ToOperation.
|
||||||
"""
|
"""
|
||||||
return cls(
|
return cls(
|
||||||
_js_expr="", # type: ignore
|
_js_expr="", # pyright: ignore [reportCallIssue]
|
||||||
_var_data=_var_data, # type: ignore
|
_var_data=_var_data, # pyright: ignore [reportCallIssue]
|
||||||
_var_type=_var_type or cls._default_var_type, # type: ignore
|
_var_type=_var_type or cls._default_var_type, # pyright: ignore [reportCallIssue, reportAttributeAccessIssue]
|
||||||
_original=value, # type: ignore
|
_original=value, # pyright: ignore [reportCallIssue]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1309,7 +1366,7 @@ class LiteralVar(Var):
|
|||||||
_var_literal_subclasses.append((cls, var_subclass))
|
_var_literal_subclasses.append((cls, var_subclass))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create( # pyright: ignore [reportArgumentType]
|
||||||
cls,
|
cls,
|
||||||
value: Any,
|
value: Any,
|
||||||
_var_data: VarData | None = None,
|
_var_data: VarData | None = None,
|
||||||
@ -1436,7 +1493,7 @@ T = TypeVar("T")
|
|||||||
|
|
||||||
# NoReturn is used to match CustomVarOperationReturn with no type hint.
|
# NoReturn is used to match CustomVarOperationReturn with no type hint.
|
||||||
@overload
|
@overload
|
||||||
def var_operation(
|
def var_operation( # pyright: ignore [reportOverlappingOverload]
|
||||||
func: Callable[P, CustomVarOperationReturn[NoReturn]],
|
func: Callable[P, CustomVarOperationReturn[NoReturn]],
|
||||||
) -> Callable[P, Var]: ...
|
) -> Callable[P, Var]: ...
|
||||||
|
|
||||||
@ -1486,7 +1543,7 @@ def var_operation(
|
|||||||
) -> Callable[P, Var[T]]: ...
|
) -> Callable[P, Var[T]]: ...
|
||||||
|
|
||||||
|
|
||||||
def var_operation(
|
def var_operation( # pyright: ignore [reportInconsistentOverload]
|
||||||
func: Callable[P, CustomVarOperationReturn[T]],
|
func: Callable[P, CustomVarOperationReturn[T]],
|
||||||
) -> Callable[P, Var[T]]:
|
) -> Callable[P, Var[T]]:
|
||||||
"""Decorator for creating a var operation.
|
"""Decorator for creating a var operation.
|
||||||
@ -1520,7 +1577,7 @@ def var_operation(
|
|||||||
return CustomVarOperation.create(
|
return CustomVarOperation.create(
|
||||||
name=func.__name__,
|
name=func.__name__,
|
||||||
args=tuple(list(args_vars.items()) + list(kwargs_vars.items())),
|
args=tuple(list(args_vars.items()) + list(kwargs_vars.items())),
|
||||||
return_var=func(*args_vars.values(), **kwargs_vars), # type: ignore
|
return_var=func(*args_vars.values(), **kwargs_vars), # pyright: ignore [reportCallIssue, reportReturnType]
|
||||||
).guess_type()
|
).guess_type()
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
@ -1557,7 +1614,7 @@ def figure_out_type(value: Any) -> types.GenericType:
|
|||||||
class cached_property_no_lock(functools.cached_property): # noqa: N801
|
class cached_property_no_lock(functools.cached_property): # noqa: N801
|
||||||
"""A special version of functools.cached_property that does not use a lock."""
|
"""A special version of functools.cached_property that does not use a lock."""
|
||||||
|
|
||||||
def __init__(self, func):
|
def __init__(self, func: Callable):
|
||||||
"""Initialize the cached_property_no_lock.
|
"""Initialize the cached_property_no_lock.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1590,7 +1647,7 @@ class CachedVarOperation:
|
|||||||
|
|
||||||
next_class = parent_classes[parent_classes.index(CachedVarOperation) + 1]
|
next_class = parent_classes[parent_classes.index(CachedVarOperation) + 1]
|
||||||
|
|
||||||
return next_class.__getattr__(self, name) # type: ignore
|
return next_class.__getattr__(self, name)
|
||||||
|
|
||||||
def _get_all_var_data(self) -> VarData | None:
|
def _get_all_var_data(self) -> VarData | None:
|
||||||
"""Get all VarData associated with the Var.
|
"""Get all VarData associated with the Var.
|
||||||
@ -1612,7 +1669,7 @@ class CachedVarOperation:
|
|||||||
value._get_all_var_data() if isinstance(value, Var) else None
|
value._get_all_var_data() if isinstance(value, Var) else None
|
||||||
for value in (
|
for value in (
|
||||||
getattr(self, field.name)
|
getattr(self, field.name)
|
||||||
for field in dataclasses.fields(self) # type: ignore
|
for field in dataclasses.fields(self) # pyright: ignore [reportArgumentType]
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
self._var_data,
|
self._var_data,
|
||||||
@ -1629,7 +1686,7 @@ class CachedVarOperation:
|
|||||||
type(self).__name__,
|
type(self).__name__,
|
||||||
*[
|
*[
|
||||||
getattr(self, field.name)
|
getattr(self, field.name)
|
||||||
for field in dataclasses.fields(self) # type: ignore
|
for field in dataclasses.fields(self) # pyright: ignore [reportArgumentType]
|
||||||
if field.name not in ["_js_expr", "_var_data", "_var_type"]
|
if field.name not in ["_js_expr", "_var_data", "_var_type"]
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -1646,7 +1703,7 @@ def and_operation(a: Var | Any, b: Var | Any) -> Var:
|
|||||||
Returns:
|
Returns:
|
||||||
The result of the logical AND operation.
|
The result of the logical AND operation.
|
||||||
"""
|
"""
|
||||||
return _and_operation(a, b) # type: ignore
|
return _and_operation(a, b)
|
||||||
|
|
||||||
|
|
||||||
@var_operation
|
@var_operation
|
||||||
@ -1676,7 +1733,7 @@ def or_operation(a: Var | Any, b: Var | Any) -> Var:
|
|||||||
Returns:
|
Returns:
|
||||||
The result of the logical OR operation.
|
The result of the logical OR operation.
|
||||||
"""
|
"""
|
||||||
return _or_operation(a, b) # type: ignore
|
return _or_operation(a, b)
|
||||||
|
|
||||||
|
|
||||||
@var_operation
|
@var_operation
|
||||||
@ -1730,7 +1787,7 @@ class CallableVar(Var):
|
|||||||
object.__setattr__(self, "fn", fn)
|
object.__setattr__(self, "fn", fn)
|
||||||
object.__setattr__(self, "original_var", original_var)
|
object.__setattr__(self, "original_var", original_var)
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs) -> Var:
|
def __call__(self, *args: Any, **kwargs: Any) -> Var:
|
||||||
"""Call the decorated function.
|
"""Call the decorated function.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1805,7 +1862,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|||||||
|
|
||||||
_fget: Callable[[BaseState], RETURN_TYPE] = dataclasses.field(
|
_fget: Callable[[BaseState], RETURN_TYPE] = dataclasses.field(
|
||||||
default_factory=lambda: lambda _: None
|
default_factory=lambda: lambda _: None
|
||||||
) # type: ignore
|
) # pyright: ignore [reportAssignmentType]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -1899,10 +1956,16 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|||||||
object.__setattr__(self, "_fget", fget)
|
object.__setattr__(self, "_fget", fget)
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def _replace(self, merge_var_data=None, **kwargs: Any) -> Self:
|
def _replace(
|
||||||
|
self,
|
||||||
|
_var_type: Any = None,
|
||||||
|
merge_var_data: VarData | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Self:
|
||||||
"""Replace the attributes of the ComputedVar.
|
"""Replace the attributes of the ComputedVar.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
_var_type: ignored in ComputedVar.
|
||||||
merge_var_data: VarData to merge into the existing VarData.
|
merge_var_data: VarData to merge into the existing VarData.
|
||||||
**kwargs: Var fields to update.
|
**kwargs: Var fields to update.
|
||||||
|
|
||||||
@ -2016,7 +2079,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|||||||
@overload
|
@overload
|
||||||
def __get__(self, instance: BaseState, owner: Type) -> RETURN_TYPE: ...
|
def __get__(self, instance: BaseState, owner: Type) -> RETURN_TYPE: ...
|
||||||
|
|
||||||
def __get__(self, instance: BaseState | None, owner):
|
def __get__(self, instance: BaseState | None, owner: Type):
|
||||||
"""Get the ComputedVar value.
|
"""Get the ComputedVar value.
|
||||||
|
|
||||||
If the value is already cached on the instance, return the cached value.
|
If the value is already cached on the instance, return the cached value.
|
||||||
@ -2063,7 +2126,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _check_deprecated_return_type(self, instance, value) -> None:
|
def _check_deprecated_return_type(self, instance: BaseState, value: Any) -> None:
|
||||||
if not _isinstance(value, self._var_type):
|
if not _isinstance(value, self._var_type):
|
||||||
console.error(
|
console.error(
|
||||||
f"Computed var '{type(instance).__name__}.{self._js_expr}' must return"
|
f"Computed var '{type(instance).__name__}.{self._js_expr}' must return"
|
||||||
@ -2121,7 +2184,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|||||||
)
|
)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def mark_dirty(self, instance) -> None:
|
def mark_dirty(self, instance: BaseState) -> None:
|
||||||
"""Mark this ComputedVar as dirty.
|
"""Mark this ComputedVar as dirty.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -2170,7 +2233,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
|||||||
hints = get_type_hints(self._fget)
|
hints = get_type_hints(self._fget)
|
||||||
if "return" in hints:
|
if "return" in hints:
|
||||||
return hints["return"]
|
return hints["return"]
|
||||||
return Any
|
return Any # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def __class__(self) -> Type:
|
def __class__(self) -> Type:
|
||||||
@ -2279,7 +2342,7 @@ class AsyncComputedVar(ComputedVar[RETURN_TYPE]):
|
|||||||
|
|
||||||
if not self._cache:
|
if not self._cache:
|
||||||
|
|
||||||
async def _awaitable_result(instance=instance) -> RETURN_TYPE:
|
async def _awaitable_result(instance: BaseState = instance) -> RETURN_TYPE:
|
||||||
value = await self.fget(instance)
|
value = await self.fget(instance)
|
||||||
self._check_deprecated_return_type(instance, value)
|
self._check_deprecated_return_type(instance, value)
|
||||||
return value
|
return value
|
||||||
@ -2287,7 +2350,7 @@ class AsyncComputedVar(ComputedVar[RETURN_TYPE]):
|
|||||||
return _awaitable_result()
|
return _awaitable_result()
|
||||||
else:
|
else:
|
||||||
# handle caching
|
# handle caching
|
||||||
async def _awaitable_result(instance=instance) -> RETURN_TYPE:
|
async def _awaitable_result(instance: BaseState = instance) -> RETURN_TYPE:
|
||||||
if not hasattr(instance, self._cache_attr) or self.needs_update(
|
if not hasattr(instance, self._cache_attr) or self.needs_update(
|
||||||
instance
|
instance
|
||||||
):
|
):
|
||||||
@ -2327,7 +2390,7 @@ def computed_var(
|
|||||||
interval: Optional[Union[datetime.timedelta, int]] = None,
|
interval: Optional[Union[datetime.timedelta, int]] = None,
|
||||||
backend: bool | None = None,
|
backend: bool | None = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> Callable[[Callable[[BASE_STATE], RETURN_TYPE]], ComputedVar[RETURN_TYPE]]: ...
|
) -> Callable[[Callable[[BASE_STATE], RETURN_TYPE]], ComputedVar[RETURN_TYPE]]: ... # pyright: ignore [reportInvalidTypeVarUse]
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -2673,7 +2736,7 @@ def get_uuid_string_var() -> Var:
|
|||||||
unique_uuid_var = get_unique_variable_name()
|
unique_uuid_var = get_unique_variable_name()
|
||||||
unique_uuid_var_data = VarData(
|
unique_uuid_var_data = VarData(
|
||||||
imports={
|
imports={
|
||||||
f"$/{constants.Dirs.STATE_PATH}": {ImportVar(tag="generateUUID")}, # type: ignore
|
f"$/{constants.Dirs.STATE_PATH}": {ImportVar(tag="generateUUID")}, # pyright: ignore [reportArgumentType]
|
||||||
"react": "useMemo",
|
"react": "useMemo",
|
||||||
},
|
},
|
||||||
hooks={f"const {unique_uuid_var} = useMemo(generateUUID, [])": None},
|
hooks={f"const {unique_uuid_var} = useMemo(generateUUID, [])": None},
|
||||||
@ -2733,7 +2796,7 @@ def _extract_var_data(value: Iterable) -> list[VarData | None]:
|
|||||||
elif not isinstance(sub, str):
|
elif not isinstance(sub, str):
|
||||||
# Recurse into dict values.
|
# Recurse into dict values.
|
||||||
if hasattr(sub, "values") and callable(sub.values):
|
if hasattr(sub, "values") and callable(sub.values):
|
||||||
var_datas.extend(_extract_var_data(sub.values()))
|
var_datas.extend(_extract_var_data(sub.values())) # pyright: ignore [reportArgumentType]
|
||||||
# Recurse into iterable values (or dict keys).
|
# Recurse into iterable values (or dict keys).
|
||||||
var_datas.extend(_extract_var_data(sub))
|
var_datas.extend(_extract_var_data(sub))
|
||||||
|
|
||||||
@ -2744,7 +2807,7 @@ def _extract_var_data(value: Iterable) -> list[VarData | None]:
|
|||||||
# Recurse when value is a dict itself.
|
# Recurse when value is a dict itself.
|
||||||
values = getattr(value, "values", None)
|
values = getattr(value, "values", None)
|
||||||
if callable(values):
|
if callable(values):
|
||||||
var_datas.extend(_extract_var_data(values()))
|
var_datas.extend(_extract_var_data(values())) # pyright: ignore [reportArgumentType]
|
||||||
return var_datas
|
return var_datas
|
||||||
|
|
||||||
|
|
||||||
@ -2841,7 +2904,7 @@ def generic_type_to_actual_type_map(
|
|||||||
# call recursively for nested generic types and merge the results
|
# call recursively for nested generic types and merge the results
|
||||||
return {
|
return {
|
||||||
k: v
|
k: v
|
||||||
for generic_arg, actual_arg in zip(generic_args, actual_args)
|
for generic_arg, actual_arg in zip(generic_args, actual_args, strict=True)
|
||||||
for k, v in generic_type_to_actual_type_map(generic_arg, actual_arg).items()
|
for k, v in generic_type_to_actual_type_map(generic_arg, actual_arg).items()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3007,7 +3070,7 @@ MAPPING_TYPE = TypeVar("MAPPING_TYPE", bound=Mapping)
|
|||||||
class Field(Generic[FIELD_TYPE]):
|
class Field(Generic[FIELD_TYPE]):
|
||||||
"""Shadow class for Var to allow for type hinting in the IDE."""
|
"""Shadow class for Var to allow for type hinting in the IDE."""
|
||||||
|
|
||||||
def __set__(self, instance, value: FIELD_TYPE):
|
def __set__(self, instance: Any, value: FIELD_TYPE):
|
||||||
"""Set the Var.
|
"""Set the Var.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3016,43 +3079,43 @@ class Field(Generic[FIELD_TYPE]):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(self: Field[bool], instance: None, owner) -> BooleanVar: ...
|
def __get__(self: Field[bool], instance: None, owner: Any) -> BooleanVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(
|
def __get__(
|
||||||
self: Field[int] | Field[float] | Field[int | float], instance: None, owner
|
self: Field[int] | Field[float] | Field[int | float], instance: None, owner: Any
|
||||||
) -> NumberVar: ...
|
) -> NumberVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(self: Field[str], instance: None, owner) -> StringVar: ...
|
def __get__(self: Field[str], instance: None, owner: Any) -> StringVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(self: Field[None], instance: None, owner) -> NoneVar: ...
|
def __get__(self: Field[None], instance: None, owner: Any) -> NoneVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(
|
def __get__(
|
||||||
self: Field[List[V]] | Field[Set[V]] | Field[Tuple[V, ...]],
|
self: Field[List[V]] | Field[Set[V]] | Field[Tuple[V, ...]],
|
||||||
instance: None,
|
instance: None,
|
||||||
owner,
|
owner: Any,
|
||||||
) -> ArrayVar[List[V]]: ...
|
) -> ArrayVar[List[V]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(
|
def __get__(
|
||||||
self: Field[MAPPING_TYPE], instance: None, owner
|
self: Field[MAPPING_TYPE], instance: None, owner: Any
|
||||||
) -> ObjectVar[MAPPING_TYPE]: ...
|
) -> ObjectVar[MAPPING_TYPE]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(
|
def __get__(
|
||||||
self: Field[BASE_TYPE], instance: None, owner
|
self: Field[BASE_TYPE], instance: None, owner: Any
|
||||||
) -> ObjectVar[BASE_TYPE]: ...
|
) -> ObjectVar[BASE_TYPE]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(self, instance: None, owner) -> Var[FIELD_TYPE]: ...
|
def __get__(self, instance: None, owner: Any) -> Var[FIELD_TYPE]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(self, instance, owner) -> FIELD_TYPE: ...
|
def __get__(self, instance: Any, owner: Any) -> FIELD_TYPE: ...
|
||||||
|
|
||||||
def __get__(self, instance, owner): # type: ignore
|
def __get__(self, instance: Any, owner: Any): # pyright: ignore [reportInconsistentOverload]
|
||||||
"""Get the Var.
|
"""Get the Var.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -3070,4 +3133,4 @@ def field(value: FIELD_TYPE) -> Field[FIELD_TYPE]:
|
|||||||
Returns:
|
Returns:
|
||||||
The Field.
|
The Field.
|
||||||
"""
|
"""
|
||||||
return value # type: ignore
|
return value # pyright: ignore [reportReturnType]
|
||||||
|
@ -40,7 +40,7 @@ class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
|
|||||||
def __lt__(self, other: datetime_types) -> BooleanVar: ...
|
def __lt__(self, other: datetime_types) -> BooleanVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __lt__(self, other: NoReturn) -> NoReturn: ...
|
def __lt__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
def __lt__(self, other: Any):
|
def __lt__(self, other: Any):
|
||||||
"""Less than comparison.
|
"""Less than comparison.
|
||||||
@ -59,7 +59,7 @@ class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
|
|||||||
def __le__(self, other: datetime_types) -> BooleanVar: ...
|
def __le__(self, other: datetime_types) -> BooleanVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __le__(self, other: NoReturn) -> NoReturn: ...
|
def __le__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
def __le__(self, other: Any):
|
def __le__(self, other: Any):
|
||||||
"""Less than or equal comparison.
|
"""Less than or equal comparison.
|
||||||
@ -78,7 +78,7 @@ class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
|
|||||||
def __gt__(self, other: datetime_types) -> BooleanVar: ...
|
def __gt__(self, other: datetime_types) -> BooleanVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __gt__(self, other: NoReturn) -> NoReturn: ...
|
def __gt__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
def __gt__(self, other: Any):
|
def __gt__(self, other: Any):
|
||||||
"""Greater than comparison.
|
"""Greater than comparison.
|
||||||
@ -97,7 +97,7 @@ class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
|
|||||||
def __ge__(self, other: datetime_types) -> BooleanVar: ...
|
def __ge__(self, other: datetime_types) -> BooleanVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __ge__(self, other: NoReturn) -> NoReturn: ...
|
def __ge__(self, other: NoReturn) -> NoReturn: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
def __ge__(self, other: Any):
|
def __ge__(self, other: Any):
|
||||||
"""Greater than or equal comparison.
|
"""Greater than or equal comparison.
|
||||||
|
@ -7,7 +7,7 @@ import dataclasses
|
|||||||
import dis
|
import dis
|
||||||
import enum
|
import enum
|
||||||
import inspect
|
import inspect
|
||||||
from types import CodeType, FunctionType
|
from types import CellType, CodeType, FunctionType
|
||||||
from typing import TYPE_CHECKING, Any, ClassVar, Type, cast
|
from typing import TYPE_CHECKING, Any, ClassVar, Type, cast
|
||||||
|
|
||||||
from reflex.utils.exceptions import VarValueError
|
from reflex.utils.exceptions import VarValueError
|
||||||
@ -21,7 +21,7 @@ if TYPE_CHECKING:
|
|||||||
CellEmpty = object()
|
CellEmpty = object()
|
||||||
|
|
||||||
|
|
||||||
def get_cell_value(cell) -> Any:
|
def get_cell_value(cell: CellType) -> Any:
|
||||||
"""Get the value of a cell object.
|
"""Get the value of a cell object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -70,10 +70,10 @@ class DependencyTracker:
|
|||||||
"""After initializing, populate the dependencies dict."""
|
"""After initializing, populate the dependencies dict."""
|
||||||
with contextlib.suppress(AttributeError):
|
with contextlib.suppress(AttributeError):
|
||||||
# unbox functools.partial
|
# unbox functools.partial
|
||||||
self.func = cast(FunctionType, self.func.func) # type: ignore
|
self.func = cast(FunctionType, self.func.func) # pyright: ignore[reportGeneralTypeIssues]
|
||||||
with contextlib.suppress(AttributeError):
|
with contextlib.suppress(AttributeError):
|
||||||
# unbox EventHandler
|
# unbox EventHandler
|
||||||
self.func = cast(FunctionType, self.func.fn) # type: ignore
|
self.func = cast(FunctionType, self.func.fn) # pyright: ignore[reportGeneralTypeIssues]
|
||||||
|
|
||||||
if isinstance(self.func, FunctionType):
|
if isinstance(self.func, FunctionType):
|
||||||
with contextlib.suppress(AttributeError, IndexError):
|
with contextlib.suppress(AttributeError, IndexError):
|
||||||
@ -127,7 +127,7 @@ class DependencyTracker:
|
|||||||
|
|
||||||
if isinstance(ref_obj, property) and not isinstance(ref_obj, ComputedVar):
|
if isinstance(ref_obj, property) and not isinstance(ref_obj, ComputedVar):
|
||||||
# recurse into property fget functions
|
# recurse into property fget functions
|
||||||
ref_obj = ref_obj.fget # type: ignore
|
ref_obj = ref_obj.fget
|
||||||
if callable(ref_obj):
|
if callable(ref_obj):
|
||||||
# recurse into callable attributes
|
# recurse into callable attributes
|
||||||
self._merge_deps(
|
self._merge_deps(
|
||||||
@ -164,7 +164,8 @@ class DependencyTracker:
|
|||||||
var_name: get_cell_value(cell)
|
var_name: get_cell_value(cell)
|
||||||
for var_name, cell in zip(
|
for var_name, cell in zip(
|
||||||
self.func.__code__.co_freevars, # pyright: ignore[reportGeneralTypeIssues]
|
self.func.__code__.co_freevars, # pyright: ignore[reportGeneralTypeIssues]
|
||||||
self.func.__closure__, # pyright: ignore[reportGeneralTypeIssues]
|
self.func.__closure__ or (),
|
||||||
|
strict=False,
|
||||||
)
|
)
|
||||||
if get_cell_value(cell) is not CellEmpty
|
if get_cell_value(cell) is not CellEmpty
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ class FunctionVar(Var[CALLABLE_TYPE], default_type=ReflexCallable[Any, Any]):
|
|||||||
@overload
|
@overload
|
||||||
def partial(self, *args: Var | Any) -> FunctionVar: ...
|
def partial(self, *args: Var | Any) -> FunctionVar: ...
|
||||||
|
|
||||||
def partial(self, *args: Var | Any) -> FunctionVar: # type: ignore
|
def partial(self, *args: Var | Any) -> FunctionVar: # pyright: ignore [reportInconsistentOverload]
|
||||||
"""Partially apply the function with the given arguments.
|
"""Partially apply the function with the given arguments.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -174,7 +174,7 @@ class FunctionVar(Var[CALLABLE_TYPE], default_type=ReflexCallable[Any, Any]):
|
|||||||
@overload
|
@overload
|
||||||
def call(self, *args: Var | Any) -> Var: ...
|
def call(self, *args: Var | Any) -> Var: ...
|
||||||
|
|
||||||
def call(self, *args: Var | Any) -> Var: # type: ignore
|
def call(self, *args: Var | Any) -> Var: # pyright: ignore [reportInconsistentOverload]
|
||||||
"""Call the function with the given arguments.
|
"""Call the function with the given arguments.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -210,6 +210,7 @@ class FunctionStringVar(FunctionVar[CALLABLE_TYPE]):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
func: The function to call.
|
func: The function to call.
|
||||||
|
_var_type: The type of the Var.
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -268,6 +269,7 @@ class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
|
|||||||
Args:
|
Args:
|
||||||
func: The function to call.
|
func: The function to call.
|
||||||
*args: The arguments to call the function with.
|
*args: The arguments to call the function with.
|
||||||
|
_var_type: The type of the Var.
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -385,6 +387,7 @@ class ArgsFunctionOperation(CachedVarOperation, FunctionVar):
|
|||||||
return_expr: The return expression of the function.
|
return_expr: The return expression of the function.
|
||||||
rest: The name of the rest argument.
|
rest: The name of the rest argument.
|
||||||
explicit_return: Whether to use explicit return syntax.
|
explicit_return: Whether to use explicit return syntax.
|
||||||
|
_var_type: The type of the Var.
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -441,6 +444,7 @@ class ArgsFunctionOperationBuilder(CachedVarOperation, BuilderFunctionVar):
|
|||||||
return_expr: The return expression of the function.
|
return_expr: The return expression of the function.
|
||||||
rest: The name of the rest argument.
|
rest: The name of the rest argument.
|
||||||
explicit_return: Whether to use explicit return syntax.
|
explicit_return: Whether to use explicit return syntax.
|
||||||
|
_var_type: The type of the Var.
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user