1
0
Эх сурвалжийг харах

Merge branch 'main' into add-validation-to-function-vars

Khaleel Al-Adhami 3 сар өмнө
parent
commit
8fab30eb69
100 өөрчлөгдсөн 1263 нэмэгдсэн , 424 устгасан
  1. 34 0
      .github/workflows/performance.yml
  2. 2 0
      .gitignore
  3. 1 1
      .pre-commit-config.yaml
  4. 10 10
      benchmarks/test_benchmark_compile_components.py
  5. 13 13
      benchmarks/test_benchmark_compile_pages.py
  6. 215 0
      benchmarks/test_evaluate.py
  7. 237 52
      poetry.lock
  8. 7 7
      pyproject.toml
  9. 14 2
      reflex/.templates/web/utils/state.js
  10. 4 1
      reflex/__init__.py
  11. 1 1
      reflex/__init__.pyi
  12. 63 23
      reflex/app.py
  13. 6 6
      reflex/app_mixins/lifespan.py
  14. 6 6
      reflex/app_mixins/middleware.py
  15. 5 5
      reflex/base.py
  16. 12 4
      reflex/compiler/utils.py
  17. 1 1
      reflex/components/base/bare.py
  18. 2 1
      reflex/components/base/error_boundary.py
  19. 2 1
      reflex/components/base/error_boundary.pyi
  20. 2 2
      reflex/components/base/meta.py
  21. 17 18
      reflex/components/component.py
  22. 83 4
      reflex/components/core/banner.py
  23. 86 0
      reflex/components/core/banner.pyi
  24. 3 1
      reflex/components/core/breakpoints.py
  25. 1 1
      reflex/components/core/client_side_routing.py
  26. 1 1
      reflex/components/core/client_side_routing.pyi
  27. 1 1
      reflex/components/core/cond.py
  28. 1 1
      reflex/components/core/debounce.py
  29. 2 0
      reflex/components/core/foreach.py
  30. 1 1
      reflex/components/core/upload.py
  31. 1 1
      reflex/components/datadisplay/code.py
  32. 6 3
      reflex/components/datadisplay/dataeditor.py
  33. 2 4
      reflex/components/datadisplay/logo.py
  34. 14 9
      reflex/components/datadisplay/shiki_code_block.py
  35. 1 1
      reflex/components/el/constants/reflex.py
  36. 1 1
      reflex/components/el/element.py
  37. 2 2
      reflex/components/el/elements/forms.py
  38. 10 8
      reflex/components/markdown/markdown.py
  39. 2 2
      reflex/components/moment/moment.py
  40. 3 1
      reflex/components/next/image.py
  41. 1 1
      reflex/components/next/link.py
  42. 4 4
      reflex/components/plotly/plotly.py
  43. 3 3
      reflex/components/props.py
  44. 1 1
      reflex/components/radix/__init__.pyi
  45. 5 1
      reflex/components/radix/primitives/accordion.py
  46. 3 1
      reflex/components/radix/primitives/accordion.pyi
  47. 4 1
      reflex/components/radix/primitives/drawer.py
  48. 1 1
      reflex/components/radix/primitives/progress.py
  49. 1 1
      reflex/components/radix/primitives/slider.py
  50. 9 7
      reflex/components/radix/themes/color_mode.py
  51. 3 0
      reflex/components/radix/themes/components/alert_dialog.py
  52. 1 1
      reflex/components/radix/themes/components/card.py
  53. 1 1
      reflex/components/radix/themes/components/card.pyi
  54. 5 0
      reflex/components/radix/themes/components/context_menu.py
  55. 3 0
      reflex/components/radix/themes/components/dialog.py
  56. 5 0
      reflex/components/radix/themes/components/dropdown_menu.py
  57. 3 0
      reflex/components/radix/themes/components/hover_card.py
  58. 3 0
      reflex/components/radix/themes/components/popover.py
  59. 2 0
      reflex/components/radix/themes/components/radio_cards.py
  60. 1 1
      reflex/components/radix/themes/components/radio_group.py
  61. 3 0
      reflex/components/radix/themes/components/select.py
  62. 3 0
      reflex/components/radix/themes/components/tabs.py
  63. 12 0
      reflex/components/radix/themes/components/text_area.py
  64. 2 0
      reflex/components/radix/themes/components/text_area.pyi
  65. 1 1
      reflex/components/radix/themes/components/text_field.py
  66. 1 1
      reflex/components/radix/themes/layout/__init__.pyi
  67. 2 2
      reflex/components/radix/themes/layout/list.py
  68. 2 2
      reflex/components/radix/themes/layout/stack.py
  69. 1 1
      reflex/components/radix/themes/typography/link.py
  70. 2 2
      reflex/components/radix/themes/typography/text.py
  71. 1 1
      reflex/components/react_player/react_player.py
  72. 11 13
      reflex/components/recharts/charts.py
  73. 1 1
      reflex/components/recharts/polar.py
  74. 15 13
      reflex/components/sonner/toast.py
  75. 5 5
      reflex/components/sonner/toast.pyi
  76. 6 4
      reflex/components/suneditor/editor.py
  77. 2 2
      reflex/components/suneditor/editor.pyi
  78. 25 3
      reflex/components/tags/tag.py
  79. 12 6
      reflex/config.py
  80. 3 1
      reflex/constants/base.py
  81. 3 2
      reflex/constants/compiler.py
  82. 8 1
      reflex/constants/config.py
  83. 2 2
      reflex/custom_components/custom_components.py
  84. 54 37
      reflex/event.py
  85. 2 5
      reflex/experimental/client_state.py
  86. 5 5
      reflex/experimental/hooks.py
  87. 8 5
      reflex/experimental/layout.py
  88. 3 3
      reflex/experimental/misc.py
  89. 1 1
      reflex/istate/wrappers.py
  90. 11 6
      reflex/model.py
  91. 3 3
      reflex/page.py
  92. 14 10
      reflex/reflex.py
  93. 1 1
      reflex/route.py
  94. 46 36
      reflex/state.py
  95. 24 2
      reflex/style.py
  96. 19 17
      reflex/testing.py
  97. 1 1
      reflex/utils/build.py
  98. 6 5
      reflex/utils/compat.py
  99. 2 2
      reflex/utils/console.py
  100. 6 2
      reflex/utils/exceptions.py

+ 34 - 0
.github/workflows/performance.yml

@@ -0,0 +1,34 @@
+name: performance-tests
+
+on:
+  push:
+    branches:
+      - "main" # or "master"
+    paths-ignore:
+      - "**/*.md"
+  pull_request:
+  workflow_dispatch:
+
+env:
+  TELEMETRY_ENABLED: false
+  NODE_OPTIONS: "--max_old_space_size=8192"
+  PR_TITLE: ${{ github.event.pull_request.title }}
+  APP_HARNESS_HEADLESS: 1
+  PYTHONUNBUFFERED: 1
+
+jobs:
+  benchmarks:
+    name: Run benchmarks
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: ./.github/actions/setup_build_env
+        with:
+          python-version: 3.12.8
+          run-poetry-install: true
+          create-venv-at-path: .venv
+      - name: Run benchmarks
+        uses: CodSpeedHQ/action@v3
+        with:
+          token: ${{ secrets.CODSPEED_TOKEN }}
+          run: poetry run pytest benchmarks/test_evaluate.py --codspeed

+ 2 - 0
.gitignore

@@ -4,6 +4,7 @@ assets/external/*
 dist/*
 dist/*
 examples/
 examples/
 .web
 .web
+.states
 .idea
 .idea
 .vscode
 .vscode
 .coverage
 .coverage
@@ -14,3 +15,4 @@ requirements.txt
 .pyi_generator_last_run
 .pyi_generator_last_run
 .pyi_generator_diff
 .pyi_generator_diff
 reflex.db
 reflex.db
+.codspeed

+ 1 - 1
.pre-commit-config.yaml

@@ -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]

+ 10 - 10
benchmarks/test_benchmark_compile_components.py

@@ -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
-                        content="Yes. It's built with accessibility in mind.",  # type: ignore
+                        header="Full Ingredients",
+                        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
-                        content="Yes. It's unstyled by default, giving you freedom over the look and feel.",  # type: ignore
+                        header="Applications",
+                        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)

+ 13 - 13
benchmarks/test_benchmark_compile_pages.py

@@ -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)

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 215 - 0
benchmarks/test_evaluate.py


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 237 - 52
poetry.lock


+ 7 - 7
pyproject.toml

@@ -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"
@@ -71,6 +71,7 @@ selenium = ">=4.11.0,<5.0"
 pytest-benchmark = ">=4.0.0,<6.0"
 pytest-benchmark = ">=4.0.0,<6.0"
 playwright = ">=1.46.0"
 playwright = ">=1.46.0"
 pytest-playwright = ">=0.5.1"
 pytest-playwright = ">=0.5.1"
+pytest-codspeed = "^3.1.2"
 
 
 [tool.poetry.scripts]
 [tool.poetry.scripts]
 reflex = "reflex.reflex:cli"
 reflex = "reflex.reflex:cli"
@@ -81,22 +82,21 @@ build-backend = "poetry.core.masonry.api"
 
 
 [tool.pyright]
 [tool.pyright]
 reportIncompatibleMethodOverride = false
 reportIncompatibleMethodOverride = false
-reportIncompatibleVariableOverride = 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"]
-"benchmarks/*.py" = ["D100", "D103", "D104", "B018", "PERF", "T", "N"]
+"tests/*.py" = ["ANN001", "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"]

+ 14 - 2
reflex/.templates/web/utils/state.js

@@ -106,6 +106,18 @@ export const getBackendURL = (url_str) => {
   return endpoint;
   return endpoint;
 };
 };
 
 
+/**
+ * Check if the backend is disabled.
+ *
+ * @returns True if the backend is disabled, false otherwise.
+ */
+export const isBackendDisabled = () => {
+  const cookie = document.cookie
+    .split("; ")
+    .find((row) => row.startsWith("backend-enabled="));
+  return cookie !== undefined && cookie.split("=")[1] == "false";
+};
+
 /**
 /**
  * Determine if any event in the event queue is stateful.
  * Determine if any event in the event queue is stateful.
  *
  *
@@ -405,7 +417,7 @@ export const connect = async (
   socket.current = io(endpoint.href, {
   socket.current = io(endpoint.href, {
     path: endpoint["pathname"],
     path: endpoint["pathname"],
     transports: transports,
     transports: transports,
-    protocols: env.TEST_MODE ? undefined : [reflexEnvironment.version],
+    protocols: [reflexEnvironment.version],
     autoUnref: false,
     autoUnref: false,
   });
   });
   // Ensure undefined fields in events are sent as null instead of removed
   // Ensure undefined fields in events are sent as null instead of removed
@@ -812,7 +824,7 @@ export const useEventLoop = (
       return;
       return;
     }
     }
     // only use websockets if state is present
     // only use websockets if state is present
-    if (Object.keys(initialState).length > 1) {
+    if (Object.keys(initialState).length > 1 && !isBackendDisabled()) {
       // Initialize the websocket connection.
       // Initialize the websocket connection.
       if (!socket.current) {
       if (!socket.current) {
         connect(
         connect(

+ 4 - 1
reflex/__init__.py

@@ -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)

+ 1 - 1
reflex/__init__.pyi

@@ -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

+ 63 - 23
reflex/app.py

@@ -27,6 +27,7 @@ from typing import (
     Dict,
     Dict,
     Generic,
     Generic,
     List,
     List,
+    MutableMapping,
     Optional,
     Optional,
     Set,
     Set,
     Type,
     Type,
@@ -58,7 +59,11 @@ from reflex.components.component import (
     ComponentStyle,
     ComponentStyle,
     evaluate_style_namespaces,
     evaluate_style_namespaces,
 )
 )
-from reflex.components.core.banner import connection_pulser, connection_toaster
+from reflex.components.core.banner import (
+    backend_disabled,
+    connection_pulser,
+    connection_toaster,
+)
 from reflex.components.core.breakpoints import set_breakpoints
 from reflex.components.core.breakpoints import set_breakpoints
 from reflex.components.core.client_side_routing import (
 from reflex.components.core.client_side_routing import (
     Default404Page,
     Default404Page,
@@ -145,7 +150,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))
@@ -157,9 +162,12 @@ def default_overlay_component() -> Component:
     Returns:
     Returns:
         The default overlay_component, which is a connection_modal.
         The default overlay_component, which is a connection_modal.
     """
     """
+    config = get_config()
+
     return Fragment.create(
     return Fragment.create(
         connection_pulser(),
         connection_pulser(),
         connection_toaster(),
         connection_toaster(),
+        *([backend_disabled()] if config.is_reflex_cloud else []),
         *codespaces.codespaces_auto_redirect(),
         *codespaces.codespaces_auto_redirect(),
     )
     )
 
 
@@ -405,7 +413,36 @@ class App(MiddlewareMixin, LifespanMixin):
         self.sio.register_namespace(self.event_namespace)
         self.sio.register_namespace(self.event_namespace)
         # Mount the socket app with the API.
         # Mount the socket app with the API.
         if self.api:
         if self.api:
-            self.api.mount(str(constants.Endpoint.EVENT), socket_app)
+
+            class HeaderMiddleware:
+                def __init__(self, app: ASGIApp):
+                    self.app = app
+
+                async def __call__(
+                    self, scope: MutableMapping[str, Any], receive: Any, send: Callable
+                ):
+                    original_send = send
+
+                    async def modified_send(message: dict):
+                        if message["type"] == "websocket.accept":
+                            if scope.get("subprotocols"):
+                                # The following *does* say "subprotocol" instead of "subprotocols", intentionally.
+                                message["subprotocol"] = scope["subprotocols"][0]
+
+                            headers = dict(message.get("headers", []))
+                            header_key = b"sec-websocket-protocol"
+                            if subprotocol := headers.get(header_key):
+                                message["headers"] = [
+                                    *message.get("headers", []),
+                                    (header_key, subprotocol),
+                                ]
+
+                        return await original_send(message)
+
+                    return await self.app(scope, receive, modified_send)
+
+            socket_app_with_headers = HeaderMiddleware(socket_app)
+            self.api.mount(str(constants.Endpoint.EVENT), socket_app_with_headers)
 
 
         # Check the exception handlers
         # Check the exception handlers
         self._validate_exception_handlers()
         self._validate_exception_handlers()
@@ -648,7 +685,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
@@ -679,8 +719,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.
         """
         """
@@ -747,7 +787,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`"
                 )
                 )
@@ -992,7 +1032,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]
             )
             )
         )
         )
 
 
@@ -1015,7 +1055,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
@@ -1023,7 +1063,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)
 
 
@@ -1212,6 +1252,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__
@@ -1353,15 +1394,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
-
-                # Process the event synchronously.
-                async for update in state._process(event):
-                    # Postprocess the event.
-                    update = await app._postprocess(state, event, update)
-
-                    # Yield the update.
-                    yield update
+                else:
+                    # Process the event synchronously.
+                    async for update in state._process(event):
+                        # 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")
 
 
@@ -1556,20 +1596,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:
@@ -1591,7 +1631,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:
@@ -1658,7 +1698,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:

+ 6 - 6
reflex/app_mixins/lifespan.py

@@ -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
-            functools.update_wrapper(task, original_task)  # type: ignore
-        self.lifespan_tasks.add(task)  # type: ignore
-        console.debug(f"Registered lifespan task: {task.__name__}")  # type: ignore
+            task = functools.partial(task, **task_kwargs)  # pyright: ignore [reportArgumentType]
+            functools.update_wrapper(task, original_task)  # pyright: ignore [reportArgumentType]
+        self.lifespan_tasks.add(task)
+        console.debug(f"Registered lifespan task: {task.__name__}")  # pyright: ignore [reportAttributeAccessIssue]

+ 6 - 6
reflex/app_mixins/middleware.py

@@ -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

+ 5 - 5
reflex/base.py

@@ -38,7 +38,7 @@ 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
@@ -69,12 +69,12 @@ class Base(BaseModel):
         """
         """
         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:
@@ -107,12 +107,12 @@ class Base(BaseModel):
             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})
 
 

+ 12 - 4
reflex/compiler/utils.py

@@ -2,6 +2,8 @@
 
 
 from __future__ import annotations
 from __future__ import annotations
 
 
+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
@@ -12,7 +14,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 (
@@ -115,7 +119,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:
@@ -163,8 +167,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
@@ -494,7 +502,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:

+ 1 - 1
reflex/components/base/bare.py

@@ -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.

+ 2 - 1
reflex/components/base/error_boundary.py

@@ -11,10 +11,11 @@ from reflex.event import EventHandler, set_clipboard
 from reflex.state import FrontendEventExceptionState
 from reflex.state import FrontendEventExceptionState
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 from reflex.vars.function import ArgsFunctionOperation
 from reflex.vars.function import ArgsFunctionOperation
+from reflex.vars.object import ObjectVar
 
 
 
 
 def on_error_spec(
 def on_error_spec(
-    error: Var[Dict[str, str]], info: Var[Dict[str, str]]
+    error: ObjectVar[Dict[str, str]], info: ObjectVar[Dict[str, str]]
 ) -> Tuple[Var[str], Var[str]]:
 ) -> Tuple[Var[str], Var[str]]:
     """The spec for the on_error event handler.
     """The spec for the on_error event handler.
 
 

+ 2 - 1
reflex/components/base/error_boundary.pyi

@@ -9,9 +9,10 @@ from reflex.components.component import Component
 from reflex.event import BASE_STATE, EventType
 from reflex.event import BASE_STATE, EventType
 from reflex.style import Style
 from reflex.style import Style
 from reflex.vars.base import Var
 from reflex.vars.base import Var
+from reflex.vars.object import ObjectVar
 
 
 def on_error_spec(
 def on_error_spec(
-    error: Var[Dict[str, str]], info: Var[Dict[str, str]]
+    error: ObjectVar[Dict[str, str]], info: ObjectVar[Dict[str, str]]
 ) -> Tuple[Var[str], Var[str]]: ...
 ) -> Tuple[Var[str], Var[str]]: ...
 
 
 class ErrorBoundary(Component):
 class ErrorBoundary(Component):

+ 2 - 2
reflex/components/base/meta.py

@@ -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"

+ 17 - 18
reflex/components/component.py

@@ -149,7 +149,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:
@@ -425,7 +425,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)
 
 
@@ -461,9 +461,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
-                        for arg in passed_type.__args__  # type: ignore
-                        if arg is not type(None)
+                        arg for arg in passed_type.__args__ 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.
@@ -490,7 +488,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,
                 )
                 )
@@ -577,7 +575,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:
@@ -708,7 +706,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)
@@ -760,7 +758,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)
 
 
@@ -852,7 +850,7 @@ class Component(BaseComponent, ABC):
             else {}
             else {}
         )
         )
 
 
-    def render(self) -> Dict:
+    def render(self) -> dict:
         """Render the component.
         """Render the component.
 
 
         Returns:
         Returns:
@@ -870,7 +868,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:
@@ -906,7 +904,7 @@ class Component(BaseComponent, ABC):
         comp_name = type(self).__name__
         comp_name = type(self).__name__
         allowed_components = [comp.__name__ for comp in (Fragment,)]
         allowed_components = [comp.__name__ for comp in (Fragment,)]
 
 
-        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
@@ -1683,7 +1681,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(),
                         )
                         )
@@ -1716,7 +1714,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:
@@ -1811,7 +1809,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.
 
 
@@ -1953,7 +1951,7 @@ class StatefulComponent(BaseComponent):
 
 
         if not should_memoize:
         if not should_memoize:
             # Determine if any Vars have associated data.
             # Determine if any Vars have associated data.
-            for prop_var in component._get_vars():
+            for prop_var in component._get_vars(include_children=True):
                 if prop_var._get_all_var_data():
                 if prop_var._get_all_var_data():
                     should_memoize = True
                     should_memoize = True
                     break
                     break
@@ -2323,8 +2321,8 @@ class MemoizationLeaf(Component):
         """
         """
         comp = super().create(*children, **props)
         comp = super().create(*children, **props)
         if comp._get_all_hooks():
         if comp._get_all_hooks():
-            comp._memoization_mode = cls._memoization_mode.copy(
-                update={"disposition": MemoizationDisposition.ALWAYS}
+            comp._memoization_mode = dataclasses.replace(
+                comp._memoization_mode, disposition=MemoizationDisposition.ALWAYS
             )
             )
         return comp
         return comp
 
 
@@ -2406,6 +2404,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
 @dataclasses.dataclass(
 @dataclasses.dataclass(
     eq=False,
     eq=False,
     frozen=True,
     frozen=True,
+    slots=True,
 )
 )
 class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
 class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
     """A Var that represents a Component."""
     """A Var that represents a Component."""

+ 83 - 4
reflex/components/core/banner.py

@@ -5,8 +5,10 @@ from __future__ import annotations
 from typing import Optional
 from typing import Optional
 
 
 from reflex.components.base.fragment import Fragment
 from reflex.components.base.fragment import Fragment
+from reflex import constants
 from reflex.components.component import Component
 from reflex.components.component import Component
 from reflex.components.core.cond import cond
 from reflex.components.core.cond import cond
+from reflex.components.datadisplay.logo import svg_logo
 from reflex.components.el.elements.typography import Div
 from reflex.components.el.elements.typography import Div
 from reflex.components.lucide.icon import Icon
 from reflex.components.lucide.icon import Icon
 from reflex.components.radix.themes.components.dialog import (
 from reflex.components.radix.themes.components.dialog import (
@@ -26,7 +28,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},
 )
 )
@@ -100,14 +102,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};",
@@ -117,7 +119,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(
@@ -296,7 +298,84 @@ class ConnectionPulser(Div):
         )
         )
 
 
 
 
+class BackendDisabled(Div):
+    """A component that displays a message when the backend is disabled."""
+
+    @classmethod
+    def create(cls, **props) -> Component:
+        """Create a backend disabled component.
+
+        Args:
+            **props: The properties of the component.
+
+        Returns:
+            The backend disabled component.
+        """
+        import reflex as rx
+
+        is_backend_disabled = Var(
+            "backendDisabled",
+            _var_type=bool,
+            _var_data=VarData(
+                hooks={
+                    "const [backendDisabled, setBackendDisabled] = useState(false);": None,
+                    "useEffect(() => { setBackendDisabled(isBackendDisabled()); }, []);": None,
+                },
+                imports={
+                    f"$/{constants.Dirs.STATE_PATH}": [
+                        ImportVar(tag="isBackendDisabled")
+                    ],
+                },
+            ),
+        )
+
+        return super().create(
+            rx.cond(
+                is_backend_disabled,
+                rx.box(
+                    rx.box(
+                        rx.card(
+                            rx.vstack(
+                                svg_logo(),
+                                rx.text(
+                                    "You ran out of compute credits.",
+                                ),
+                                rx.callout(
+                                    rx.fragment(
+                                        "Please upgrade your plan or raise your compute credits at ",
+                                        rx.link(
+                                            "Reflex Cloud.",
+                                            href="https://cloud.reflex.dev/",
+                                        ),
+                                    ),
+                                    width="100%",
+                                    icon="info",
+                                    variant="surface",
+                                ),
+                            ),
+                            font_size="20px",
+                            font_family='"Inter", "Helvetica", "Arial", sans-serif',
+                            variant="classic",
+                        ),
+                        position="fixed",
+                        top="50%",
+                        left="50%",
+                        transform="translate(-50%, -50%)",
+                        width="40ch",
+                        max_width="90vw",
+                    ),
+                    position="fixed",
+                    z_index=9999,
+                    backdrop_filter="grayscale(1) blur(5px)",
+                    width="100dvw",
+                    height="100dvh",
+                ),
+            )
+        )
+
+
 connection_banner = ConnectionBanner.create
 connection_banner = ConnectionBanner.create
 connection_modal = ConnectionModal.create
 connection_modal = ConnectionModal.create
 connection_toaster = ConnectionToaster.create
 connection_toaster = ConnectionToaster.create
 connection_pulser = ConnectionPulser.create
 connection_pulser = ConnectionPulser.create
+backend_disabled = BackendDisabled.create

+ 86 - 0
reflex/components/core/banner.pyi

@@ -351,7 +351,93 @@ class ConnectionPulser(Div):
         """
         """
         ...
         ...
 
 
+class BackendDisabled(Div):
+    @overload
+    @classmethod
+    def create(  # type: ignore
+        cls,
+        *children,
+        access_key: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        auto_capitalize: Optional[
+            Union[Var[Union[bool, int, str]], bool, int, str]
+        ] = None,
+        content_editable: Optional[
+            Union[Var[Union[bool, int, str]], bool, int, str]
+        ] = None,
+        context_menu: Optional[
+            Union[Var[Union[bool, int, str]], bool, int, str]
+        ] = None,
+        dir: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        draggable: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        enter_key_hint: Optional[
+            Union[Var[Union[bool, int, str]], bool, int, str]
+        ] = None,
+        hidden: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        input_mode: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        item_prop: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        lang: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        role: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        slot: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        spell_check: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        tab_index: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        title: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
+        style: Optional[Style] = None,
+        key: Optional[Any] = None,
+        id: Optional[Any] = None,
+        class_name: Optional[Any] = None,
+        autofocus: Optional[bool] = None,
+        custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
+        on_blur: Optional[EventType[[], BASE_STATE]] = None,
+        on_click: Optional[EventType[[], BASE_STATE]] = None,
+        on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
+        on_double_click: Optional[EventType[[], BASE_STATE]] = None,
+        on_focus: Optional[EventType[[], BASE_STATE]] = None,
+        on_mount: Optional[EventType[[], BASE_STATE]] = None,
+        on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
+        on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
+        on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
+        on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
+        on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
+        on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
+        on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
+        on_scroll: Optional[EventType[[], BASE_STATE]] = None,
+        on_unmount: Optional[EventType[[], BASE_STATE]] = None,
+        **props,
+    ) -> "BackendDisabled":
+        """Create a backend disabled component.
+
+        Args:
+            access_key: Provides a hint for generating a keyboard shortcut for the current element.
+            auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
+            content_editable: Indicates whether the element's content is editable.
+            context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
+            dir: Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)
+            draggable: Defines whether the element can be dragged.
+            enter_key_hint: Hints what media types the media element is able to play.
+            hidden: Defines whether the element is hidden.
+            input_mode: Defines the type of the element.
+            item_prop: Defines the name of the element for metadata purposes.
+            lang: Defines the language used in the element.
+            role: Defines the role of the element.
+            slot: Assigns a slot in a shadow DOM shadow tree to an element.
+            spell_check: Defines whether the element may be checked for spelling errors.
+            tab_index: Defines the position of the current element in the tabbing order.
+            title: Defines a tooltip for the element.
+            style: The style of the component.
+            key: A unique key for the component.
+            id: The id for the component.
+            class_name: The class name for the component.
+            autofocus: Whether the component should take the focus once the page is loaded
+            custom_attrs: custom attribute
+            **props: The properties of the component.
+
+        Returns:
+            The backend disabled component.
+        """
+        ...
+
 connection_banner = ConnectionBanner.create
 connection_banner = ConnectionBanner.create
 connection_modal = ConnectionModal.create
 connection_modal = ConnectionModal.create
 connection_toaster = ConnectionToaster.create
 connection_toaster = ConnectionToaster.create
 connection_pulser = ConnectionPulser.create
 connection_pulser = ConnectionPulser.create
+backend_disabled = BackendDisabled.create

+ 3 - 1
reflex/components/core/breakpoints.py

@@ -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
                 }
                 }
             )
             )

+ 1 - 1
reflex/components/core/client_side_routing.py

@@ -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.

+ 1 - 1
reflex/components/core/client_side_routing.pyi

@@ -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

+ 1 - 1
reflex/components/core/cond.py

@@ -59,7 +59,7 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
 
 
 
 
 @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

+ 1 - 1
reflex/components/core/debounce.py

@@ -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 - 0
reflex/components/core/foreach.py

@@ -2,8 +2,10 @@
 
 
 from __future__ import annotations
 from __future__ import annotations
 
 
+import functools
 from typing import Callable, Iterable
 from typing import Callable, Iterable
 
 
+from reflex.utils.exceptions import UntypedVarError
 from reflex.vars.base import LiteralVar, Var
 from reflex.vars.base import LiteralVar, Var
 from reflex.vars.object import ObjectVar
 from reflex.vars.object import ObjectVar
 from reflex.vars.sequence import ArrayVar
 from reflex.vars.sequence import ArrayVar

+ 1 - 1
reflex/components/core/upload.py

@@ -267,7 +267,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(

+ 1 - 1
reflex/components/datadisplay/code.py

@@ -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(

+ 6 - 3
reflex/components/datadisplay/dataeditor.py

@@ -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])" "{"]
 
 
@@ -385,7 +387,8 @@ class DataEditor(NoSSRComponent):
                 raise ValueError(
                 raise ValueError(
                     "DataEditor data must be an ArrayVar if rows is not provided."
                     "DataEditor data must be an ArrayVar if rows is not provided."
                 )
                 )
-            props["rows"] = data.length() if isinstance(data, Var) else len(data)
+
+            props["rows"] = data.length() if isinstance(data, ArrayVar) else len(data)
 
 
         if not isinstance(columns, Var) and len(columns):
         if not isinstance(columns, Var) and len(columns):
             if types.is_dataframe(type(data)) or (
             if types.is_dataframe(type(data)) or (

+ 2 - 4
reflex/components/datadisplay/logo.py

@@ -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):
-        return rx.el.svg.path(
-            d=d,
-        )
+    def logo_path(d: str):
+        return rx.el.svg.path(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",

+ 14 - 9
reflex/components/datadisplay/shiki_code_block.py

@@ -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", {}))
@@ -621,18 +621,22 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
 
 
         Returns:
         Returns:
             Imports for the component.
             Imports for the component.
+
+        Raises:
+            ValueError: If the transformers are not of type LiteralVar.
         """
         """
         imports = defaultdict(list)
         imports = defaultdict(list)
+        if not isinstance(self.transformers, LiteralVar):
+            raise ValueError(
+                f"transformers should be a LiteralVar type. Got {type(self.transformers)} instead."
+            )
         for transformer in self.transformers._var_value:
         for transformer in self.transformers._var_value:
             if isinstance(transformer, ShikiBaseTransformers):
             if isinstance(transformer, ShikiBaseTransformers):
                 imports[transformer.library].extend(
                 imports[transformer.library].extend(
                     [ImportVar(tag=str(fn)) for fn in transformer.fns]
                     [ImportVar(tag=str(fn)) for fn in transformer.fns]
                 )
                 )
-                (
+                if transformer.library not in self.lib_dependencies:
                     self.lib_dependencies.append(transformer.library)
                     self.lib_dependencies.append(transformer.library)
-                    if transformer.library not in self.lib_dependencies
-                    else None
-                )
         return imports
         return imports
 
 
     @classmethod
     @classmethod
@@ -653,8 +657,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
-            library=library, fns=[FunctionStringVar.create(fn) for fn in fns]
+        return ShikiBaseTransformers(
+            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 +762,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(

+ 1 - 1
reflex/components/el/constants/reflex.py

@@ -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)

+ 1 - 1
reflex/components/el/element.py

@@ -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:

+ 2 - 2
reflex/components/el/elements/forms.py

@@ -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(""),

+ 10 - 8
reflex/components/markdown/markdown.py

@@ -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
-        "ol": lambda value: OrderedList.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"),
         "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}

+ 2 - 2
reflex/components/moment/moment.py

@@ -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).

+ 3 - 1
reflex/components/next/image.py

@@ -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
 
 

+ 1 - 1
reflex/components/next/link.py

@@ -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)

+ 4 - 4
reflex/components/plotly/plotly.py

@@ -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
-    Template = Any  # type: ignore
+    Figure = Any
+    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]

+ 3 - 3
reflex/components/props.py

@@ -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

+ 1 - 1
reflex/components/radix/__init__.pyi

@@ -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

+ 5 - 1
reflex/components/radix/primitives/accordion.py

@@ -10,6 +10,7 @@ from reflex.components.core.cond import cond
 from reflex.components.lucide.icon import Icon
 from reflex.components.lucide.icon import Icon
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import LiteralAccentColor, LiteralRadius
 from reflex.components.radix.themes.base import LiteralAccentColor, LiteralRadius
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler
 from reflex.event import EventHandler
 from reflex.style import Style
 from reflex.style import Style
 from reflex.vars import get_uuid_string_var
 from reflex.vars import get_uuid_string_var
@@ -196,8 +197,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("")
+    content: Var[Union[Component, str, None]] = Var.create(None)
 
 
     _valid_children: List[str] = [
     _valid_children: List[str] = [
         "AccordionHeader",
         "AccordionHeader",
@@ -341,6 +343,8 @@ class AccordionTrigger(AccordionComponent):
 
 
     alias = "RadixAccordionTrigger"
     alias = "RadixAccordionTrigger"
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
     @classmethod
     @classmethod
     def create(cls, *children, **props) -> Component:
     def create(cls, *children, **props) -> Component:
         """Create the Accordion trigger component.
         """Create the Accordion trigger component.

+ 3 - 1
reflex/components/radix/primitives/accordion.pyi

@@ -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[

+ 4 - 1
reflex/components/radix/primitives/drawer.py

@@ -10,6 +10,7 @@ from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import Theme
 from reflex.components.radix.themes.base import Theme
 from reflex.components.radix.themes.layout.flex import Flex
 from reflex.components.radix.themes.layout.flex import Flex
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -83,7 +84,9 @@ 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)
+
+    _memoization_mode = MemoizationMode(recursive=False)
 
 
     @classmethod
     @classmethod
     def create(cls, *children: Any, **props: Any) -> Component:
     def create(cls, *children: Any, **props: Any) -> Component:

+ 1 - 1
reflex/components/radix/primitives/progress.py

@@ -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)",
         }
         }
 
 

+ 1 - 1
reflex/components/radix/primitives/slider.py

@@ -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):

+ 9 - 7
reflex/components/radix/themes/color_mode.py

@@ -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 color_mode_cond, cond
 from reflex.components.core.cond import color_mode_cond, cond
@@ -73,17 +73,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)
 
 
@@ -110,12 +112,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")
@@ -137,7 +139,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)
                 )
                 )

+ 3 - 0
reflex/components/radix/themes/components/alert_dialog.py

@@ -5,6 +5,7 @@ from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.el import elements
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -33,6 +34,8 @@ class AlertDialogTrigger(RadixThemesTriggerComponent):
 
 
     tag = "AlertDialog.Trigger"
     tag = "AlertDialog.Trigger"
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class AlertDialogContent(elements.Div, RadixThemesComponent):
 class AlertDialogContent(elements.Div, RadixThemesComponent):
     """Contains the content of the dialog. This component is based on the div element."""
     """Contains the content of the dialog. This component is based on the div element."""

+ 1 - 1
reflex/components/radix/themes/components/card.py

@@ -20,7 +20,7 @@ class Card(elements.Div, RadixThemesComponent):
     # Card size: "1" - "5"
     # Card size: "1" - "5"
     size: Var[Responsive[Literal["1", "2", "3", "4", "5"],]]
     size: Var[Responsive[Literal["1", "2", "3", "4", "5"],]]
 
 
-    # Variant of Card: "solid" | "soft" | "outline" | "ghost"
+    # Variant of Card: "surface" | "classic" | "ghost"
     variant: Var[Literal["surface", "classic", "ghost"]]
     variant: Var[Literal["surface", "classic", "ghost"]]
 
 
 
 

+ 1 - 1
reflex/components/radix/themes/components/card.pyi

@@ -94,7 +94,7 @@ class Card(elements.Div, RadixThemesComponent):
             *children: Child components.
             *children: Child components.
             as_child: Change the default rendered element for the one passed as a child, merging their props and behavior.
             as_child: Change the default rendered element for the one passed as a child, merging their props and behavior.
             size: Card size: "1" - "5"
             size: Card size: "1" - "5"
-            variant: Variant of Card: "solid" | "soft" | "outline" | "ghost"
+            variant: Variant of Card: "surface" | "classic" | "ghost"
             access_key: Provides a hint for generating a keyboard shortcut for the current element.
             access_key: Provides a hint for generating a keyboard shortcut for the current element.
             auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
             auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
             content_editable: Indicates whether the element's content is editable.
             content_editable: Indicates whether the element's content is editable.

+ 5 - 0
reflex/components/radix/themes/components/context_menu.py

@@ -4,6 +4,7 @@ from typing import Dict, List, Literal, Union
 
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -55,6 +56,8 @@ class ContextMenuTrigger(RadixThemesComponent):
 
 
     _invalid_children: List[str] = ["ContextMenuContent"]
     _invalid_children: List[str] = ["ContextMenuContent"]
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class ContextMenuContent(RadixThemesComponent):
 class ContextMenuContent(RadixThemesComponent):
     """The component that pops out when the context menu is open."""
     """The component that pops out when the context menu is open."""
@@ -153,6 +156,8 @@ class ContextMenuSubTrigger(RadixThemesComponent):
 
 
     _valid_parents: List[str] = ["ContextMenuContent", "ContextMenuSub"]
     _valid_parents: List[str] = ["ContextMenuContent", "ContextMenuSub"]
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class ContextMenuSubContent(RadixThemesComponent):
 class ContextMenuSubContent(RadixThemesComponent):
     """The component that pops out when a submenu is open."""
     """The component that pops out when a submenu is open."""

+ 3 - 0
reflex/components/radix/themes/components/dialog.py

@@ -5,6 +5,7 @@ from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.el import elements
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -31,6 +32,8 @@ class DialogTrigger(RadixThemesTriggerComponent):
 
 
     tag = "Dialog.Trigger"
     tag = "Dialog.Trigger"
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class DialogTitle(RadixThemesComponent):
 class DialogTitle(RadixThemesComponent):
     """Title component to display inside a Dialog modal."""
     """Title component to display inside a Dialog modal."""

+ 5 - 0
reflex/components/radix/themes/components/dropdown_menu.py

@@ -4,6 +4,7 @@ from typing import Dict, List, Literal, Union
 
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -60,6 +61,8 @@ class DropdownMenuTrigger(RadixThemesTriggerComponent):
 
 
     _invalid_children: List[str] = ["DropdownMenuContent"]
     _invalid_children: List[str] = ["DropdownMenuContent"]
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class DropdownMenuContent(RadixThemesComponent):
 class DropdownMenuContent(RadixThemesComponent):
     """The Dropdown Menu Content component that pops out when the dropdown menu is open."""
     """The Dropdown Menu Content component that pops out when the dropdown menu is open."""
@@ -143,6 +146,8 @@ class DropdownMenuSubTrigger(RadixThemesTriggerComponent):
 
 
     _valid_parents: List[str] = ["DropdownMenuContent", "DropdownMenuSub"]
     _valid_parents: List[str] = ["DropdownMenuContent", "DropdownMenuSub"]
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class DropdownMenuSub(RadixThemesComponent):
 class DropdownMenuSub(RadixThemesComponent):
     """Contains all the parts of a submenu."""
     """Contains all the parts of a submenu."""

+ 3 - 0
reflex/components/radix/themes/components/hover_card.py

@@ -5,6 +5,7 @@ from typing import Dict, Literal, Union
 from reflex.components.component import ComponentNamespace
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.el import elements
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -37,6 +38,8 @@ class HoverCardTrigger(RadixThemesTriggerComponent):
 
 
     tag = "HoverCard.Trigger"
     tag = "HoverCard.Trigger"
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class HoverCardContent(elements.Div, RadixThemesComponent):
 class HoverCardContent(elements.Div, RadixThemesComponent):
     """Contains the content of the open hover card."""
     """Contains the content of the open hover card."""

+ 3 - 0
reflex/components/radix/themes/components/popover.py

@@ -5,6 +5,7 @@ from typing import Dict, Literal, Union
 from reflex.components.component import ComponentNamespace
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.el import elements
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -34,6 +35,8 @@ class PopoverTrigger(RadixThemesTriggerComponent):
 
 
     tag = "Popover.Trigger"
     tag = "Popover.Trigger"
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class PopoverContent(elements.Div, RadixThemesComponent):
 class PopoverContent(elements.Div, RadixThemesComponent):
     """Contains content to be rendered in the open popover."""
     """Contains content to be rendered in the open popover."""

+ 2 - 0
reflex/components/radix/themes/components/radio_cards.py

@@ -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."""

+ 1 - 1
reflex/components/radix/themes/components/radio_group.py

@@ -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()
 
 

+ 3 - 0
reflex/components/radix/themes/components/select.py

@@ -5,6 +5,7 @@ from typing import List, Literal, Union
 import reflex as rx
 import reflex as rx
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import no_args_event_spec, passthrough_event_spec
 from reflex.event import no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -69,6 +70,8 @@ class SelectTrigger(RadixThemesComponent):
 
 
     _valid_parents: List[str] = ["SelectRoot"]
     _valid_parents: List[str] = ["SelectRoot"]
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
 
 
 class SelectContent(RadixThemesComponent):
 class SelectContent(RadixThemesComponent):
     """The component that pops out when the select is open."""
     """The component that pops out when the select is open."""

+ 3 - 0
reflex/components/radix/themes/components/tabs.py

@@ -7,6 +7,7 @@ from typing import Any, Dict, List, Literal
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.colors import color
 from reflex.components.core.colors import color
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.vars.base import Var
 from reflex.vars.base import Var
 
 
@@ -95,6 +96,8 @@ class TabsTrigger(RadixThemesComponent):
 
 
     _valid_parents: List[str] = ["TabsList"]
     _valid_parents: List[str] = ["TabsList"]
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
     @classmethod
     @classmethod
     def create(cls, *children, **props) -> Component:
     def create(cls, *children, **props) -> Component:
         """Create a TabsTrigger component.
         """Create a TabsTrigger component.

+ 12 - 0
reflex/components/radix/themes/components/text_area.py

@@ -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

+ 2 - 0
reflex/components/radix/themes/components/text_area.pyi

@@ -268,4 +268,6 @@ class TextArea(RadixThemesComponent, elements.Textarea):
         """
         """
         ...
         ...
 
 
+    def add_style(self): ...
+
 text_area = TextArea.create
 text_area = TextArea.create

+ 1 - 1
reflex/components/radix/themes/components/text_field.py

@@ -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(""),

+ 1 - 1
reflex/components/radix/themes/layout/__init__.pyi

@@ -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

+ 2 - 2
reflex/components/radix/themes/layout/list.py

@@ -72,7 +72,7 @@ class BaseList(Component, MarkdownComponentMap):
             if isinstance(items, Var):
             if isinstance(items, Var):
                 children = [foreach(items, ListItem.create)]
                 children = [foreach(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":

+ 2 - 2
reflex/components/radix/themes/layout/stack.py

@@ -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

+ 1 - 1
reflex/components/radix/themes/typography/link.py

@@ -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:

+ 2 - 2
reflex/components/radix/themes/typography/text.py

@@ -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):

+ 1 - 1
reflex/components/react_player/react_player.py

@@ -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]

+ 11 - 13
reflex/components/recharts/charts.py

@@ -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)
-        dim_props["min_width"] = props.pop("min_width", 10)
+        min_height = props.pop("min_height", 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]]]

+ 1 - 1
reflex/components/recharts/polar.py

@@ -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]

+ 15 - 13
reflex/components/sonner/toast.py

@@ -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:

+ 5 - 5
reflex/components/sonner/toast.pyi

@@ -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

+ 6 - 4
reflex/components/suneditor/editor.py

@@ -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:

+ 2 - 2
reflex/components/suneditor/editor.pyi

@@ -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.
-            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".
+            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".
             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%

+ 25 - 3
reflex/components/tags/tag.py

@@ -3,13 +3,33 @@
 from __future__ import annotations
 from __future__ import annotations
 
 
 import dataclasses
 import dataclasses
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, List, Optional, Sequence, Union
 
 
 from reflex.event import EventChain
 from reflex.event import EventChain
 from reflex.utils import format, types
 from reflex.utils import format, types
 from reflex.vars.base import LiteralVar, Var
 from reflex.vars.base import LiteralVar, Var
 
 
 
 
+def render_prop(value: Any) -> Any:
+    """Render the prop.
+
+    Args:
+        value: The value to render.
+
+    Returns:
+        The rendered value.
+    """
+    from reflex.components.component import BaseComponent
+
+    if isinstance(value, BaseComponent):
+        return value.render()
+    if isinstance(value, Sequence) and not isinstance(value, str):
+        return [render_prop(v) for v in value]
+    if callable(value) and not isinstance(value, Var):
+        return None
+    return value
+
+
 @dataclasses.dataclass()
 @dataclasses.dataclass()
 class Tag:
 class Tag:
     """A React tag."""
     """A React tag."""
@@ -49,7 +69,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
@@ -66,7 +86,9 @@ class Tag:
             Tuple[str, Any]: The field name and value.
             Tuple[str, Any]: The field name and value.
         """
         """
         for field in dataclasses.fields(self):
         for field in dataclasses.fields(self):
-            yield field.name, getattr(self, field.name)
+            rendered_value = render_prop(getattr(self, field.name))
+            if rendered_value is not None:
+                yield field.name, rendered_value
 
 
     def add_props(self, **kwargs: Optional[Any]) -> Tag:
     def add_props(self, **kwargs: Optional[Any]) -> Tag:
         """Add props to the tag.
         """Add props to the tag.

+ 12 - 6
reflex/config.py

@@ -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:
@@ -490,6 +490,9 @@ class EnvironmentVariables:
     # The working directory for the next.js commands.
     # The working directory for the next.js commands.
     REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB))
     REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB))
 
 
+    # The working directory for the states directory.
+    REFLEX_STATES_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.STATES))
+
     # Path to the alembic config file
     # Path to the alembic config file
     ALEMBIC_CONFIG: EnvVar[ExistingPath] = env_var(Path(constants.ALEMBIC_CONFIG))
     ALEMBIC_CONFIG: EnvVar[ExistingPath] = env_var(Path(constants.ALEMBIC_CONFIG))
 
 
@@ -597,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
@@ -700,6 +703,9 @@ class Config(Base):
     # Path to file containing key-values pairs to override in the environment; Dotenv format.
     # Path to file containing key-values pairs to override in the environment; Dotenv format.
     env_file: Optional[str] = None
     env_file: Optional[str] = None
 
 
+    # Whether the app is running in the reflex cloud environment.
+    is_reflex_cloud: bool = False
+
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
         """Initialize the config values.
         """Initialize the config values.
 
 
@@ -763,7 +769,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)

+ 3 - 1
reflex/constants/base.py

@@ -52,7 +52,7 @@ class Dirs(SimpleNamespace):
     # The name of the postcss config file.
     # The name of the postcss config file.
     POSTCSS_JS = "postcss.config.js"
     POSTCSS_JS = "postcss.config.js"
     # The name of the states directory.
     # The name of the states directory.
-    STATES = "states"
+    STATES = ".states"
 
 
 
 
 class Reflex(SimpleNamespace):
 class Reflex(SimpleNamespace):
@@ -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]
 
 

+ 3 - 2
reflex/constants/compiler.py

@@ -1,10 +1,10 @@
 """Compiler variables."""
 """Compiler variables."""
 
 
+import dataclasses
 import enum
 import enum
 from enum import Enum
 from enum import Enum
 from types import SimpleNamespace
 from types import SimpleNamespace
 
 
-from reflex.base import Base
 from reflex.constants import Dirs
 from reflex.constants import Dirs
 from reflex.utils.imports import ImportVar
 from reflex.utils.imports import ImportVar
 
 
@@ -151,7 +151,8 @@ class MemoizationDisposition(enum.Enum):
     NEVER = "never"
     NEVER = "never"
 
 
 
 
-class MemoizationMode(Base):
+@dataclasses.dataclass(frozen=True)
+class MemoizationMode:
     """The mode for memoizing a Component."""
     """The mode for memoizing a Component."""
 
 
     # The conditions under which the component should be memoized.
     # The conditions under which the component should be memoized.

+ 8 - 1
reflex/constants/config.py

@@ -39,7 +39,14 @@ class GitIgnore(SimpleNamespace):
     # The gitignore file.
     # The gitignore file.
     FILE = Path(".gitignore")
     FILE = Path(".gitignore")
     # Files to gitignore.
     # Files to gitignore.
-    DEFAULTS = {Dirs.WEB, "*.db", "__pycache__/", "*.py[cod]", "assets/external/"}
+    DEFAULTS = {
+        Dirs.WEB,
+        Dirs.STATES,
+        "*.db",
+        "__pycache__/",
+        "*.py[cod]",
+        "assets/external/",
+    }
 
 
 
 
 class RequirementsTxt(SimpleNamespace):
 class RequirementsTxt(SimpleNamespace):

+ 2 - 2
reflex/custom_components/custom_components.py

@@ -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

+ 54 - 37
reflex/event.py

@@ -4,7 +4,6 @@ from __future__ import annotations
 
 
 import dataclasses
 import dataclasses
 import inspect
 import inspect
-import sys
 import types
 import types
 import urllib.parse
 import urllib.parse
 from base64 import b64encode
 from base64 import b64encode
@@ -39,6 +38,7 @@ from typing_extensions import (
 )
 )
 
 
 from reflex import constants
 from reflex import constants
+from reflex.constants.compiler import CompileVars, Hooks, Imports
 from reflex.constants.state import FRONTEND_EVENT_STATE
 from reflex.constants.state import FRONTEND_EVENT_STATE
 from reflex.utils import console, format
 from reflex.utils import console, format
 from reflex.utils.exceptions import (
 from reflex.utils.exceptions import (
@@ -245,7 +245,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(
@@ -265,7 +265,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="")
@@ -339,7 +339,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)
 
 
 
 
@@ -542,7 +542,7 @@ class JavasciptKeyboardEvent:
     shiftKey: bool = False  # noqa: N815
     shiftKey: bool = False  # noqa: N815
 
 
 
 
-def input_event(e: Var[JavascriptInputEvent]) -> Tuple[Var[str]]:
+def input_event(e: ObjectVar[JavascriptInputEvent]) -> Tuple[Var[str]]:
     """Get the value from an input event.
     """Get the value from an input event.
 
 
     Args:
     Args:
@@ -563,7 +563,9 @@ class KeyInputInfo(TypedDict):
     shift_key: bool
     shift_key: bool
 
 
 
 
-def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str], Var[KeyInputInfo]]:
+def key_event(
+    e: ObjectVar[JavasciptKeyboardEvent],
+) -> Tuple[Var[str], Var[KeyInputInfo]]:
     """Get the key from a keyboard event.
     """Get the key from a keyboard event.
 
 
     Args:
     Args:
@@ -573,7 +575,7 @@ def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str], Var[KeyInputInf
         The key from the keyboard event.
         The key from the keyboard event.
     """
     """
     return (
     return (
-        e.key,
+        e.key.to(str),
         Var.create(
         Var.create(
             {
             {
                 "alt_key": e.altKey,
                 "alt_key": e.altKey,
@@ -581,7 +583,7 @@ def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str], Var[KeyInputInf
                 "meta_key": e.metaKey,
                 "meta_key": e.metaKey,
                 "shift_key": e.shiftKey,
                 "shift_key": e.shiftKey,
             },
             },
-        ),
+        ).to(KeyInputInfo),
     )
     )
 
 
 
 
@@ -591,7 +593,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.
@@ -654,9 +656,9 @@ def passthrough_event_spec(  # pyright: ignore[reportInconsistentOverload]
         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}",
@@ -738,7 +740,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):
@@ -1058,13 +1060,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.
@@ -1083,7 +1085,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:
@@ -1188,7 +1191,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:
@@ -1201,7 +1204,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:
@@ -1238,7 +1241,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(
@@ -1348,7 +1351,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):
@@ -1360,7 +1363,7 @@ def unwrap_var_annotation(annotation: GenericType):
     Returns:
     Returns:
         The unwrapped annotation.
         The unwrapped annotation.
     """
     """
-    if get_origin(annotation) is Var and (args := get_args(annotation)):
+    if get_origin(annotation) in (Var, ObjectVar) and (args := get_args(annotation)):
         return args[0]
         return args[0]
     return annotation
     return annotation
 
 
@@ -1582,7 +1585,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 = {
@@ -1626,12 +1629,12 @@ class EventVar(ObjectVar, python_types=EventSpec):
 @dataclasses.dataclass(
 @dataclasses.dataclass(
     eq=False,
     eq=False,
     frozen=True,
     frozen=True,
-    **{"slots": True} if sys.version_info >= (3, 10) else {},
+    slots=True,
 )
 )
 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 +1690,7 @@ class EventChainVar(BuilderFunctionVar, python_types=EventChain):
 @dataclasses.dataclass(
 @dataclasses.dataclass(
     eq=False,
     eq=False,
     frozen=True,
     frozen=True,
-    **{"slots": True} if sys.version_info >= (3, 10) else {},
+    slots=True,
 )
 )
 # Note: LiteralVar is second in the inheritance list allowing it act like a
 # Note: LiteralVar is second in the inheritance list allowing it act like a
 # CachedVarOperation (ArgsFunctionOperation) and get the _js_expr from the
 # CachedVarOperation (ArgsFunctionOperation) and get the _js_expr from the
@@ -1695,7 +1698,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.
@@ -1719,13 +1722,16 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
 
 
         Returns:
         Returns:
             The created LiteralEventChainVar instance.
             The created LiteralEventChainVar instance.
+
+        Raises:
+            ValueError: If the invocation is not a FunctionVar.
         """
         """
         arg_spec = (
         arg_spec = (
             value.args_spec[0]
             value.args_spec[0]
             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])
@@ -1736,10 +1742,21 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
             arg_def_expr = Var(_js_expr="args")
             arg_def_expr = Var(_js_expr="args")
 
 
         if value.invocation is None:
         if value.invocation is None:
-            invocation = FunctionStringVar.create("addEvents")
+            invocation = FunctionStringVar.create(
+                CompileVars.ADD_EVENTS,
+                _var_data=VarData(
+                    imports=Imports.EVENTS,
+                    hooks={Hooks.EVENTS: None},
+                ),
+            )
         else:
         else:
             invocation = value.invocation
             invocation = value.invocation
 
 
+        if invocation is not None and not isinstance(invocation, FunctionVar):
+            raise ValueError(
+                f"EventChain invocation must be a FunctionVar, got {invocation!s} of type {invocation._var_type!s}."
+            )
+
         return cls(
         return cls(
             _js_expr="",
             _js_expr="",
             _var_type=EventChain,
             _var_type=EventChain,
@@ -1858,7 +1875,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:
@@ -1867,17 +1884,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:
@@ -1888,9 +1905,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")
@@ -1941,7 +1958,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
@@ -1984,7 +2001,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)

+ 2 - 5
reflex/experimental/client_state.py

@@ -4,7 +4,6 @@ from __future__ import annotations
 
 
 import dataclasses
 import dataclasses
 import re
 import re
-import sys
 from typing import Any, Callable, Union
 from typing import Any, Callable, Union
 
 
 from reflex import constants
 from reflex import constants
@@ -49,7 +48,7 @@ def _client_state_ref_dict(var_name: str) -> str:
 @dataclasses.dataclass(
 @dataclasses.dataclass(
     eq=False,
     eq=False,
     frozen=True,
     frozen=True,
-    **{"slots": True} if sys.version_info >= (3, 10) else {},
+    slots=True,
 )
 )
 class ClientStateVar(Var):
 class ClientStateVar(Var):
     """A Var that exists on the client via useState."""
     """A Var that exists on the client via useState."""
@@ -201,9 +200,7 @@ class ClientStateVar(Var):
             )
             )
             .to(self._var_type)
             .to(self._var_type)
             ._replace(
             ._replace(
-                merge_var_data=VarData(  # type: ignore
-                    imports=_refs_import if self._global_ref else {}
-                )
+                merge_var_data=VarData(imports=_refs_import if self._global_ref else {})
             )
             )
         )
         )
 
 

+ 5 - 5
reflex/experimental/hooks.py

@@ -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:

+ 8 - 5
reflex/experimental/layout.py

@@ -12,6 +12,7 @@ from reflex.components.radix.themes.components.icon_button import IconButton
 from reflex.components.radix.themes.layout.box import Box
 from reflex.components.radix.themes.layout.box import Box
 from reflex.components.radix.themes.layout.container import Container
 from reflex.components.radix.themes.layout.container import Container
 from reflex.components.radix.themes.layout.stack import HStack
 from reflex.components.radix.themes.layout.stack import HStack
+from reflex.constants.compiler import MemoizationMode
 from reflex.event import run_script
 from reflex.event import run_script
 from reflex.experimental import hooks
 from reflex.experimental import hooks
 from reflex.state import ComponentState
 from reflex.state import ComponentState
@@ -44,10 +45,10 @@ class Sidebar(Box, MemoizationLeaf):
         Returns:
         Returns:
             The style of the component.
             The style of the component.
         """
         """
-        sidebar: Component = self.children[-2]  # type: ignore
-        spacer: Component = self.children[-1]  # type: ignore
+        sidebar: Component = self.children[-2]  # pyright: ignore [reportAssignmentType]
+        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")
         )
         )
@@ -146,6 +147,8 @@ sidebar_trigger_style = {
 class SidebarTrigger(Fragment):
 class SidebarTrigger(Fragment):
     """A component that renders the sidebar trigger."""
     """A component that renders the sidebar trigger."""
 
 
+    _memoization_mode = MemoizationMode(recursive=False)
+
     @classmethod
     @classmethod
     def create(cls, sidebar: Component, **props):
     def create(cls, sidebar: Component, **props):
         """Create the sidebar trigger component.
         """Create the sidebar trigger component.
@@ -159,11 +162,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"),

+ 3 - 3
reflex/experimental/misc.py

@@ -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.

+ 1 - 1
reflex/istate/wrappers.py

@@ -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:

+ 11 - 6
reflex/model.py

@@ -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 - 3
reflex/page.py

@@ -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:

+ 14 - 10
reflex/reflex.py

@@ -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),
-    backend_port: str = str(config.backend_port),
+    frontend_port: int = config.frontend_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()

+ 1 - 1
reflex/route.py

@@ -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:

+ 46 - 36
reflex/state.py

@@ -31,6 +31,7 @@ from typing import (
     Optional,
     Optional,
     Sequence,
     Sequence,
     Set,
     Set,
+    SupportsIndex,
     Tuple,
     Tuple,
     Type,
     Type,
     TypeVar,
     TypeVar,
@@ -899,7 +900,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
     def get_substates(cls) -> set[Type[BaseState]]:
     def get_substates(cls) -> set[Type[BaseState]]:
@@ -1058,7 +1059,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:
@@ -1176,14 +1177,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 inner_func(self) -> str:
+        def argsingle_factory(param: 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 inner_func(self) -> List[str]:
+        def arglist_factory(param: 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
@@ -1268,8 +1269,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.__qualname__ = handler.fn.__qualname__  # type: ignore
+            fn.__module__ = handler.fn.__module__
+            fn.__qualname__ = handler.fn.__qualname__
             return fn
             return fn
 
 
         backend_vars = super().__getattribute__("_backend_vars")
         backend_vars = super().__getattribute__("_backend_vars")
@@ -1434,6 +1435,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
         for part1, part2 in zip(
         for part1, part2 in zip(
             cls.get_full_name().split("."),
             cls.get_full_name().split("."),
             other.get_full_name().split("."),
             other.get_full_name().split("."),
+            strict=True,
         ):
         ):
             if part1 != part2:
             if part1 != part2:
                 break
                 break
@@ -1633,11 +1635,13 @@ 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
+
+        unset = object()
 
 
         # 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"):
-            return var._var_value
+        if (var_value := getattr(var, "_var_value", unset)) is not unset:
+            return var_value  # pyright: ignore [reportReturnType]
 
 
         var_data = var._get_all_var_data()
         var_data = var._get_all_var_data()
         if var_data is None or not var_data.state:
         if var_data is None or not var_data.state:
@@ -2452,7 +2456,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]
         ]
         ]
 
 
 
 
@@ -2596,7 +2600,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.
 
 
@@ -2739,7 +2745,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__:
@@ -2752,7 +2758,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:
@@ -2952,7 +2958,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 = {
@@ -3049,7 +3055,7 @@ def is_serializable(value: Any) -> bool:
 
 
 def reset_disk_state_manager():
 def reset_disk_state_manager():
     """Reset the disk state manager."""
     """Reset the disk state manager."""
-    states_directory = prerequisites.get_web_dir() / constants.Dirs.STATES
+    states_directory = prerequisites.get_states_dir()
     if states_directory.exists():
     if states_directory.exists():
         for path in states_directory.iterdir():
         for path in states_directory.iterdir():
             path.unlink()
             path.unlink()
@@ -3070,7 +3076,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 = {
@@ -3097,7 +3103,7 @@ class StateManagerDisk(StateManager):
         Returns:
         Returns:
             The states directory.
             The states directory.
         """
         """
-        return prerequisites.get_web_dir() / constants.Dirs.STATES
+        return prerequisites.get_states_dir()
 
 
     def _purge_expired_states(self):
     def _purge_expired_states(self):
         """Purge expired states from the disk."""
         """Purge expired states from the disk."""
@@ -3542,7 +3548,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:
@@ -3808,10 +3816,10 @@ class MutableProxy(wrapt.ObjectProxy):
 
 
     def _mark_dirty(
     def _mark_dirty(
         self,
         self,
-        wrapped=None,
-        instance=None,
-        args=(),
-        kwargs=None,
+        wrapped: Callable | None = None,
+        instance: BaseState | None = None,
+        args: tuple = (),
+        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.
 
 
@@ -3885,7 +3893,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.
@@ -3944,7 +3954,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:
@@ -3967,7 +3977,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:
@@ -3975,7 +3985,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:
@@ -3983,7 +3993,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:
@@ -3992,7 +4002,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
@@ -4016,7 +4026,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:
@@ -4027,7 +4037,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.
@@ -4091,10 +4101,10 @@ class ImmutableMutableProxy(MutableProxy):
 
 
     def _mark_dirty(
     def _mark_dirty(
         self,
         self,
-        wrapped=None,
-        instance=None,
-        args=(),
-        kwargs=None,
+        wrapped: Callable | None = None,
+        instance: BaseState | None = None,
+        args: tuple = (),
+        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.
 
 

+ 24 - 2
reflex/style.py

@@ -77,7 +77,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")
@@ -181,7 +181,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
 
 
@@ -291,6 +293,26 @@ 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.
+        """
+        other_var_data = None
+        if not isinstance(other, Style):
+            other_dict, other_var_data = convert(other)
+        else:
+            other_dict, other_var_data = other, other._var_data
+
+        new_style = Style(super().__or__(other_dict))
+        if self._var_data or other_var_data:
+            new_style._var_data = VarData.merge(self._var_data, other_var_data)
+        return new_style
+
 
 
 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.

+ 19 - 17
reflex/testing.py

@@ -78,7 +78,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
@@ -88,7 +88,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:
@@ -256,7 +256,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(
                 [
                 [
@@ -300,7 +300,9 @@ class AppHarness:
                 raise RuntimeError("App state is not initialized.")
                 raise RuntimeError("App state is not initialized.")
             self.state_manager = StateManagerRedis.create(self.app_instance._state)
             self.state_manager = StateManagerRedis.create(self.app_instance._state)
         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."""
@@ -325,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(
@@ -428,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.
@@ -623,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")()
-        if driver_clz is webdriver.Chrome:
+                driver_options = getattr(webdriver, f"{requested_driver}Options")()  # pyright: ignore [reportPossiblyUnboundVariable]
+        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:
@@ -655,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
@@ -887,8 +889,8 @@ class Subdir404TCPServer(socketserver.TCPServer):
             request,
             request,
             client_address,
             client_address,
             self,
             self,
-            directory=str(self.root),  # type: ignore
-            error_page_map=self.error_page_map,  # type: ignore
+            directory=str(self.root),  # pyright: ignore [reportCallIssue]
+            error_page_map=self.error_page_map,  # pyright: ignore [reportCallIssue]
         )
         )
 
 
 
 

+ 1 - 1
reflex/utils/build.py

@@ -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:

+ 6 - 5
reflex/utils/compat.py

@@ -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.main"] = pydantic.v1.main  # type: ignore
-        sys.modules["pydantic.errors"] = pydantic.v1.errors  # type: ignore
+        sys.modules["pydantic.fields"] = pydantic.v1.fields  # pyright: ignore [reportAttributeAccessIssue]
+        sys.modules["pydantic.main"] = pydantic.v1.main  # pyright: ignore [reportAttributeAccessIssue]
+        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:

+ 2 - 2
reflex/utils/console.py

@@ -278,7 +278,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.
 
 
@@ -293,7 +293,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():

+ 6 - 2
reflex/utils/exceptions.py

@@ -75,10 +75,14 @@ class VarAttributeError(ReflexError, AttributeError):
     """Custom AttributeError for var related errors."""
     """Custom AttributeError for var related errors."""
 
 
 
 
+class UntypedVarError(ReflexError, TypeError):
+    """Custom TypeError for untyped var errors."""
+
+
 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 +94,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:

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно