ソースを参照

Enable wide assortion of ruff rules (#5372)

* enable ASYNC

* enable RET

* enable RSE

* enable most of PT

* enable RUF006

* enable RUF008

* enable SIM115

* enable B008

* enable EM

* enable FLY

* enable INP but disable it for tests

* enable NPY

* enable PD

* enable PIE

* enable TID

* addendum to ASYNC, fixes redis ci

* merge with main

* replace msg, with msg

* replace segment
Khaleel Al-Adhami 2 日 前
コミット
24cf76424c
100 ファイル変更602 行追加601 行削除
  1. 51 51
      pyi_hashes.json
  2. 17 16
      pyproject.toml
  3. 0 2
      reflex/.templates/apps/blank/code/blank.py
  4. 60 67
      reflex/app.py
  5. 2 3
      reflex/app_mixins/lifespan.py
  6. 1 0
      reflex/app_mixins/middleware.py
  7. 0 1
      reflex/app_mixins/mixin.py
  8. 6 3
      reflex/assets.py
  9. 3 2
      reflex/base.py
  10. 20 23
      reflex/compiler/compiler.py
  11. 8 6
      reflex/compiler/utils.py
  12. 5 7
      reflex/components/base/bare.py
  13. 2 1
      reflex/components/base/meta.py
  14. 2 1
      reflex/components/base/script.py
  15. 34 37
      reflex/components/component.py
  16. 9 11
      reflex/components/core/breakpoints.py
  17. 10 7
      reflex/components/core/colors.py
  18. 4 2
      reflex/components/core/cond.py
  19. 5 3
      reflex/components/core/debounce.py
  20. 8 6
      reflex/components/core/foreach.py
  21. 3 3
      reflex/components/core/html.py
  22. 19 17
      reflex/components/core/match.py
  23. 1 2
      reflex/components/datadisplay/code.py
  24. 7 10
      reflex/components/datadisplay/dataeditor.py
  25. 3 4
      reflex/components/datadisplay/logo.py
  26. 8 11
      reflex/components/datadisplay/shiki_code_block.py
  27. 2 3
      reflex/components/dynamic.py
  28. 2 3
      reflex/components/el/elements/forms.py
  29. 0 1
      reflex/components/el/elements/metadata.py
  30. 10 13
      reflex/components/gridjs/datatable.py
  31. 10 9
      reflex/components/lucide/icon.py
  32. 6 8
      reflex/components/markdown/markdown.py
  33. 0 2
      reflex/components/next/base.py
  34. 2 3
      reflex/components/props.py
  35. 1 3
      reflex/components/radix/primitives/base.py
  36. 4 8
      reflex/components/radix/primitives/form.py
  37. 4 2
      reflex/components/radix/themes/components/alert_dialog.py
  38. 1 2
      reflex/components/radix/themes/components/aspect_ratio.py
  39. 5 2
      reflex/components/radix/themes/components/avatar.py
  40. 5 2
      reflex/components/radix/themes/components/badge.py
  41. 2 3
      reflex/components/radix/themes/components/button.py
  42. 1 2
      reflex/components/radix/themes/components/callout.py
  43. 1 2
      reflex/components/radix/themes/components/card.py
  44. 7 4
      reflex/components/radix/themes/components/checkbox.py
  45. 1 2
      reflex/components/radix/themes/components/checkbox_cards.py
  46. 1 2
      reflex/components/radix/themes/components/checkbox_group.py
  47. 1 1
      reflex/components/radix/themes/components/context_menu.py
  48. 1 2
      reflex/components/radix/themes/components/data_list.py
  49. 4 2
      reflex/components/radix/themes/components/dialog.py
  50. 5 2
      reflex/components/radix/themes/components/dropdown_menu.py
  51. 4 2
      reflex/components/radix/themes/components/hover_card.py
  52. 7 8
      reflex/components/radix/themes/components/icon_button.py
  53. 1 2
      reflex/components/radix/themes/components/inset.py
  54. 4 2
      reflex/components/radix/themes/components/popover.py
  55. 1 2
      reflex/components/radix/themes/components/progress.py
  56. 1 2
      reflex/components/radix/themes/components/radio.py
  57. 1 2
      reflex/components/radix/themes/components/radio_cards.py
  58. 7 5
      reflex/components/radix/themes/components/radio_group.py
  59. 1 2
      reflex/components/radix/themes/components/scroll_area.py
  60. 1 2
      reflex/components/radix/themes/components/segmented_control.py
  61. 5 2
      reflex/components/radix/themes/components/select.py
  62. 1 2
      reflex/components/radix/themes/components/separator.py
  63. 1 2
      reflex/components/radix/themes/components/skeleton.py
  64. 1 2
      reflex/components/radix/themes/components/slider.py
  65. 1 2
      reflex/components/radix/themes/components/spinner.py
  66. 1 2
      reflex/components/radix/themes/components/switch.py
  67. 1 2
      reflex/components/radix/themes/components/table.py
  68. 1 2
      reflex/components/radix/themes/components/tabs.py
  69. 5 2
      reflex/components/radix/themes/components/text_area.py
  70. 5 2
      reflex/components/radix/themes/components/text_field.py
  71. 1 2
      reflex/components/radix/themes/components/tooltip.py
  72. 5 2
      reflex/components/radix/themes/layout/base.py
  73. 1 2
      reflex/components/radix/themes/layout/box.py
  74. 1 2
      reflex/components/radix/themes/layout/container.py
  75. 6 2
      reflex/components/radix/themes/layout/flex.py
  76. 6 2
      reflex/components/radix/themes/layout/grid.py
  77. 2 1
      reflex/components/radix/themes/layout/list.py
  78. 1 2
      reflex/components/radix/themes/layout/section.py
  79. 1 1
      reflex/components/radix/themes/layout/stack.py
  80. 1 1
      reflex/components/radix/themes/typography/blockquote.py
  81. 5 1
      reflex/components/radix/themes/typography/code.py
  82. 1 1
      reflex/components/radix/themes/typography/heading.py
  83. 3 2
      reflex/components/radix/themes/typography/link.py
  84. 1 1
      reflex/components/radix/themes/typography/text.py
  85. 0 2
      reflex/components/react_player/audio.py
  86. 0 2
      reflex/components/react_player/video.py
  87. 2 1
      reflex/components/recharts/charts.py
  88. 2 1
      reflex/components/sonner/toast.py
  89. 2 1
      reflex/components/suneditor/editor.py
  90. 4 2
      reflex/components/tags/iter_tag.py
  91. 25 31
      reflex/config.py
  92. 3 3
      reflex/constants/base.py
  93. 8 6
      reflex/constants/compiler.py
  94. 1 2
      reflex/custom_components/custom_components.py
  95. 58 60
      reflex/event.py
  96. 2 2
      reflex/experimental/__init__.py
  97. 6 3
      reflex/experimental/client_state.py
  98. 15 19
      reflex/istate/manager.py
  99. 19 12
      reflex/istate/proxy.py
  100. 6 4
      reflex/model.py

+ 51 - 51
pyi_hashes.json

@@ -42,7 +42,7 @@
   "reflex/components/lucide/icon.pyi": "775e6686e491fd46f28a00b19699db3d",
   "reflex/components/markdown/markdown.pyi": "73d3116fa28450c90f25b21107285daa",
   "reflex/components/moment/moment.pyi": "ab1d6618159693014fdf22b4aa84c877",
-  "reflex/components/next/base.pyi": "5ea32ecae5c64e02217c8895783f9ccb",
+  "reflex/components/next/base.pyi": "5e75245c2b0ee4715f89efaf42d101d8",
   "reflex/components/next/image.pyi": "8c305c03019d37c07560c154a05bf5dd",
   "reflex/components/next/link.pyi": "cc438e48a9f31bf16f1cdb6e16017477",
   "reflex/components/next/video.pyi": "8f5694a4a2118c5297e2eba479b6f018",
@@ -52,68 +52,68 @@
   "reflex/components/radix/primitives/accordion.pyi": "a31599f0b2a1a69a10917137dcb75a9d",
   "reflex/components/radix/primitives/base.pyi": "fc910c9bd364b57e1c092fbf8889158d",
   "reflex/components/radix/primitives/drawer.pyi": "8f20bac0e36266398be1a124218bda87",
-  "reflex/components/radix/primitives/form.pyi": "11402dfac6256f2220c5c830008b8b8b",
+  "reflex/components/radix/primitives/form.pyi": "efd2ec67535eb1b1eefaafc0d5e36d8a",
   "reflex/components/radix/primitives/progress.pyi": "98b4add410a80a353ab503ad577169c2",
   "reflex/components/radix/primitives/slider.pyi": "573837a7d8d90deaf57c911faffed254",
   "reflex/components/radix/themes/__init__.pyi": "a15f9464ad99f248249ffa8e6deea4cf",
   "reflex/components/radix/themes/base.pyi": "526db93a3f52bb00ad220f8744eba797",
   "reflex/components/radix/themes/color_mode.pyi": "f7515dccd1e315dc28a3cbbe2eabe7ff",
   "reflex/components/radix/themes/components/__init__.pyi": "87bb9ffff641928562da1622d2ca5993",
-  "reflex/components/radix/themes/components/alert_dialog.pyi": "9f19bcdb4588a7f76596d142a0ac0950",
-  "reflex/components/radix/themes/components/aspect_ratio.pyi": "ecace271fa2c518c429594556ddf4389",
-  "reflex/components/radix/themes/components/avatar.pyi": "51d3f65fb3e5c4abda00cc8bf4a7e50c",
-  "reflex/components/radix/themes/components/badge.pyi": "1ecf1253abb3a7e293146d4cc6327ceb",
-  "reflex/components/radix/themes/components/button.pyi": "70b5258eb4c2716af39f1b2e5bfc4cbb",
-  "reflex/components/radix/themes/components/callout.pyi": "aa9d08f1246d9c7f97ad6a3ac4d5fcb5",
-  "reflex/components/radix/themes/components/card.pyi": "60374dee8093535874fac2901d993aaf",
-  "reflex/components/radix/themes/components/checkbox.pyi": "0766d08ef379dd919134ff22481528c6",
-  "reflex/components/radix/themes/components/checkbox_cards.pyi": "7cb7297d3e3388efbd2b678278bb034b",
-  "reflex/components/radix/themes/components/checkbox_group.pyi": "0878853ed682b3930fbf0c4f0a655ba2",
-  "reflex/components/radix/themes/components/context_menu.pyi": "4f64ded6e04727c9d24ef2518f9db540",
-  "reflex/components/radix/themes/components/data_list.pyi": "a07a9e89e0fb3f10db78549029fecb37",
-  "reflex/components/radix/themes/components/dialog.pyi": "8b9725b561c253b37562279ce94a99e9",
-  "reflex/components/radix/themes/components/dropdown_menu.pyi": "1a0bdafb4fa95044c8edcc9e83efacf5",
-  "reflex/components/radix/themes/components/hover_card.pyi": "f15aedcd77ce8a7ab7f7470780fe4035",
-  "reflex/components/radix/themes/components/icon_button.pyi": "3887d4225f5ead440e8aeecceec990fd",
-  "reflex/components/radix/themes/components/inset.pyi": "3dbda9fbe5f660c8bfda717aceb0dbdc",
-  "reflex/components/radix/themes/components/popover.pyi": "bf2cd9e744a23305b74ff888d980993f",
-  "reflex/components/radix/themes/components/progress.pyi": "a5610ee8a8eab36b1aada37e866f9494",
-  "reflex/components/radix/themes/components/radio.pyi": "69f5c47aee9a1179c273a4e4765c6099",
-  "reflex/components/radix/themes/components/radio_cards.pyi": "6f323c60aff4da0f576655c32d208bb8",
-  "reflex/components/radix/themes/components/radio_group.pyi": "4d9d918832555a5fa3efa4a71df15ad2",
-  "reflex/components/radix/themes/components/scroll_area.pyi": "7b507e661c87b08061df4e13e73ab47b",
-  "reflex/components/radix/themes/components/segmented_control.pyi": "a848ceda014c4f64a1adc89202598c15",
-  "reflex/components/radix/themes/components/select.pyi": "b223797edc8b9d3341c105c796d392de",
-  "reflex/components/radix/themes/components/separator.pyi": "92c789575a1336bb3e5dcd2012fb68a1",
-  "reflex/components/radix/themes/components/skeleton.pyi": "34340e43123c2aaa89f042411cae06ec",
-  "reflex/components/radix/themes/components/slider.pyi": "023bc8fada28779c0d2f8f14f8b30fec",
-  "reflex/components/radix/themes/components/spinner.pyi": "941dfcee9581f116af7c7116084a6938",
-  "reflex/components/radix/themes/components/switch.pyi": "9e3dfd7dfa16166bb2adc5fb60b25438",
-  "reflex/components/radix/themes/components/table.pyi": "5643313daebc43bc6246d0beee81505f",
-  "reflex/components/radix/themes/components/tabs.pyi": "0bc64cfc23592767477af649339f0e4e",
-  "reflex/components/radix/themes/components/text_area.pyi": "8d976ea7e23b0f5942aeb3a0d295835c",
-  "reflex/components/radix/themes/components/text_field.pyi": "77b28c7caebea3fdb4ba5ef6f3ce19f3",
-  "reflex/components/radix/themes/components/tooltip.pyi": "050ecd7a591e358170d332b1e9c07059",
+  "reflex/components/radix/themes/components/alert_dialog.pyi": "3832f3e8a6a3eed1bfa969efea627b72",
+  "reflex/components/radix/themes/components/aspect_ratio.pyi": "f90aa46ef8b29bd076d98321de96315a",
+  "reflex/components/radix/themes/components/avatar.pyi": "d40e8e25a9c007f2554590abd116a095",
+  "reflex/components/radix/themes/components/badge.pyi": "422c4d1586e6b22d00a2d5f002989651",
+  "reflex/components/radix/themes/components/button.pyi": "fc5c290d6df9b5197c65036c9edafa38",
+  "reflex/components/radix/themes/components/callout.pyi": "f81f5032d90e36705fd5b5ba30d3f3ab",
+  "reflex/components/radix/themes/components/card.pyi": "fdf71624bdeeba391d1c0545039dd2e7",
+  "reflex/components/radix/themes/components/checkbox.pyi": "006614845a236f6611c656c05a8db394",
+  "reflex/components/radix/themes/components/checkbox_cards.pyi": "289d0fd448f654e17f3132234e9d4983",
+  "reflex/components/radix/themes/components/checkbox_group.pyi": "8eb8cca3e0c5885150576cc60ba19fea",
+  "reflex/components/radix/themes/components/context_menu.pyi": "5f178adef09c0f36103e33b11326cb2a",
+  "reflex/components/radix/themes/components/data_list.pyi": "4014ea23eec39cfe98032852665a92ca",
+  "reflex/components/radix/themes/components/dialog.pyi": "8dc1a09d30aff2fcf28e28988fca170f",
+  "reflex/components/radix/themes/components/dropdown_menu.pyi": "0cd87cddbe9a83dcfa9cbcc4f9d98dd4",
+  "reflex/components/radix/themes/components/hover_card.pyi": "973a4911f68cec60f40a8e2ca5e42770",
+  "reflex/components/radix/themes/components/icon_button.pyi": "55e0b8c8233d1e5a52a8c09c959e4989",
+  "reflex/components/radix/themes/components/inset.pyi": "a215de3b29b2133626cbfc83544305fe",
+  "reflex/components/radix/themes/components/popover.pyi": "1fa6f96aef6f148f110fa208aa449ab7",
+  "reflex/components/radix/themes/components/progress.pyi": "1d0f827e8db089418b2786f82d55512d",
+  "reflex/components/radix/themes/components/radio.pyi": "a8fcc63bf42129196d70a9571647d4bb",
+  "reflex/components/radix/themes/components/radio_cards.pyi": "b5222b86e418920de2ef988752f0b577",
+  "reflex/components/radix/themes/components/radio_group.pyi": "7b95ee1fcd41186f2c7670be273d134f",
+  "reflex/components/radix/themes/components/scroll_area.pyi": "28352b03135ef2065876a5199b9c150a",
+  "reflex/components/radix/themes/components/segmented_control.pyi": "0477ee74033ed0f67cd2cb94a47ccea9",
+  "reflex/components/radix/themes/components/select.pyi": "9c63eb11bab2d2913431ec0c13111b6d",
+  "reflex/components/radix/themes/components/separator.pyi": "f8c9c18ea7f67e8287f4ebc5c09790b5",
+  "reflex/components/radix/themes/components/skeleton.pyi": "aeff3cbc53989c4824a5e49e9ea3bbca",
+  "reflex/components/radix/themes/components/slider.pyi": "242e107d73ec14d984cb88fa8f23ad68",
+  "reflex/components/radix/themes/components/spinner.pyi": "5050ba710b0c950c29f69cafd93f6c4f",
+  "reflex/components/radix/themes/components/switch.pyi": "61729a28148bc17acd20e48c12f60a54",
+  "reflex/components/radix/themes/components/table.pyi": "81c77cecf78ddb3e931c9a5f0f8eccde",
+  "reflex/components/radix/themes/components/tabs.pyi": "6facf7ebd344f8995934a167af01a9e5",
+  "reflex/components/radix/themes/components/text_area.pyi": "eef90fcc66990c44f3c0540862877cba",
+  "reflex/components/radix/themes/components/text_field.pyi": "92552297cc747dd3aae6f382699e319d",
+  "reflex/components/radix/themes/components/tooltip.pyi": "5e17b67e50410f1124d2150237eab7cf",
   "reflex/components/radix/themes/layout/__init__.pyi": "9a52c5b283c864be70b51a8fd6120392",
-  "reflex/components/radix/themes/layout/base.pyi": "a3a869acd2a1c5025580697ae5e2c024",
-  "reflex/components/radix/themes/layout/box.pyi": "d2d2b266eed53e866c5b5ad8cee292e4",
+  "reflex/components/radix/themes/layout/base.pyi": "6a255a392bf0d54c924c26e673248971",
+  "reflex/components/radix/themes/layout/box.pyi": "731cc26fc41d2b174ed4e901f5292479",
   "reflex/components/radix/themes/layout/center.pyi": "e0592f33bdec5586a7377ca986f1a966",
-  "reflex/components/radix/themes/layout/container.pyi": "691ec3a849be5f42c0b5d6ba1b243b55",
-  "reflex/components/radix/themes/layout/flex.pyi": "ed2746b5cd2b3d9ef73e370f85a66043",
-  "reflex/components/radix/themes/layout/grid.pyi": "6543e4413501fd41a20ff4d58931b584",
+  "reflex/components/radix/themes/layout/container.pyi": "3c5ddf03873da9bf0f5308d5d6429097",
+  "reflex/components/radix/themes/layout/flex.pyi": "8d8cfd4f00e21aac8d165ded0f7c600f",
+  "reflex/components/radix/themes/layout/grid.pyi": "412f164266f810671cf38ca5e50d9cfd",
   "reflex/components/radix/themes/layout/list.pyi": "32ce23a3f851698ac0d609e616bd3605",
-  "reflex/components/radix/themes/layout/section.pyi": "2b9b826ab42eae3f8cf4d1899dea4b33",
+  "reflex/components/radix/themes/layout/section.pyi": "2904116ccc24dcb66285ff2daaac1875",
   "reflex/components/radix/themes/layout/spacer.pyi": "3def4df36e8eecdfba0a7d2f1890b908",
-  "reflex/components/radix/themes/layout/stack.pyi": "1b09d9123358d430ad6c66343d0e9c92",
+  "reflex/components/radix/themes/layout/stack.pyi": "b7ec458d254cd09058ca805d553199da",
   "reflex/components/radix/themes/typography/__init__.pyi": "ef0ba71353dcac1f3546de45f8721bae",
-  "reflex/components/radix/themes/typography/blockquote.pyi": "04de9fdb22583d87faaba5619bdc6e3e",
-  "reflex/components/radix/themes/typography/code.pyi": "bd58d40878c3488f1ba58a122e78f4e7",
-  "reflex/components/radix/themes/typography/heading.pyi": "91bfc9176f7e9ef33d1f69711ceddbe1",
-  "reflex/components/radix/themes/typography/link.pyi": "febffdd31eee7a4f67d12d6e10a13516",
-  "reflex/components/radix/themes/typography/text.pyi": "d2ba2f718acd0eaf7b5923fe6a27d59c",
-  "reflex/components/react_player/audio.pyi": "bd7e024d39ac641f8279ee0f6afd7985",
+  "reflex/components/radix/themes/typography/blockquote.pyi": "fdd2214a8416bcd4ba644a0bd0015c5a",
+  "reflex/components/radix/themes/typography/code.pyi": "2e0b487ed1128422bfc4105928dbb18a",
+  "reflex/components/radix/themes/typography/heading.pyi": "bec5af8f72e3c0a764d77e16608da4a1",
+  "reflex/components/radix/themes/typography/link.pyi": "196d6ef6c1a15f2d7180a973e8753ea5",
+  "reflex/components/radix/themes/typography/text.pyi": "33f91de2a0ae94e5802e7c8f0971b1df",
+  "reflex/components/react_player/audio.pyi": "231e9338b19330a6963928f7e90cb40f",
   "reflex/components/react_player/react_player.pyi": "40db798bcb7fa40207d24f49722135ae",
-  "reflex/components/react_player/video.pyi": "22d84a7f57be13ece90cb30536d76c7d",
+  "reflex/components/react_player/video.pyi": "f92885d49cdc565b95b20820d09e2ca2",
   "reflex/components/recharts/__init__.pyi": "a060a4abcd018165bc499173e723cf9e",
   "reflex/components/recharts/cartesian.pyi": "601e1acb0ad6bd93ce371d763220aabe",
   "reflex/components/recharts/charts.pyi": "2f0a39f9c02de83d9e2d97763b4411af",

+ 17 - 16
pyproject.toml

@@ -91,50 +91,51 @@ lint.ignore = [
   "ANN2",
   "ANN4",
   "ARG",
-  "ASYNC",
-  "B008",
   "BLE",
   "C901",
   "COM",
   "D205",
   "DTZ",
   "E501",
-  "EM",
   "F403",
   "FBT",
   "FIX",
-  "FLY",
   "G004",
-  "INP",
   "ISC003",
-  "NPY",
-  "PD",
-  "PIE",
   "PLC",
   "PLR",
   "PLW",
-  "PT",
+  "PT011",
+  "PT012",
   "PYI",
-  "RET",
-  "RSE",
-  "RUF006",
-  "RUF008",
   "RUF012",
   "S",
-  "SIM115",
   "SLF",
   "SLOT",
   "TC",
   "TD",
-  "TID",
   "TRY0",
   "UP038",
 ]
 lint.pydocstyle.convention = "google"
+lint.flake8-bugbear.extend-immutable-calls = [
+  "reflex.utils.types.Unset",
+  "reflex.vars.base.Var.create",
+]
 
 [tool.ruff.lint.per-file-ignores]
 "__init__.py" = ["F401"]
-"tests/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
+"tests/*.py" = [
+  "ANN001",
+  "D100",
+  "D103",
+  "D104",
+  "INP",
+  "B018",
+  "PERF",
+  "T",
+  "N",
+]
 "benchmarks/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
 "reflex/.templates/*.py" = ["D100", "D103", "D104"]
 "*.pyi" = ["D301", "D415", "D417", "D418", "E742", "N", "PGH"]

+ 0 - 2
reflex/.templates/apps/blank/code/blank.py

@@ -8,8 +8,6 @@ from rxconfig import config
 class State(rx.State):
     """The app state."""
 
-    ...
-
 
 def index() -> rx.Component:
     # Welcome Page (Index)

+ 60 - 67
reflex/app.py

@@ -229,8 +229,6 @@ def default_error_boundary(*children: Component) -> Component:
 class OverlayFragment(Fragment):
     """Alias for Fragment, used to wrap the overlay_component."""
 
-    pass
-
 
 @dataclasses.dataclass(frozen=True)
 class UploadFile(StarletteUploadFile):
@@ -262,6 +260,7 @@ class UploadFile(StarletteUploadFile):
         """
         if self.path:
             return self.path.name
+        return None
 
     @property
     def filename(self) -> str | None:
@@ -481,9 +480,8 @@ class App(MiddlewareMixin, LifespanMixin):
         # Special case to allow test cases have multiple subclasses of rx.BaseState.
         if not is_testing_env() and BaseState.__subclasses__() != [State]:
             # Only rx.State is allowed as Base State subclass.
-            raise ValueError(
-                "rx.BaseState cannot be subclassed directly. Use rx.State instead"
-            )
+            msg = "rx.BaseState cannot be subclassed directly. Use rx.State instead"
+            raise ValueError(msg)
 
         get_config(reload=True)
 
@@ -552,9 +550,8 @@ class App(MiddlewareMixin, LifespanMixin):
                 transports=["websocket"],
             )
         elif getattr(self.sio, "async_mode", "") != "asgi":
-            raise RuntimeError(
-                f"Custom `sio` must use `async_mode='asgi'`, not '{self.sio.async_mode}'."
-            )
+            msg = f"Custom `sio` must use `async_mode='asgi'`, not '{self.sio.async_mode}'."
+            raise RuntimeError(msg)
 
         # Create the socket app. Note event endpoint constant replaces the default 'socket.io' path.
         socket_app = EngineIOApp(self.sio, socketio_path="")
@@ -633,7 +630,8 @@ class App(MiddlewareMixin, LifespanMixin):
         compile_future.result()
 
         if not self._api:
-            raise ValueError("The app has not been initialized.")
+            msg = "The app has not been initialized."
+            raise ValueError(msg)
 
         if self._cached_fastapi_app is not None:
             asgi_app = self._cached_fastapi_app
@@ -741,7 +739,8 @@ class App(MiddlewareMixin, LifespanMixin):
             ValueError: if the state has not been initialized.
         """
         if self._state_manager is None:
-            raise ValueError("The state manager has not been initialized.")
+            msg = "The state manager has not been initialized."
+            raise ValueError(msg)
         return self._state_manager
 
     @staticmethod
@@ -791,9 +790,8 @@ class App(MiddlewareMixin, LifespanMixin):
         # If the route is not set, get it from the callable.
         if route is None:
             if not isinstance(component, Callable):
-                raise exceptions.RouteValueError(
-                    "Route must be set if component is not a callable."
-                )
+                msg = "Route must be set if component is not a callable."
+                raise exceptions.RouteValueError(msg)
             # Format the route.
             route = format.format_route(component.__name__)
         else:
@@ -808,9 +806,8 @@ class App(MiddlewareMixin, LifespanMixin):
             image = image or constants.Page404.IMAGE
         else:
             if component is None:
-                raise exceptions.PageValueError(
-                    "Component must be set for a non-404 page."
-                )
+                msg = "Component must be set for a non-404 page."
+                raise exceptions.PageValueError(msg)
 
         # Check if the route given is valid
         verify_route_validity(route)
@@ -841,11 +838,12 @@ class App(MiddlewareMixin, LifespanMixin):
                     else f"`{route}`"
                 )
                 existing_component = self._unevaluated_pages[route].component
-                raise exceptions.RouteValueError(
+                msg = (
                     f"Tried to add page {readable_name_from_component(component)} with route {route_name} but "
                     f"page {readable_name_from_component(existing_component)} with the same route already exists. "
                     "Make sure you do not have two pages with the same route."
                 )
+                raise exceptions.RouteValueError(msg)
 
         # Setup dynamic args for the route.
         # this state assignment is only required for tests using the deprecated state kwarg for App
@@ -930,10 +928,9 @@ class App(MiddlewareMixin, LifespanMixin):
             ):
                 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
-                    raise RouteValueError(
-                        f"You cannot use different slug names for the same dynamic path in  {route} and {new_route} ('{r}' != '{nr}')"
-                    )
-                elif rw not in segments and r != nr:
+                    msg = f"You cannot use different slug names for the same dynamic path in  {route} and {new_route} ('{r}' != '{nr}')"
+                    raise RouteValueError(msg)
+                if rw not in segments and r != nr:
                     # if the section being compared in both routes is not a dynamic segment(i.e not wrapped in brackets)
                     # then we are guaranteed that the route is valid and there's no need checking the rest.
                     # eg. /posts/[id]/info/[slug1] and /posts/[id]/info1/[slug1] is always going to be valid since
@@ -1088,9 +1085,7 @@ class App(MiddlewareMixin, LifespanMixin):
             return component
 
         # recreate OverlayFragment with overlay_component as first child
-        component = OverlayFragment.create(overlay_component, *children)
-
-        return component
+        return OverlayFragment.create(overlay_component, *children)
 
     def _setup_overlay_component(self):
         """If a State is not used and no overlay_component is specified, do not render the connection modal."""
@@ -1152,9 +1147,8 @@ class App(MiddlewareMixin, LifespanMixin):
                 )
                 for dep in dep_set:
                     if dep not in state_cls.vars and dep not in state_cls.backend_vars:
-                        raise exceptions.VarDependencyError(
-                            f"ComputedVar {var._js_expr} on state {state.__name__} has an invalid dependency {state_name}.{dep}"
-                        )
+                        msg = f"ComputedVar {var._js_expr} on state {state.__name__} has an invalid dependency {state_name}.{dep}"
+                        raise exceptions.VarDependencyError(msg)
 
         for substate in state.class_subclasses:
             self._validate_var_dependencies(substate)
@@ -1346,10 +1340,11 @@ class App(MiddlewareMixin, LifespanMixin):
 
         # Catch "static" apps (that do not define a rx.State subclass) which are trying to access rx.State.
         if code_uses_state_contexts(stateful_components_code) and self._state is None:
-            raise ReflexRuntimeError(
+            msg = (
                 "To access rx.State in frontend components, at least one "
                 "subclass of rx.State must be defined in the app."
             )
+            raise ReflexRuntimeError(msg)
         compile_results.append((stateful_components_path, stateful_components_code))
 
         progress.advance(task)
@@ -1543,9 +1538,8 @@ class App(MiddlewareMixin, LifespanMixin):
                 if path.exists():
                     file_content = path.read_text()
                 else:
-                    raise FileNotFoundError(
-                        f"Plugin {plugin_name} is trying to modify {path} but it does not exist."
-                    )
+                    msg = f"Plugin {plugin_name} is trying to modify {path} but it does not exist."
+                    raise FileNotFoundError(msg)
             output_mapping[path] = modify_fn(file_content)
 
         with console.timing("Write to Disk"):
@@ -1588,7 +1582,8 @@ class App(MiddlewareMixin, LifespanMixin):
             RuntimeError: If the app has not been initialized yet.
         """
         if self.event_namespace is None:
-            raise RuntimeError("App has not been initialized yet.")
+            msg = "App has not been initialized yet."
+            raise RuntimeError(msg)
 
         # Get exclusive access to the state.
         async with self.state_manager.modify_state(token) as state:
@@ -1627,7 +1622,8 @@ class App(MiddlewareMixin, LifespanMixin):
                 RuntimeError: If the app has not been initialized yet.
             """
             if self.event_namespace is None:
-                raise RuntimeError("App has not been initialized yet.")
+                msg = "App has not been initialized yet."
+                raise RuntimeError(msg)
 
             # Process the event.
             async for update in state._process_event(
@@ -1678,20 +1674,17 @@ class App(MiddlewareMixin, LifespanMixin):
                 _fn_name = type(handler_fn).__name__
 
             if isinstance(handler_fn, functools.partial):
-                raise ValueError(
-                    f"Provided custom {handler_domain} exception handler `{_fn_name}` is a partial function. Please provide a named function instead."
-                )
+                msg = f"Provided custom {handler_domain} exception handler `{_fn_name}` is a partial function. Please provide a named function instead."
+                raise ValueError(msg)
 
             if not callable(handler_fn):
-                raise ValueError(
-                    f"Provided custom {handler_domain} exception handler `{_fn_name}` is not a function."
-                )
+                msg = f"Provided custom {handler_domain} exception handler `{_fn_name}` is not a function."
+                raise ValueError(msg)
 
             # Allow named functions only as lambda functions cannot be introspected
             if _fn_name == "<lambda>":
-                raise ValueError(
-                    f"Provided custom {handler_domain} exception handler `{_fn_name}` is a lambda function. Please use a named function instead."
-                )
+                msg = f"Provided custom {handler_domain} exception handler `{_fn_name}` is a lambda function. Please use a named function instead."
+                raise ValueError(msg)
 
             # Check if the function has the necessary annotations and types in the right order
             argspec = inspect.getfullargspec(handler_fn)
@@ -1703,22 +1696,21 @@ class App(MiddlewareMixin, LifespanMixin):
 
             for required_arg_index, required_arg in enumerate(handler_spec):
                 if required_arg not in arg_annotations:
-                    raise ValueError(
-                        f"Provided custom {handler_domain} exception handler `{_fn_name}` does not take the required argument `{required_arg}`"
-                    )
-                elif (
-                    not list(arg_annotations.keys())[required_arg_index] == required_arg
-                ):
-                    raise ValueError(
+                    msg = f"Provided custom {handler_domain} exception handler `{_fn_name}` does not take the required argument `{required_arg}`"
+                    raise ValueError(msg)
+                if list(arg_annotations.keys())[required_arg_index] != required_arg:
+                    msg = (
                         f"Provided custom {handler_domain} exception handler `{_fn_name}` has the wrong argument order."
                         f"Expected `{required_arg}` as the {required_arg_index + 1} argument but got `{list(arg_annotations.keys())[required_arg_index]}`"
                     )
+                    raise ValueError(msg)
 
                 if not issubclass(arg_annotations[required_arg], Exception):
-                    raise ValueError(
+                    msg = (
                         f"Provided custom {handler_domain} exception handler `{_fn_name}` has the wrong type for {required_arg} argument."
                         f"Expected to be `Exception` but got `{arg_annotations[required_arg]}`"
                     )
+                    raise ValueError(msg)
 
             # Check if the return type is valid for backend exception handler
             if handler_domain == "backend":
@@ -1738,10 +1730,11 @@ class App(MiddlewareMixin, LifespanMixin):
                 )
 
                 if not valid:
-                    raise ValueError(
+                    msg = (
                         f"Provided custom {handler_domain} exception handler `{_fn_name}` has the wrong return type."
                         f"Expected `EventSpec | list[EventSpec] | None` but got `{return_type}`"
                     )
+                    raise ValueError(msg)
 
 
 async def process(
@@ -1910,7 +1903,8 @@ def upload(app: App):
             return Response()  # user cancelled
         files = files.getlist("files")
         if not files:
-            raise UploadValueError("No files were uploaded.")
+            msg = "No files were uploaded."
+            raise UploadValueError(msg)
 
         token = request.headers.get("reflex-client-token")
         handler = request.headers.get("reflex-event-handler")
@@ -1937,9 +1931,8 @@ def upload(app: App):
         # check if there exists any handler args with annotation, list[UploadFile]
         if isinstance(func, EventHandler):
             if func.is_background:
-                raise UploadTypeError(
-                    f"@rx.event(background=True) is not supported for upload handler `{handler}`.",
-                )
+                msg = f"@rx.event(background=True) is not supported for upload handler `{handler}`."
+                raise UploadTypeError(msg)
             func = func.fn
         if isinstance(func, functools.partial):
             func = func.func
@@ -1952,10 +1945,11 @@ def upload(app: App):
                 break
 
         if not handler_upload_param:
-            raise UploadValueError(
+            msg = (
                 f"`{handler}` handler should have a parameter annotated as "
                 "list[rx.UploadFile]"
             )
+            raise UploadValueError(msg)
 
         # Make a copy of the files as they are closed after the request.
         # This behaviour changed from fastapi 0.103.0 to 0.103.1 as the
@@ -2098,32 +2092,31 @@ class EventNamespace(AsyncNamespace):
             try:
                 fields = json.loads(fields)
             except json.JSONDecodeError as ex:
-                raise exceptions.EventDeserializationError(
-                    f"Failed to deserialize event data: {fields}."
-                ) from ex
+                msg = f"Failed to deserialize event data: {fields}."
+                raise exceptions.EventDeserializationError(msg) from ex
 
         if not isinstance(fields, dict):
-            raise exceptions.EventDeserializationError(
-                f"Event data must be a dictionary, but received {fields} of type {type(fields)}."
-            )
+            msg = f"Event data must be a dictionary, but received {fields} of type {type(fields)}."
+            raise exceptions.EventDeserializationError(msg)
 
         try:
             # Get the event.
             event = Event(**{k: v for k, v in fields.items() if k in _EVENT_FIELDS})
         except (TypeError, ValueError) as ex:
-            raise exceptions.EventDeserializationError(
-                f"Failed to deserialize event data: {fields}."
-            ) from ex
+            msg = f"Failed to deserialize event data: {fields}."
+            raise exceptions.EventDeserializationError(msg) from ex
 
         self.token_to_sid[event.token] = sid
         self.sid_to_token[sid] = event.token
 
         # Get the event environment.
         if self.app.sio is None:
-            raise RuntimeError("Socket.IO is not initialized.")
+            msg = "Socket.IO is not initialized."
+            raise RuntimeError(msg)
         environ = self.app.sio.get_environ(sid, self.namespace)
         if environ is None:
-            raise RuntimeError("Socket.IO environ is not initialized.")
+            msg = "Socket.IO environ is not initialized."
+            raise RuntimeError(msg)
 
         # Get the client headers.
         headers = {

+ 2 - 3
reflex/app_mixins/lifespan.py

@@ -67,9 +67,8 @@ class LifespanMixin(AppMixin):
             InvalidLifespanTaskTypeError: If the task is a generator function.
         """
         if inspect.isgeneratorfunction(task) or inspect.isasyncgenfunction(task):
-            raise InvalidLifespanTaskTypeError(
-                f"Task {task.__name__} of type generator must be decorated with contextlib.asynccontextmanager."
-            )
+            msg = f"Task {task.__name__} of type generator must be decorated with contextlib.asynccontextmanager."
+            raise InvalidLifespanTaskTypeError(msg)
 
         if task_kwargs:
             original_task = task

+ 1 - 0
reflex/app_mixins/middleware.py

@@ -56,6 +56,7 @@ class MiddlewareMixin(AppMixin):
                 out = await out
             if out is not None:
                 return out
+        return None
 
     async def _postprocess(
         self, state: BaseState, event: Event, update: StateUpdate

+ 0 - 1
reflex/app_mixins/mixin.py

@@ -12,4 +12,3 @@ class AppMixin:
 
         Any App mixin can override this method to perform any initialization.
         """
-        ...

+ 6 - 3
reflex/assets.py

@@ -58,9 +58,11 @@ def asset(
         cwd = Path.cwd()
         src_file_local = cwd / assets / path
         if subfolder is not None:
-            raise ValueError("Subfolder is not supported for local assets.")
+            msg = "Subfolder is not supported for local assets."
+            raise ValueError(msg)
         if not backend_only and not src_file_local.exists():
-            raise FileNotFoundError(f"File not found: {src_file_local}")
+            msg = f"File not found: {src_file_local}"
+            raise FileNotFoundError(msg)
         return f"/{path}"
 
     # Shared asset handling
@@ -73,7 +75,8 @@ def asset(
     external = constants.Dirs.EXTERNAL_APP_ASSETS
     src_file_shared = Path(calling_file).parent / path
     if not src_file_shared.exists():
-        raise FileNotFoundError(f"File not found: {src_file_shared}")
+        msg = f"File not found: {src_file_shared}"
+        raise FileNotFoundError(msg)
 
     caller_module_path = module.__name__.replace(".", "/")
     subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path

+ 3 - 2
reflex/base.py

@@ -30,10 +30,11 @@ def validate_field_name(bases: list[type[BaseModel]], field_name: str) -> None:
             if not reload and getattr(base, field_name, None):
                 pass
     except TypeError as te:
-        raise VarNameError(
+        msg = (
             f'State var "{field_name}" in {base} has been shadowed by a substate var; '
             f'use a different field name instead".'
-        ) from te
+        )
+        raise VarNameError(msg) from te
 
 
 # monkeypatch pydantic validate_field_name method to skip validating

+ 20 - 23
reflex/compiler/compiler.py

@@ -201,15 +201,14 @@ def _validate_stylesheet(stylesheet_full_path: Path, assets_app_path: Path) -> N
     """
     suffix = stylesheet_full_path.suffix[1:] if stylesheet_full_path.suffix else ""
     if suffix not in constants.Reflex.STYLESHEETS_SUPPORTED:
-        raise ValueError(f"Stylesheet file {stylesheet_full_path} is not supported.")
+        msg = f"Stylesheet file {stylesheet_full_path} is not supported."
+        raise ValueError(msg)
     if not stylesheet_full_path.absolute().is_relative_to(assets_app_path.absolute()):
-        raise FileNotFoundError(
-            f"Cannot include stylesheets from outside the assets directory: {stylesheet_full_path}"
-        )
+        msg = f"Cannot include stylesheets from outside the assets directory: {stylesheet_full_path}"
+        raise FileNotFoundError(msg)
     if not stylesheet_full_path.name:
-        raise ValueError(
-            f"Stylesheet file name cannot be empty: {stylesheet_full_path}"
-        )
+        msg = f"Stylesheet file name cannot be empty: {stylesheet_full_path}"
+        raise ValueError(msg)
     if (
         len(
             stylesheet_full_path.absolute()
@@ -219,9 +218,8 @@ def _validate_stylesheet(stylesheet_full_path: Path, assets_app_path: Path) -> N
         == 1
         and stylesheet_full_path.stem == PageNames.STYLESHEET_ROOT
     ):
-        raise ValueError(
-            f"Stylesheet file name cannot be '{PageNames.STYLESHEET_ROOT}': {stylesheet_full_path}"
-        )
+        msg = f"Stylesheet file name cannot be '{PageNames.STYLESHEET_ROOT}': {stylesheet_full_path}"
+        raise ValueError(msg)
 
 
 RADIX_THEMES_STYLESHEET = "@radix-ui/themes/styles.css"
@@ -258,9 +256,8 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
             stylesheet_full_path = assets_app_path / stylesheet.strip("/")
 
             if not stylesheet_full_path.exists():
-                raise FileNotFoundError(
-                    f"The stylesheet file {stylesheet_full_path} does not exist."
-                )
+                msg = f"The stylesheet file {stylesheet_full_path} does not exist."
+                raise FileNotFoundError(msg)
 
             if stylesheet_full_path.is_dir():
                 all_files = (
@@ -687,9 +684,8 @@ def into_component(component: Component | ComponentCallable) -> Component:
     if (converted := _into_component_once(component)) is not None:
         return converted
     if not callable(component):
-        raise TypeError(
-            f"Expected a Component or callable, got {component!r} of type {type(component)}"
-        )
+        msg = f"Expected a Component or callable, got {component!r} of type {type(component)}"
+        raise TypeError(msg)
 
     try:
         component_called = component()
@@ -716,9 +712,10 @@ def into_component(component: Component | ComponentCallable) -> Component:
                     "Cannot pass a Var to a built-in function. Consider using .length() for accessing the length of an iterable Var."
                 ).with_traceback(e.__traceback__) from None
             if message.endswith(
-                "indices must be integers or slices, not NumberCastedVar"
-            ) or message.endswith(
-                "indices must be integers or slices, not BooleanCastedVar"
+                (
+                    "indices must be integers or slices, not NumberCastedVar",
+                    "indices must be integers or slices, not BooleanCastedVar",
+                )
             ):
                 raise TypeError(
                     "Cannot index into a primitive sequence with a Var. Consider calling rx.Var.create() on the sequence."
@@ -732,9 +729,8 @@ def into_component(component: Component | ComponentCallable) -> Component:
     if (converted := _into_component_once(component_called)) is not None:
         return converted
 
-    raise TypeError(
-        f"Expected a Component, got {component_called!r} of type {type(component_called)}"
-    )
+    msg = f"Expected a Component, got {component_called!r} of type {type(component_called)}"
+    raise TypeError(msg)
 
 
 def compile_unevaluated_page(
@@ -889,5 +885,6 @@ class ExecutorSafeFunctions:
             ValueError: If the style is not set.
         """
         if style is None:
-            raise ValueError("STYLE should be set")
+            msg = "STYLE should be set"
+            raise ValueError(msg)
         return compile_theme(style)

+ 8 - 6
reflex/compiler/utils.py

@@ -60,7 +60,8 @@ def compile_import_statement(fields: list[ImportVar]) -> tuple[str, list[str]]:
     # Check for default imports.
     defaults = {field for field in fields_set if field.is_default}
     if len(defaults) >= 2:
-        raise ValueError("Only one default import is allowed.")
+        msg = "Only one default import is allowed."
+        raise ValueError(msg)
 
     # Get the default import, and the specific imports.
     default = next(iter({field.name for field in defaults}), "")
@@ -91,9 +92,8 @@ def validate_imports(import_dict: ParsedImportDict):
                 ):
                     used_tags[import_name] = lib if lib[0] == "$" else already_imported
                     continue
-                raise ValueError(
-                    f"Can not compile, the tag {import_name} is used multiple time from {lib} and {used_tags[import_name]}"
-                )
+                msg = f"Can not compile, the tag {import_name} is used multiple time from {lib} and {used_tags[import_name]}"
+                raise ValueError(msg)
             if import_name is not None:
                 used_tags[import_name] = lib
 
@@ -130,9 +130,11 @@ def compile_imports(import_dict: ParsedImportDict) -> list[dict]:
         for path, (default, rest) in compiled.items():
             if not lib:
                 if default:
-                    raise ValueError("No default field allowed for empty library.")
+                    msg = "No default field allowed for empty library."
+                    raise ValueError(msg)
                 if rest is None or len(rest) == 0:
-                    raise ValueError("No fields to import.")
+                    msg = "No fields to import."
+                    raise ValueError(msg)
                 import_dicts.extend(get_import_dict(module) for module in sorted(rest))
                 continue
 

+ 5 - 7
reflex/components/base/bare.py

@@ -43,9 +43,8 @@ def validate_str(value: str):
                 f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
             )
         elif perf_mode == PerformanceMode.RAISE:
-            raise ValueError(
-                f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
-            )
+            msg = f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
+            raise ValueError(msg)
 
 
 def _components_from_var(var: Var) -> Sequence[BaseComponent]:
@@ -72,10 +71,9 @@ class Bare(Component):
             if isinstance(contents, LiteralStringVar):
                 validate_str(contents._var_value)
             return cls._unsafe_create(children=[], contents=contents)
-        else:
-            if isinstance(contents, str):
-                validate_str(contents)
-            contents = Var.create(contents if contents is not None else "")
+        if isinstance(contents, str):
+            validate_str(contents)
+        contents = Var.create(contents if contents is not None else "")
 
         return cls._unsafe_create(children=[], contents=contents)
 

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

@@ -20,7 +20,8 @@ class Title(elements.Title):
         """
         # Make sure the title is a single string.
         if len(self.children) != 1 or not isinstance(self.children[0], Bare):
-            raise ValueError("Title must be a single string.")
+            msg = "Title must be a single string."
+            raise ValueError(msg)
         return super().render()
 
 

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

@@ -68,7 +68,8 @@ class Script(Component):
             ValueError: when neither children nor `src` are specified.
         """
         if not children and not props.get("src"):
-            raise ValueError("Must provide inline script or `src` prop.")
+            msg = "Must provide inline script or `src` prop."
+            raise ValueError(msg)
         return super().create(*children, **props)
 
 

+ 34 - 37
reflex/components/component.py

@@ -157,7 +157,8 @@ class ComponentField(Generic[FIELD_TYPE]):
             return self.default
         if self.default_factory is not None:
             return self.default_factory()
-        raise ValueError("No default value or factory provided.")
+        msg = "No default value or factory provided."
+        raise ValueError(msg)
 
     def __repr__(self) -> str:
         """Represent the field in a readable format.
@@ -194,7 +195,8 @@ def field(
         ValueError: If both default and default_factory are specified.
     """
     if default is not MISSING and default_factory is not None:
-        raise ValueError("cannot specify both default and default_factory")
+        msg = "cannot specify both default and default_factory"
+        raise ValueError(msg)
     return ComponentField(  # pyright: ignore [reportReturnType]
         default=default,
         default_factory=default_factory,
@@ -770,11 +772,12 @@ class Component(BaseComponent, ABC):
                 and key not in component_specific_triggers
                 and key not in props
             ):
-                raise ValueError(
+                msg = (
                     f"The {(comp_name := type(self).__name__)} does not take in an `{key}` event trigger. If {comp_name}"
                     f" is a third party component make sure to add `{key}` to the component's event triggers. "
                     f"visit https://reflex.dev/docs/wrapping-react/guide/#event-triggers for more info."
                 )
+                raise ValueError(msg)
             if key in component_specific_triggers:
                 # Event triggers are bound to event chains.
                 is_var = False
@@ -845,7 +848,8 @@ class Component(BaseComponent, ABC):
         style = kwargs.get("style", {})
         if isinstance(style, Sequence):
             if any(not isinstance(s, Mapping) for s in style):
-                raise TypeError("Style must be a dictionary or a list of dictionaries.")
+                msg = "Style must be a dictionary or a list of dictionaries."
+                raise TypeError(msg)
             # Merge styles, the later ones overriding keys in the earlier ones.
             style = {
                 k: v
@@ -880,14 +884,12 @@ class Component(BaseComponent, ABC):
                     if not isinstance(c, StringVar) and not issubclass(
                         c._var_type, str
                     ):
-                        raise TypeError(
-                            f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c._js_expr} of type {c._var_type}."
-                        )
+                        msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c._js_expr} of type {c._var_type}."
+                        raise TypeError(msg)
                     has_var = True
                 else:
-                    raise TypeError(
-                        f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c} of type {type(c)}."
-                    )
+                    msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c} of type {type(c)}."
+                    raise TypeError(msg)
             if has_var:
                 kwargs["class_name"] = LiteralArrayVar.create(
                     class_name, _var_type=list[str]
@@ -899,9 +901,8 @@ class Component(BaseComponent, ABC):
             and not isinstance(class_name, StringVar)
             and not issubclass(class_name._var_type, str)
         ):
-            raise TypeError(
-                f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {class_name._js_expr} of type {class_name._var_type}."
-            )
+            msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {class_name._js_expr} of type {class_name._var_type}."
+            raise TypeError(msg)
         # Construct the component.
         for key, value in kwargs.items():
             setattr(self, key, value)
@@ -1228,9 +1229,8 @@ class Component(BaseComponent, ABC):
         """
         # 1. Default style from `_add_style`/`add_style`.
         if type(self)._add_style != Component._add_style:
-            raise UserWarning(
-                "Do not override _add_style directly. Use add_style instead."
-            )
+            msg = "Do not override _add_style directly. Use add_style instead."
+            raise UserWarning(msg)
         new_style = self._add_style()
         style_vars = [new_style._var_data]
 
@@ -1348,9 +1348,8 @@ class Component(BaseComponent, ABC):
                 validate_child(child.default)
 
             if self._invalid_children and child_name in self._invalid_children:
-                raise ValueError(
-                    f"The component `{comp_name}` cannot have `{child_name}` as a child component"
-                )
+                msg = f"The component `{comp_name}` cannot have `{child_name}` as a child component"
+                raise ValueError(msg)
 
             if self._valid_children and child_name not in [
                 *self._valid_children,
@@ -1359,9 +1358,8 @@ class Component(BaseComponent, ABC):
                 valid_child_list = ", ".join(
                     [f"`{v_child}`" for v_child in self._valid_children]
                 )
-                raise ValueError(
-                    f"The component `{comp_name}` only allows the components: {valid_child_list} as children. Got `{child_name}` instead."
-                )
+                msg = f"The component `{comp_name}` only allows the components: {valid_child_list} as children. Got `{child_name}` instead."
+                raise ValueError(msg)
 
             if child._valid_parents and all(
                 clz_name not in [*child._valid_parents, *allowed_components]
@@ -1370,9 +1368,8 @@ class Component(BaseComponent, ABC):
                 valid_parent_list = ", ".join(
                     [f"`{v_parent}`" for v_parent in child._valid_parents]
                 )
-                raise ValueError(
-                    f"The component `{child_name}` can only be a child of the components: {valid_parent_list}. Got `{comp_name}` instead."
-                )
+                msg = f"The component `{child_name}` can only be a child of the components: {valid_parent_list}. Got `{comp_name}` instead."
+                raise ValueError(msg)
 
         for child in children:
             validate_child(child)
@@ -1503,13 +1500,9 @@ class Component(BaseComponent, ABC):
         """
         if self.event_triggers and self._event_trigger_values_use_state():
             return True
-        else:
-            for child in self.children:
-                if (
-                    isinstance(child, Component)
-                    and child._has_stateful_event_triggers()
-                ):
-                    return True
+        for child in self.children:
+            if isinstance(child, Component) and child._has_stateful_event_triggers():
+                return True
         return False
 
     @classmethod
@@ -1768,6 +1761,7 @@ class Component(BaseComponent, ABC):
                         {on_unmount or ""}
                     }}
                 }}, []);"""
+        return None
 
     def _get_ref_hook(self) -> Var | None:
         """Generate the ref hook for the component.
@@ -1781,6 +1775,7 @@ class Component(BaseComponent, ABC):
                 f"const {ref} = useRef(null); {Var(_js_expr=ref)._as_ref()!s} = {ref};",
                 _var_data=VarData(position=Hooks.HookPosition.INTERNAL),
             )
+        return None
 
     def _get_vars_hooks(self) -> dict[str, VarData | None]:
         """Get the hooks required by vars referenced in this component.
@@ -2223,7 +2218,7 @@ def _register_custom_component(
                 _var_type=unwrap_var_annotation(annotation),
             ).guess_type()
             if not types.safe_issubclass(annotation, EventHandler)
-            else EventSpec(handler=EventHandler(fn=lambda: []))
+            else EventSpec(handler=EventHandler(fn=no_args_event_spec))
         )
         for prop, annotation in typing.get_type_hints(component_fn).items()
         if prop != "return"
@@ -2234,7 +2229,8 @@ def _register_custom_component(
         **dummy_props,
     )
     if dummy_component.tag is None:
-        raise TypeError(f"Could not determine the tag name for {component_fn!r}")
+        msg = f"Could not determine the tag name for {component_fn!r}"
+        raise TypeError(msg)
     CUSTOM_COMPONENTS[dummy_component.tag] = dummy_component
 
 
@@ -2313,7 +2309,8 @@ class NoSSRComponent(Component):
         # extract the correct import name from library name
         base_import_name = self._get_import_name()
         if base_import_name is None:
-            raise ValueError("Undefined library for NoSSRComponent")
+            msg = "Undefined library for NoSSRComponent"
+            raise ValueError(msg)
         import_name = format.format_library_name(base_import_name)
 
         library_import = f"const {self.alias if self.alias else self.tag} = dynamic(() => import('{import_name}')"
@@ -2321,7 +2318,7 @@ class NoSSRComponent(Component):
             # https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#with-named-exports
             f".then((mod) => mod.{self.tag})" if not self.is_default else ""
         )
-        return "".join((library_import, mod_import, opts_fragment))
+        return library_import + mod_import + opts_fragment
 
 
 class StatefulComponent(BaseComponent):
@@ -2541,7 +2538,7 @@ class StatefulComponent(BaseComponent):
         var_name = var_name.strip()
 
         # Break up array and object destructuring if used.
-        if var_name.startswith("[") or var_name.startswith("{"):
+        if var_name.startswith(("[", "{")):
             return [
                 v.strip().replace("...", "") for v in var_name.strip("[]{}").split(",")
             ]

+ 9 - 11
reflex/components/core/breakpoints.py

@@ -75,19 +75,17 @@ class Breakpoints(dict[K, V]):
 
         if custom is not None:
             if any(threshold is not None for threshold in thresholds):
-                raise ValueError("Named props cannot be used with custom thresholds")
+                msg = "Named props cannot be used with custom thresholds"
+                raise ValueError(msg)
 
             return Breakpoints(custom)
-        else:
-            return Breakpoints(
-                {
-                    k: v
-                    for k, v in zip(
-                        ["initial", *breakpoint_names], thresholds, strict=True
-                    )
-                    if v is not None
-                }
-            )
+        return Breakpoints(
+            {
+                k: v
+                for k, v in zip(["initial", *breakpoint_names], thresholds, strict=True)
+                if v is not None
+            }
+        )
 
 
 breakpoints = Breakpoints.create

+ 10 - 7
reflex/components/core/colors.py

@@ -32,19 +32,22 @@ def color(
     """
     if isinstance(color, str):
         if color not in COLORS and REFLEX_VAR_OPENING_TAG not in color:
-            raise ValueError(f"Color must be one of {COLORS}, received {color}")
+            msg = f"Color must be one of {COLORS}, received {color}"
+            raise ValueError(msg)
     elif not isinstance(color, Var):
-        raise ValueError("Color must be a string or a Var")
+        msg = "Color must be a string or a Var"
+        raise ValueError(msg)
 
     if isinstance(shade, int):
         if shade < MIN_SHADE_VALUE or shade > MAX_SHADE_VALUE:
-            raise ValueError(
-                f"Shade must be between {MIN_SHADE_VALUE} and {MAX_SHADE_VALUE}"
-            )
+            msg = f"Shade must be between {MIN_SHADE_VALUE} and {MAX_SHADE_VALUE}"
+            raise ValueError(msg)
     elif not isinstance(shade, Var):
-        raise ValueError("Shade must be an integer or a Var")
+        msg = "Shade must be an integer or a Var"
+        raise ValueError(msg)
 
     if not isinstance(alpha, (bool, Var)):
-        raise ValueError("Alpha must be a boolean or a Var")
+        msg = "Alpha must be a boolean or a Var"
+        raise ValueError(msg)
 
     return Color(color, shade, alpha)

+ 4 - 2
reflex/components/core/cond.py

@@ -132,7 +132,8 @@ def cond(condition: Any, c1: Any, c2: Any = types.Unset(), /) -> Component | Var
     # Convert the condition to a Var.
     cond_var = LiteralVar.create(condition)
     if cond_var is None:
-        raise ValueError("The condition must be set.")
+        msg = "The condition must be set."
+        raise ValueError(msg)
 
     # If the first component is a component, create a Cond component.
     if isinstance(c1, BaseComponent):
@@ -145,7 +146,8 @@ def cond(condition: Any, c1: Any, c2: Any = types.Unset(), /) -> Component | Var
     if isinstance(c2, BaseComponent):
         return Cond.create(cond_var.bool(), Fragment.create(c1), c2)
     if isinstance(c2, types.Unset):
-        raise ValueError("For conditional vars, the second argument must be set.")
+        msg = "For conditional vars, the second argument must be set."
+        raise ValueError(msg)
 
     # convert the truth and false cond parts into vars so the _var_data can be obtained.
     c1_var = Var.create(c1)

+ 5 - 3
reflex/components/core/debounce.py

@@ -70,14 +70,16 @@ class DebounceInput(Component):
             ValueError: if the child element does not have an on_change handler.
         """
         if len(children) != 1:
-            raise RuntimeError(
+            msg = (
                 "Provide a single child for DebounceInput, such as rx.input() or "
-                "rx.text_area()",
+                "rx.text_area()"
             )
+            raise RuntimeError(msg)
 
         child = children[0]
         if "on_change" not in child.event_triggers:
-            raise ValueError("DebounceInput child requires an on_change handler")
+            msg = "DebounceInput child requires an on_change handler"
+            raise ValueError(msg)
 
         # Carry known props and event_triggers from the child.
         props_from_child = {

+ 8 - 6
reflex/components/core/foreach.py

@@ -69,19 +69,19 @@ class Foreach(Component):
         )
 
         if iterable._var_type == Any:
-            raise ForeachVarError(
+            msg = (
                 f"Could not foreach over var `{iterable!s}` of type Any. "
                 "(If you are trying to foreach over a state var, add a type annotation to the var). "
                 "See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
             )
+            raise ForeachVarError(msg)
 
         if (
             hasattr(render_fn, "__qualname__")
             and render_fn.__qualname__ == ComponentState.create.__qualname__
         ):
-            raise TypeError(
-                "Using a ComponentState as `render_fn` inside `rx.foreach` is not supported yet."
-            )
+            msg = "Using a ComponentState as `render_fn` inside `rx.foreach` is not supported yet."
+            raise TypeError(msg)
 
         if isinstance(iterable, ObjectVar):
             iterable = iterable.entries()
@@ -90,10 +90,11 @@ class Foreach(Component):
             iterable = iterable.split()
 
         if not isinstance(iterable, ArrayVar):
-            raise ForeachVarError(
+            msg = (
                 f"Could not foreach over var `{iterable!s}` of type {iterable._var_type}. "
                 "See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
             )
+            raise ForeachVarError(msg)
 
         if types.is_optional(iterable._var_type):
             iterable = cond(iterable, iterable, [])
@@ -122,11 +123,12 @@ class Foreach(Component):
 
         # Validate the render function signature.
         if len(params) == 0 or len(params) > 2:
-            raise ForeachRenderError(
+            msg = (
                 "Expected 1 or 2 parameters in foreach render function, got "
                 f"{[p.name for p in params]}. See "
                 "https://reflex.dev/docs/library/dynamic-rendering/foreach/"
             )
+            raise ForeachRenderError(msg)
 
         if len(params) >= 1:
             # Determine the arg var name based on the params accepted by render_fn.

+ 3 - 3
reflex/components/core/html.py

@@ -30,9 +30,9 @@ class Html(Div):
         """
         # If children are not provided, throw an error.
         if len(children) != 1:
-            raise ValueError("Must provide children to the html component.")
-        else:
-            props["dangerouslySetInnerHTML"] = {"__html": children[0]}
+            msg = "Must provide children to the html component."
+            raise ValueError(msg)
+        props["dangerouslySetInnerHTML"] = {"__html": children[0]}
 
         # Apply the default classname
         given_class_name = props.pop("class_name", [])

+ 19 - 17
reflex/components/core/match.py

@@ -47,9 +47,8 @@ class Match(MemoizationLeaf):
         cls._validate_return_types(match_cases)
 
         if default is None and isinstance(match_cases[0][-1], Var):
-            raise ValueError(
-                "For cases with return types as Vars, a default case must be provided"
-            )
+            msg = "For cases with return types as Vars, a default case must be provided"
+            raise ValueError(msg)
 
         return cls._create_match_cond_var_or_component(
             match_cond_var, match_cases, default
@@ -71,7 +70,8 @@ class Match(MemoizationLeaf):
         match_cond_var = LiteralVar.create(cond)
 
         if match_cond_var is None:
-            raise ValueError("The condition must be set")
+            msg = "The condition must be set"
+            raise ValueError(msg)
         return match_cond_var
 
     @classmethod
@@ -90,10 +90,12 @@ class Match(MemoizationLeaf):
         default = None
 
         if len([case for case in cases if not isinstance(case, tuple)]) > 1:
-            raise ValueError("rx.match can only have one default case.")
+            msg = "rx.match can only have one default case."
+            raise ValueError(msg)
 
         if not cases:
-            raise ValueError("rx.match should have at least one case.")
+            msg = "rx.match should have at least one case."
+            raise ValueError(msg)
 
         # Get the default case which should be the last non-tuple arg
         if not isinstance(cases[-1], tuple):
@@ -119,8 +121,7 @@ class Match(MemoizationLeaf):
             The case element Var.
         """
         _var_data = case_element._var_data if isinstance(case_element, Style) else None
-        case_element = LiteralVar.create(case_element, _var_data=_var_data)
-        return case_element
+        return LiteralVar.create(case_element, _var_data=_var_data)
 
     @classmethod
     def _process_match_cases(cls, cases: list) -> list[list[Var]]:
@@ -138,14 +139,12 @@ class Match(MemoizationLeaf):
         match_cases = []
         for case in cases:
             if not isinstance(case, tuple):
-                raise ValueError(
-                    "rx.match should have tuples of cases and a default case as the last argument."
-                )
+                msg = "rx.match should have tuples of cases and a default case as the last argument."
+                raise ValueError(msg)
             # There should be at least two elements in a case tuple(a condition and return value)
             if len(case) < 2:
-                raise ValueError(
-                    "A case tuple should have at least a match case element and a return value."
-                )
+                msg = "A case tuple should have at least a match case element and a return value."
+                raise ValueError(msg)
 
             case_list = []
             for element in case:
@@ -156,7 +155,8 @@ class Match(MemoizationLeaf):
                     else element
                 )
                 if not isinstance(el, (Var, BaseComponent)):
-                    raise ValueError("Case element must be a var or component")
+                    msg = "Case element must be a var or component"
+                    raise ValueError(msg)
                 case_list.append(el)
 
             match_cases.append(case_list)
@@ -183,11 +183,12 @@ class Match(MemoizationLeaf):
 
         for index, case in enumerate(match_cases):
             if not isinstance(case[-1], return_type):
-                raise MatchTypeError(
+                msg = (
                     f"Match cases should have the same return types. Case {index} with return "
                     f"value `{case[-1]._js_expr if isinstance(case[-1], Var) else textwrap.shorten(str(case[-1]), width=250)}`"
                     f" of type {type(case[-1])!r} is not {return_type}"
                 )
+                raise MatchTypeError(msg)
 
     @classmethod
     def _create_match_cond_var_or_component(
@@ -226,7 +227,8 @@ class Match(MemoizationLeaf):
         if any(
             case for case in match_cases if not isinstance(case[-1], Var)
         ) or not isinstance(default, Var):
-            raise ValueError("Return types of match cases should be Vars.")
+            msg = "Return types of match cases should be Vars."
+            raise ValueError(msg)
 
         return Var(
             _js_expr=format.format_match(

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

@@ -482,8 +482,7 @@ class CodeBlock(Component, MarkdownComponentMap):
 
         if copy_button:
             return Box.create(code_block, copy_button, position="relative")
-        else:
-            return code_block
+        return code_block
 
     def add_style(self):
         """Add style to the component."""

+ 7 - 10
reflex/components/datadisplay/dataeditor.py

@@ -383,9 +383,8 @@ class DataEditor(NoSSRComponent):
         # If rows is not provided, determine from data.
         if rows is None:
             if isinstance(data, Var) and not isinstance(data, ArrayVar):
-                raise ValueError(
-                    "DataEditor data must be an ArrayVar if rows is not provided."
-                )
+                msg = "DataEditor data must be an ArrayVar if rows is not provided."
+                raise ValueError(msg)
 
             props["rows"] = data.length() if isinstance(data, ArrayVar) else len(data)
 
@@ -393,13 +392,11 @@ class DataEditor(NoSSRComponent):
             if types.is_dataframe(type(data)) or (
                 isinstance(data, Var) and types.is_dataframe(data._var_type)
             ):
-                raise ValueError(
-                    "Cannot pass in both a pandas dataframe and columns to the data_editor component."
-                )
-            else:
-                props["columns"] = [
-                    format.format_data_editor_column(col) for col in columns
-                ]
+                msg = "Cannot pass in both a pandas dataframe and columns to the data_editor component."
+                raise ValueError(msg)
+            props["columns"] = [
+                format.format_data_editor_column(col) for col in columns
+            ]
 
         if "theme" in props:
             theme = props.get("theme")

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

@@ -2,11 +2,10 @@
 
 import reflex as rx
 
+SVG_COLOR = rx.color_mode_cond("#110F1F", "white")
 
-def svg_logo(
-    color: str | rx.Var[str] = rx.color_mode_cond("#110F1F", "white"),
-    **props,
-):
+
+def svg_logo(color: str | rx.Var[str] = SVG_COLOR, **props):
     """A Reflex logo SVG.
 
     Args:

+ 8 - 11
reflex/components/datadisplay/shiki_code_block.py

@@ -636,9 +636,8 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
         """
         imports = defaultdict(list)
         if not isinstance(self.transformers, LiteralVar):
-            raise ValueError(
-                f"transformers should be a LiteralVar type. Got {type(self.transformers)} instead."
-            )
+            msg = f"transformers should be a LiteralVar type. Got {type(self.transformers)} instead."
+            raise ValueError(msg)
         for transformer in self.transformers._var_value:
             if isinstance(transformer, ShikiBaseTransformers):
                 imports[transformer.library].extend(
@@ -663,9 +662,8 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
             ValueError: If a supplied function name is not valid str.
         """
         if any(not isinstance(fn_name, str) for fn_name in fns):
-            raise ValueError(
-                f"the function names should be str names of functions in the specified transformer: {library!r}"
-            )
+            msg = f"the function names should be str names of functions in the specified transformer: {library!r}"
+            raise ValueError(msg)
         return ShikiBaseTransformers(
             library=library,
             fns=[FunctionStringVar.create(fn) for fn in fns],  # pyright: ignore [reportCallIssue]
@@ -811,8 +809,7 @@ class ShikiHighLevelCodeBlock(ShikiCodeBlock):
             return ShikiCodeBlock.create(
                 children[0], copy_button, position="relative", **props
             )
-        else:
-            return ShikiCodeBlock.create(children[0], **props)
+        return ShikiCodeBlock.create(children[0], **props)
 
     @staticmethod
     def _map_themes(theme: str) -> str:
@@ -829,9 +826,8 @@ class ShikiHighLevelCodeBlock(ShikiCodeBlock):
     @staticmethod
     def _strip_transformer_triggers(code: str | StringVar) -> StringVar | str:
         if not isinstance(code, (StringVar, str)):
-            raise VarTypeError(
-                f"code should be string literal or a StringVar type. Got {type(code)} instead."
-            )
+            msg = f"code should be string literal or a StringVar type. Got {type(code)} instead."
+            raise VarTypeError(msg)
         regex_pattern = r"[\/#]+ *\[!code.*?\]"
 
         if isinstance(code, Var):
@@ -840,6 +836,7 @@ class ShikiHighLevelCodeBlock(ShikiCodeBlock):
             )
         if isinstance(code, str):
             return re.sub(regex_pattern, "", code)
+        return None
 
 
 class TransformerNamespace(ComponentNamespace):

+ 2 - 3
reflex/components/dynamic.py

@@ -50,9 +50,8 @@ def bundle_library(component: Union["Component", str]):
         bundled_libraries.add(component)
         return
     if component.library is None:
-        raise DynamicComponentMissingLibraryError(
-            "Component must have a library to bundle."
-        )
+        msg = "Component must have a library to bundle."
+        raise DynamicComponentMissingLibraryError(msg)
     bundled_libraries.add(format_library_name(component.library))
 
 

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

@@ -746,9 +746,8 @@ class Textarea(BaseHTML):
         if enter_key_submit is not None:
             enter_key_submit = Var.create(enter_key_submit)
             if "on_key_down" in props:
-                raise ValueError(
-                    "Cannot combine `enter_key_submit` with `on_key_down`.",
-                )
+                msg = "Cannot combine `enter_key_submit` with `on_key_down`."
+                raise ValueError(msg)
             custom_attrs["on_key_down"] = Var(
                 _js_expr=f"(e) => enterKeySubmitOnKeyDown(e, {enter_key_submit!s})",
                 _var_data=VarData.merge(enter_key_submit._get_all_var_data()),

+ 0 - 1
reflex/components/el/elements/metadata.py

@@ -13,7 +13,6 @@ class Base(BaseHTML):
 
     tag = "base"
 
-    tag = "base"
     href: Var[str]
     target: Var[str]
 

+ 10 - 13
reflex/components/gridjs/datatable.py

@@ -67,36 +67,32 @@ class DataTable(Gridjs):
         # The annotation should be provided if data is a computed var. We need this to know how to
         # render pandas dataframes.
         if is_computed_var(data) and data._var_type == Any:
-            raise ValueError(
-                "Annotation of the computed var assigned to the data field should be provided."
-            )
+            msg = "Annotation of the computed var assigned to the data field should be provided."
+            raise ValueError(msg)
 
         if (
             columns is not None
             and is_computed_var(columns)
             and columns._var_type == Any
         ):
-            raise ValueError(
-                "Annotation of the computed var assigned to the column field should be provided."
-            )
+            msg = "Annotation of the computed var assigned to the column field should be provided."
+            raise ValueError(msg)
 
         # If data is a pandas dataframe and columns are provided throw an error.
         if (
             types.is_dataframe(type(data))
             or (isinstance(data, Var) and types.is_dataframe(data._var_type))
         ) and columns is not None:
-            raise ValueError(
-                "Cannot pass in both a pandas dataframe and columns to the data_table component."
-            )
+            msg = "Cannot pass in both a pandas dataframe and columns to the data_table component."
+            raise ValueError(msg)
 
         # If data is a list and columns are not provided, throw an error
         if (
             (isinstance(data, Var) and types.typehint_issubclass(data._var_type, list))
             or isinstance(data, list)
         ) and columns is None:
-            raise ValueError(
-                "column field should be specified when the data field is a list type"
-            )
+            msg = "column field should be specified when the data field is a list type"
+            raise ValueError(msg)
 
         # Create the component.
         return super().create(
@@ -126,7 +122,8 @@ class DataTable(Gridjs):
             # If given a pandas df break up the data and columns
             data = serialize(self.data)
             if not isinstance(data, dict):
-                raise ValueError("Serialized dataframe should be a dict.")
+                msg = "Serialized dataframe should be a dict."
+                raise ValueError(msg)
             self.columns = LiteralVar.create(data["columns"])
             self.data = LiteralVar.create(data["data"])
 

+ 10 - 9
reflex/components/lucide/icon.py

@@ -42,27 +42,28 @@ class Icon(LucideIconComponent):
             if len(children) == 1:
                 child = Var.create(children[0]).guess_type()
                 if not isinstance(child, StringVar):
-                    raise AttributeError(
-                        f"Icon name must be a string, got {children[0]._var_type if isinstance(children[0], Var) else children[0]}"
-                    )
+                    msg = f"Icon name must be a string, got {children[0]._var_type if isinstance(children[0], Var) else children[0]}"
+                    raise AttributeError(msg)
                 props["tag"] = children[0]
             else:
-                raise AttributeError(
-                    f"Passing multiple children to Icon component is not allowed: remove positional arguments {children[1:]} to fix"
-                )
+                msg = f"Passing multiple children to Icon component is not allowed: remove positional arguments {children[1:]} to fix"
+                raise AttributeError(msg)
         if "tag" not in props:
-            raise AttributeError("Missing 'tag' keyword-argument for Icon")
+            msg = "Missing 'tag' keyword-argument for Icon"
+            raise AttributeError(msg)
 
         tag_var: Var | LiteralVar = Var.create(props.pop("tag"))
         if isinstance(tag_var, LiteralVar):
             if isinstance(tag_var, LiteralStringVar):
                 tag = format.to_snake_case(tag_var._var_value.lower())
             else:
-                raise TypeError(f"Icon name must be a string, got {type(tag_var)}")
+                msg = f"Icon name must be a string, got {type(tag_var)}"
+                raise TypeError(msg)
         elif isinstance(tag_var, Var):
             tag_stringified = tag_var.guess_type()
             if not isinstance(tag_stringified, StringVar):
-                raise TypeError(f"Icon name must be a string, got {tag_var._var_type}")
+                msg = f"Icon name must be a string, got {tag_var._var_type}"
+                raise TypeError(msg)
             return DynamicIcon.create(name=tag_stringified.replace("_", "-"), **props)
 
         if tag not in LUCIDE_ICON_LIST:

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

@@ -170,9 +170,8 @@ class Markdown(Component):
             The markdown component.
         """
         if len(children) != 1 or not isinstance(children[0], (str, Var)):
-            raise ValueError(
-                "Markdown component must have exactly one child containing the markdown source."
-            )
+            msg = "Markdown component must have exactly one child containing the markdown source."
+            raise ValueError(msg)
 
         # Update the base component map with the custom component map.
         component_map = {**get_base_component_map(), **props.pop("component_map", {})}
@@ -319,7 +318,8 @@ let {_LANGUAGE!s} = match ? match[1] : '';
         """
         # Check the tag is valid.
         if tag not in self.component_map:
-            raise ValueError(f"No markdown component found for tag: {tag}.")
+            msg = f"No markdown component found for tag: {tag}."
+            raise ValueError(msg)
 
         special_props = [_PROPS]
         children = [
@@ -342,10 +342,9 @@ let {_LANGUAGE!s} = match ? match[1] : '';
         if children_prop is not None:
             children = []
         # Get the component.
-        component = self.component_map[tag](*children, **props).set(
+        return self.component_map[tag](*children, **props).set(
             special_props=special_props
         )
-        return component
 
     def format_component(self, tag: str, **props) -> str:
         """Format a component for rendering in the component map.
@@ -437,7 +436,7 @@ let {_LANGUAGE!s} = match ? match[1] : '';
         """
 
     def _render(self) -> Tag:
-        tag = (
+        return (
             super()
             ._render()
             .add_props(
@@ -447,4 +446,3 @@ let {_LANGUAGE!s} = match ? match[1] : '';
             )
             .remove_props("componentMap", "componentMapHash")
         )
-        return tag

+ 0 - 2
reflex/components/next/base.py

@@ -5,5 +5,3 @@ from reflex.components.component import Component
 
 class NextComponent(Component):
     """A Component used as based for any NextJS component."""
-
-    ...

+ 2 - 3
reflex/components/props.py

@@ -66,9 +66,8 @@ class NoExtrasAllowedProps(Base):
         except ValidationError as e:
             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())
-            raise InvalidPropValueError(
-                f"Invalid prop(s) {invalid_fields} for {component_name!r}. Supported props are {supported_props_str}"
-            ) from None
+            msg = f"Invalid prop(s) {invalid_fields} for {component_name!r}. Supported props are {supported_props_str}"
+            raise InvalidPropValueError(msg) from None
 
     class Config:  # pyright: ignore [reportIncompatibleVariableOverride]
         """Pydantic config."""

+ 1 - 3
reflex/components/radix/primitives/base.py

@@ -21,8 +21,6 @@ class RadixPrimitiveComponentWithClassName(RadixPrimitiveComponent):
             super()
             ._render()
             .add_props(
-                **{
-                    "class_name": f"{format.to_title_case(self.tag or '')} {self.class_name or ''}",
-                }
+                class_name=f"{format.to_title_case(self.tag or '')} {self.class_name or ''}"
             )
         )

+ 4 - 8
reflex/components/radix/primitives/form.py

@@ -100,14 +100,12 @@ class FormControl(FormComponent):
             The form control component.
         """
         if len(children) > 1:
-            raise ValueError(
-                f"FormControl can only have at most one child, got {len(children)} children"
-            )
+            msg = f"FormControl can only have at most one child, got {len(children)} children"
+            raise ValueError(msg)
         for child in children:
             if not isinstance(child, (TextFieldRoot, DebounceInput)):
-                raise TypeError(
-                    "Only Radix TextFieldRoot and DebounceInput are allowed as children of FormControl"
-                )
+                msg = "Only Radix TextFieldRoot and DebounceInput are allowed as children of FormControl"
+                raise TypeError(msg)
         return super().create(*children, **props)
 
 
@@ -168,8 +166,6 @@ class FormSubmit(FormComponent):
 class Form(FormRoot):
     """The Form component."""
 
-    pass
-
 
 class FormNamespace(ComponentNamespace):
     """Form components."""

+ 4 - 2
reflex/components/radix/themes/components/alert_dialog.py

@@ -5,12 +5,14 @@ from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    RadixThemesComponent,
+    RadixThemesTriggerComponent,
+)
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent, RadixThemesTriggerComponent
-
 LiteralContentSize = Literal["1", "2", "3", "4"]
 
 

+ 1 - 2
reflex/components/radix/themes/components/aspect_ratio.py

@@ -1,9 +1,8 @@
 """Interactive components provided by @radix-ui/themes."""
 
+from reflex.components.radix.themes.base import RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent
-
 
 class AspectRatio(RadixThemesComponent):
     """Displays content with a desired ratio."""

+ 5 - 2
reflex/components/radix/themes/components/avatar.py

@@ -3,10 +3,13 @@
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralRadius,
+    RadixThemesComponent,
+)
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
-
 LiteralSize = Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]
 
 

+ 5 - 2
reflex/components/radix/themes/components/badge.py

@@ -4,10 +4,13 @@ from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralRadius,
+    RadixThemesComponent,
+)
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
-
 
 class Badge(elements.Span, RadixThemesComponent):
     """A stylized badge element."""

+ 2 - 3
reflex/components/radix/themes/components/button.py

@@ -4,15 +4,14 @@ from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
-from reflex.vars.base import Var
-
-from ..base import (
+from reflex.components.radix.themes.base import (
     LiteralAccentColor,
     LiteralRadius,
     LiteralVariant,
     RadixLoadingProp,
     RadixThemesComponent,
 )
+from reflex.vars.base import Var
 
 LiteralButtonSize = Literal["1", "2", "3", "4"]
 

+ 1 - 2
reflex/components/radix/themes/components/callout.py

@@ -7,10 +7,9 @@ from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.lucide.icon import Icon
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 CalloutVariant = Literal["soft", "surface", "outline"]
 
 

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

@@ -4,10 +4,9 @@ from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent
-
 
 class Card(elements.Div, RadixThemesComponent):
     """Container that groups related content and actions."""

+ 7 - 4
reflex/components/radix/themes/components/checkbox.py

@@ -4,12 +4,15 @@ from typing import Literal
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralSpacing,
+    RadixThemesComponent,
+)
 from reflex.components.radix.themes.layout.flex import Flex
 from reflex.components.radix.themes.typography.text import Text
 from reflex.event import EventHandler, passthrough_event_spec
-from reflex.vars.base import LiteralVar, Var
-
-from ..base import LiteralAccentColor, LiteralSpacing, RadixThemesComponent
+from reflex.vars.base import Var
 
 LiteralCheckboxSize = Literal["1", "2", "3"]
 LiteralCheckboxVariant = Literal["classic", "surface", "soft"]
@@ -111,7 +114,7 @@ class HighLevelCheckbox(RadixThemesComponent):
     on_change: EventHandler[passthrough_event_spec(bool)]
 
     @classmethod
-    def create(cls, text: Var[str] = LiteralVar.create(""), **props) -> Component:
+    def create(cls, text: Var[str] = Var.create(""), **props) -> Component:
         """Create a checkbox with a label.
 
         Args:

+ 1 - 2
reflex/components/radix/themes/components/checkbox_cards.py

@@ -4,10 +4,9 @@ from types import SimpleNamespace
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 
 class CheckboxCardsRoot(RadixThemesComponent):
     """Root element for a CheckboxCards component."""

+ 1 - 2
reflex/components/radix/themes/components/checkbox_group.py

@@ -5,10 +5,9 @@ from types import SimpleNamespace
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 
 class CheckboxGroupRoot(RadixThemesComponent):
     """Root element for a CheckboxGroup component."""

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

@@ -4,11 +4,11 @@ from typing import ClassVar, Literal
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
 from .checkbox import Checkbox
 from .radio_group import HighLevelRadioGroup
 

+ 1 - 2
reflex/components/radix/themes/components/data_list.py

@@ -4,10 +4,9 @@ from types import SimpleNamespace
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 
 class DataListRoot(RadixThemesComponent):
     """Root element for a DataList component."""

+ 4 - 2
reflex/components/radix/themes/components/dialog.py

@@ -5,12 +5,14 @@ from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    RadixThemesComponent,
+    RadixThemesTriggerComponent,
+)
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent, RadixThemesTriggerComponent
-
 
 class DialogRoot(RadixThemesComponent):
     """Root component for Dialog."""

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

@@ -4,12 +4,15 @@ from typing import ClassVar, Literal
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    RadixThemesComponent,
+    RadixThemesTriggerComponent,
+)
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent, RadixThemesTriggerComponent
-
 LiteralDirType = Literal["ltr", "rtl"]
 
 LiteralSizeType = Literal["1", "2"]

+ 4 - 2
reflex/components/radix/themes/components/hover_card.py

@@ -5,12 +5,14 @@ from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    RadixThemesComponent,
+    RadixThemesTriggerComponent,
+)
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent, RadixThemesTriggerComponent
-
 
 class HoverCardRoot(RadixThemesComponent):
     """For sighted users to preview content available behind a link."""

+ 7 - 8
reflex/components/radix/themes/components/icon_button.py

@@ -9,16 +9,15 @@ from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.match import Match
 from reflex.components.el import elements
 from reflex.components.lucide import Icon
-from reflex.style import Style
-from reflex.vars.base import Var
-
-from ..base import (
+from reflex.components.radix.themes.base import (
     LiteralAccentColor,
     LiteralRadius,
     LiteralVariant,
     RadixLoadingProp,
     RadixThemesComponent,
 )
+from reflex.style import Style
+from reflex.vars.base import Var
 
 LiteralButtonSize = Literal["1", "2", "3", "4"]
 
@@ -70,9 +69,8 @@ class IconButton(elements.Button, RadixLoadingProp, RadixThemesComponent):
                     )
                 ]
         else:
-            raise ValueError(
-                "IconButton requires a child icon. Pass a string as the first child or a rx.icon."
-            )
+            msg = "IconButton requires a child icon. Pass a string as the first child or a rx.icon."
+            raise ValueError(msg)
         if "size" in props:
             if isinstance(props["size"], str):
                 children[0].size = RADIX_TO_LUCIDE_SIZE[props["size"]]  # pyright: ignore[reportAttributeAccessIssue]
@@ -83,7 +81,8 @@ class IconButton(elements.Button, RadixLoadingProp, RadixThemesComponent):
                     12,
                 )
                 if not isinstance(size_map_var, Var):
-                    raise ValueError(f"Match did not return a Var: {size_map_var}")
+                    msg = f"Match did not return a Var: {size_map_var}"
+                    raise ValueError(msg)
                 children[0].size = size_map_var  # pyright: ignore[reportAttributeAccessIssue]
         return super().create(*children, **props)
 

+ 1 - 2
reflex/components/radix/themes/components/inset.py

@@ -4,10 +4,9 @@ from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent
-
 LiteralButtonSize = Literal["1", "2", "3", "4"]
 
 

+ 4 - 2
reflex/components/radix/themes/components/popover.py

@@ -5,12 +5,14 @@ from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    RadixThemesComponent,
+    RadixThemesTriggerComponent,
+)
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent, RadixThemesTriggerComponent
-
 
 class PopoverRoot(RadixThemesComponent):
     """Floating element for displaying rich content, triggered by a button."""

+ 1 - 2
reflex/components/radix/themes/components/progress.py

@@ -4,11 +4,10 @@ from typing import Literal
 
 from reflex.components.component import Component
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.style import Style
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 
 class Progress(RadixThemesComponent):
     """A progress bar component."""

+ 1 - 2
reflex/components/radix/themes/components/radio.py

@@ -3,10 +3,9 @@
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 
 class Radio(RadixThemesComponent):
     """A radio component."""

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

@@ -4,11 +4,10 @@ from types import SimpleNamespace
 from typing import ClassVar, Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 
 class RadioCardsRoot(RadixThemesComponent):
     """Root element for RadioCards component."""

+ 7 - 5
reflex/components/radix/themes/components/radio_group.py

@@ -8,6 +8,11 @@ from typing import Literal
 import reflex as rx
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralSpacing,
+    RadixThemesComponent,
+)
 from reflex.components.radix.themes.layout.flex import Flex
 from reflex.components.radix.themes.typography.text import Text
 from reflex.event import EventHandler, passthrough_event_spec
@@ -15,8 +20,6 @@ from reflex.utils import types
 from reflex.vars.base import LiteralVar, Var
 from reflex.vars.sequence import StringVar
 
-from ..base import LiteralAccentColor, LiteralSpacing, RadixThemesComponent
-
 LiteralFlexDirection = Literal["row", "column", "row-reverse", "column-reverse"]
 
 
@@ -145,9 +148,8 @@ class HighLevelRadioGroup(RadixThemesComponent):
             isinstance(items, Var) and not types._issubclass(items._var_type, list)
         ):
             items_type = type(items) if not isinstance(items, Var) else items._var_type
-            raise TypeError(
-                f"The radio group component takes in a list, got {items_type} instead"
-            )
+            msg = f"The radio group component takes in a list, got {items_type} instead"
+            raise TypeError(msg)
 
         default_value = LiteralVar.create(default_value)
 

+ 1 - 2
reflex/components/radix/themes/components/scroll_area.py

@@ -2,10 +2,9 @@
 
 from typing import Literal
 
+from reflex.components.radix.themes.base import RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent
-
 
 class ScrollArea(RadixThemesComponent):
     """Custom styled, cross-browser scrollable area using native functionality."""

+ 1 - 2
reflex/components/radix/themes/components/segmented_control.py

@@ -7,11 +7,10 @@ from types import SimpleNamespace
 from typing import ClassVar, Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.event import EventHandler
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 
 def on_value_change(
     value: Var[str | list[str]],

+ 5 - 2
reflex/components/radix/themes/components/select.py

@@ -6,12 +6,15 @@ from typing import ClassVar, Literal
 import reflex as rx
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralRadius,
+    RadixThemesComponent,
+)
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import no_args_event_spec, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
-
 
 class SelectRoot(RadixThemesComponent):
     """Displays a list of options for the user to pick from, triggered by a button."""

+ 1 - 2
reflex/components/radix/themes/components/separator.py

@@ -3,10 +3,9 @@
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import LiteralVar, Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 LiteralSeperatorSize = Literal["1", "2", "3", "4"]
 
 

+ 1 - 2
reflex/components/radix/themes/components/skeleton.py

@@ -1,11 +1,10 @@
 """Skeleton theme from Radix components."""
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import RadixLoadingProp, RadixThemesComponent
 from reflex.constants.compiler import MemoizationMode
 from reflex.vars.base import Var
 
-from ..base import RadixLoadingProp, RadixThemesComponent
-
 
 class Skeleton(RadixLoadingProp, RadixThemesComponent):
     """Skeleton component."""

+ 1 - 2
reflex/components/radix/themes/components/slider.py

@@ -7,12 +7,11 @@ from typing import Literal
 
 from reflex.components.component import Component
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.utils.types import typehint_issubclass
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 on_value_event_spec = (
     passthrough_event_spec(list[int | float]),
     passthrough_event_spec(list[int]),

+ 1 - 2
reflex/components/radix/themes/components/spinner.py

@@ -3,10 +3,9 @@
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import RadixLoadingProp, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import RadixLoadingProp, RadixThemesComponent
-
 LiteralSpinnerSize = Literal["1", "2", "3"]
 
 

+ 1 - 2
reflex/components/radix/themes/components/switch.py

@@ -3,11 +3,10 @@
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 LiteralSwitchSize = Literal["1", "2", "3"]
 
 

+ 1 - 2
reflex/components/radix/themes/components/table.py

@@ -5,10 +5,9 @@ from typing import ClassVar, Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import CommonPaddingProps, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import CommonPaddingProps, RadixThemesComponent
-
 
 class TableRoot(elements.Table, RadixThemesComponent):
     """A semantic table for presenting tabular data."""

+ 1 - 2
reflex/components/radix/themes/components/tabs.py

@@ -7,12 +7,11 @@ from typing import Any, ClassVar, Literal
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.colors import color
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, passthrough_event_spec
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
-
 vertical_orientation_css = "&[data-orientation='vertical']"
 
 

+ 5 - 2
reflex/components/radix/themes/components/text_area.py

@@ -6,10 +6,13 @@ from reflex.components.component import Component
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralRadius,
+    RadixThemesComponent,
+)
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
-
 LiteralTextAreaSize = Literal["1", "2", "3"]
 
 LiteralTextAreaResize = Literal["none", "vertical", "horizontal", "both"]

+ 5 - 2
reflex/components/radix/themes/components/text_field.py

@@ -8,13 +8,16 @@ from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralRadius,
+    RadixThemesComponent,
+)
 from reflex.event import EventHandler, input_event, key_event
 from reflex.utils.types import is_optional
 from reflex.vars.base import Var
 from reflex.vars.number import ternary_operation
 
-from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
-
 LiteralTextFieldSize = Literal["1", "2", "3"]
 LiteralTextFieldVariant = Literal["classic", "surface", "soft"]
 

+ 1 - 2
reflex/components/radix/themes/components/tooltip.py

@@ -3,13 +3,12 @@
 from typing import Literal
 
 from reflex.components.component import Component
+from reflex.components.radix.themes.base import RadixThemesComponent
 from reflex.constants.compiler import MemoizationMode
 from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
 from reflex.utils import format
 from reflex.vars.base import Var
 
-from ..base import RadixThemesComponent
-
 LiteralSideType = Literal[
     "top",
     "right",

+ 5 - 2
reflex/components/radix/themes/layout/base.py

@@ -5,10 +5,13 @@ from __future__ import annotations
 from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import (
+    CommonMarginProps,
+    CommonPaddingProps,
+    RadixThemesComponent,
+)
 from reflex.vars.base import Var
 
-from ..base import CommonMarginProps, CommonPaddingProps, RadixThemesComponent
-
 LiteralBoolNumber = Literal["0", "1"]
 
 

+ 1 - 2
reflex/components/radix/themes/layout/box.py

@@ -3,8 +3,7 @@
 from __future__ import annotations
 
 from reflex.components.el import elements
-
-from ..base import RadixThemesComponent
+from reflex.components.radix.themes.base import RadixThemesComponent
 
 
 class Box(elements.Div, RadixThemesComponent):

+ 1 - 2
reflex/components/radix/themes/layout/container.py

@@ -6,11 +6,10 @@ from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import RadixThemesComponent
 from reflex.style import STACK_CHILDREN_FULL_WIDTH
 from reflex.vars.base import LiteralVar, Var
 
-from ..base import RadixThemesComponent
-
 LiteralContainerSize = Literal["1", "2", "3", "4"]
 
 

+ 6 - 2
reflex/components/radix/themes/layout/flex.py

@@ -6,10 +6,14 @@ from typing import ClassVar, Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    LiteralAlign,
+    LiteralJustify,
+    LiteralSpacing,
+    RadixThemesComponent,
+)
 from reflex.vars.base import Var
 
-from ..base import LiteralAlign, LiteralJustify, LiteralSpacing, RadixThemesComponent
-
 LiteralFlexDirection = Literal["row", "column", "row-reverse", "column-reverse"]
 LiteralFlexWrap = Literal["nowrap", "wrap", "wrap-reverse"]
 

+ 6 - 2
reflex/components/radix/themes/layout/grid.py

@@ -6,10 +6,14 @@ from typing import ClassVar, Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import (
+    LiteralAlign,
+    LiteralJustify,
+    LiteralSpacing,
+    RadixThemesComponent,
+)
 from reflex.vars.base import Var
 
-from ..base import LiteralAlign, LiteralJustify, LiteralSpacing, RadixThemesComponent
-
 LiteralGridFlow = Literal["row", "column", "dense", "row-dense", "column-dense"]
 
 

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

@@ -199,4 +199,5 @@ def __getattr__(name: Any):
     try:
         return globals()[name]
     except KeyError:
-        raise AttributeError(f"module '{__name__} has no attribute '{name}'") from None
+        msg = f"module '{__name__} has no attribute '{name}'"
+        raise AttributeError(msg) from None

+ 1 - 2
reflex/components/radix/themes/layout/section.py

@@ -6,10 +6,9 @@ from typing import Literal
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import RadixThemesComponent
 from reflex.vars.base import LiteralVar, Var
 
-from ..base import RadixThemesComponent
-
 LiteralSectionSize = Literal["1", "2", "3"]
 
 

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

@@ -4,9 +4,9 @@ from __future__ import annotations
 
 from reflex.components.component import Component
 from reflex.components.core.breakpoints import Responsive
+from reflex.components.radix.themes.base import LiteralAlign, LiteralSpacing
 from reflex.vars.base import Var
 
-from ..base import LiteralAlign, LiteralSpacing
 from .flex import Flex, LiteralFlexDirection
 
 

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

@@ -7,9 +7,9 @@ from __future__ import annotations
 
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
 from .base import LiteralTextSize, LiteralTextWeight
 
 

+ 5 - 1
reflex/components/radix/themes/typography/code.py

@@ -8,9 +8,13 @@ from __future__ import annotations
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.markdown.markdown import MarkdownComponentMap
+from reflex.components.radix.themes.base import (
+    LiteralAccentColor,
+    LiteralVariant,
+    RadixThemesComponent,
+)
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, LiteralVariant, RadixThemesComponent
 from .base import LiteralTextSize, LiteralTextWeight
 
 

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

@@ -8,9 +8,9 @@ from __future__ import annotations
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.markdown.markdown import MarkdownComponentMap
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
 from .base import LiteralTextAlign, LiteralTextSize, LiteralTextTrim, LiteralTextWeight
 
 

+ 3 - 2
reflex/components/radix/themes/typography/link.py

@@ -14,10 +14,10 @@ from reflex.components.core.cond import cond
 from reflex.components.el.elements.inline import A
 from reflex.components.markdown.markdown import MarkdownComponentMap
 from reflex.components.next.link import NextLink
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.utils.imports import ImportDict
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
 from .base import LiteralTextSize, LiteralTextTrim, LiteralTextWeight
 
 LiteralLinkUnderline = Literal["auto", "hover", "always", "none"]
@@ -86,7 +86,8 @@ class Link(RadixThemesComponent, A, MemoizationLeaf, MarkdownComponentMap):
 
         if href is not None:
             if not len(children):
-                raise ValueError("Link without a child will not display")
+                msg = "Link without a child will not display"
+                raise ValueError(msg)
 
             if "as_child" not in props:
                 # Extract props for the NextLink, the rest go to the Link/A element.

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

@@ -11,9 +11,9 @@ from reflex.components.component import ComponentNamespace
 from reflex.components.core.breakpoints import Responsive
 from reflex.components.el import elements
 from reflex.components.markdown.markdown import MarkdownComponentMap
+from reflex.components.radix.themes.base import LiteralAccentColor, RadixThemesComponent
 from reflex.vars.base import Var
 
-from ..base import LiteralAccentColor, RadixThemesComponent
 from .base import LiteralTextAlign, LiteralTextSize, LiteralTextTrim, LiteralTextWeight
 
 LiteralType = Literal[

+ 0 - 2
reflex/components/react_player/audio.py

@@ -5,5 +5,3 @@ from reflex.components.react_player.react_player import ReactPlayer
 
 class Audio(ReactPlayer):
     """Audio component share with Video component."""
-
-    pass

+ 0 - 2
reflex/components/react_player/video.py

@@ -5,5 +5,3 @@ from reflex.components.react_player.react_player import ReactPlayer
 
 class Video(ReactPlayer):
     """Video component share with audio component."""
-
-    pass

+ 2 - 1
reflex/components/recharts/charts.py

@@ -64,10 +64,11 @@ class ChartBase(RechartsCharts):
             return
         if isinstance(value, Var) and issubclass(value._var_type, int):
             return
-        raise ValueError(
+        msg = (
             f"Chart {name} must be specified as int pixels or percentage, not {value!r}. "
             "CSS unit dimensions are allowed on parent container."
         )
+        raise ValueError(msg)
 
     @classmethod
     def create(cls, *children: Any, **props: Any) -> Component:

+ 2 - 1
reflex/components/sonner/toast.py

@@ -265,7 +265,8 @@ class Toaster(Component):
             props.setdefault("title", message)
             message = ""
         elif message == "" and "title" not in props and "description" not in props:
-            raise ValueError("Toast message or title or description must be provided.")
+            msg = "Toast message or title or description must be provided."
+            raise ValueError(msg)
 
         if props:
             args = LiteralVar.create(ToastProps(component_name="rx.toast", **props))  # pyright: ignore [reportCallIssue]

+ 2 - 1
reflex/components/suneditor/editor.py

@@ -259,7 +259,8 @@ class Editor(NoSSRComponent):
         """
         if set_options is not None:
             if isinstance(set_options, Var):
-                raise ValueError("EditorOptions cannot be a state Var")
+                msg = "EditorOptions cannot be a state Var"
+                raise ValueError(msg)
             props["set_options"] = {
                 to_camel_case(k): v
                 for k, v in set_options.dict().items()

+ 4 - 2
reflex/components/tags/iter_tag.py

@@ -121,7 +121,8 @@ class IterTag(Tag):
         else:
             # If the render function takes the index as an argument.
             if len(args) != 2:
-                raise ValueError("The render function must take 2 arguments.")
+                msg = "The render function must take 2 arguments."
+                raise ValueError(msg)
             component = self.render_fn(arg, index)
 
         # Nested foreach components or cond must be wrapped in fragments.
@@ -131,7 +132,8 @@ class IterTag(Tag):
         component = _into_component_once(component)
 
         if component is None:
-            raise ValueError("The render function must return a component.")
+            msg = "The render function must return a component."
+            raise ValueError(msg)
 
         # Set the component key.
         if component.key is None:

+ 25 - 31
reflex/config.py

@@ -214,12 +214,10 @@ def get_default_value_for_field(field: dataclasses.Field) -> Any:
     """
     if field.default != dataclasses.MISSING:
         return field.default
-    elif field.default_factory != dataclasses.MISSING:
+    if field.default_factory != dataclasses.MISSING:
         return field.default_factory()
-    else:
-        raise ValueError(
-            f"Missing value for environment variable {field.name} and no default value found"
-        )
+    msg = f"Missing value for environment variable {field.name} and no default value found"
+    raise ValueError(msg)
 
 
 # TODO: Change all interpret_.* signatures to value: str, field: dataclasses.Field once we migrate rx.Config to dataclasses
@@ -241,9 +239,10 @@ def interpret_boolean_env(value: str, field_name: str) -> bool:
 
     if value.lower() in true_values:
         return True
-    elif value.lower() in false_values:
+    if value.lower() in false_values:
         return False
-    raise EnvironmentVarValueError(f"Invalid boolean value: {value} for {field_name}")
+    msg = f"Invalid boolean value: {value} for {field_name}"
+    raise EnvironmentVarValueError(msg)
 
 
 def interpret_int_env(value: str, field_name: str) -> int:
@@ -262,9 +261,8 @@ def interpret_int_env(value: str, field_name: str) -> int:
     try:
         return int(value)
     except ValueError as ve:
-        raise EnvironmentVarValueError(
-            f"Invalid integer value: {value} for {field_name}"
-        ) from ve
+        msg = f"Invalid integer value: {value} for {field_name}"
+        raise EnvironmentVarValueError(msg) from ve
 
 
 def interpret_existing_path_env(value: str, field_name: str) -> ExistingPath:
@@ -282,7 +280,8 @@ def interpret_existing_path_env(value: str, field_name: str) -> ExistingPath:
     """
     path = Path(value)
     if not path.exists():
-        raise EnvironmentVarValueError(f"Path does not exist: {path} for {field_name}")
+        msg = f"Path does not exist: {path} for {field_name}"
+        raise EnvironmentVarValueError(msg)
     return path
 
 
@@ -316,9 +315,8 @@ def interpret_enum_env(value: str, field_type: GenericType, field_name: str) ->
     try:
         return field_type(value)
     except ValueError as ve:
-        raise EnvironmentVarValueError(
-            f"Invalid enum value: {value} for {field_name}"
-        ) from ve
+        msg = f"Invalid enum value: {value} for {field_name}"
+        raise EnvironmentVarValueError(msg) from ve
 
 
 def interpret_env_var_value(
@@ -340,21 +338,20 @@ def interpret_env_var_value(
     field_type = value_inside_optional(field_type)
 
     if is_union(field_type):
-        raise ValueError(
-            f"Union types are not supported for environment variables: {field_name}."
-        )
+        msg = f"Union types are not supported for environment variables: {field_name}."
+        raise ValueError(msg)
 
     if field_type is bool:
         return interpret_boolean_env(value, field_name)
-    elif field_type is str:
+    if field_type is str:
         return value
-    elif field_type is int:
+    if field_type is int:
         return interpret_int_env(value, field_name)
-    elif field_type is Path:
+    if field_type is Path:
         return interpret_path_env(value, field_name)
-    elif field_type is ExistingPath:
+    if field_type is ExistingPath:
         return interpret_existing_path_env(value, field_name)
-    elif get_origin(field_type) is list:
+    if get_origin(field_type) is list:
         return [
             interpret_env_var_value(
                 v,
@@ -363,13 +360,11 @@ def interpret_env_var_value(
             )
             for i, v in enumerate(value.split(":"))
         ]
-    elif inspect.isclass(field_type) and issubclass(field_type, enum.Enum):
+    if inspect.isclass(field_type) and issubclass(field_type, enum.Enum):
         return interpret_enum_env(value, field_type, field_name)
 
-    else:
-        raise ValueError(
-            f"Invalid type for environment variable {field_name}: {field_type}. This is probably an issue in Reflex."
-        )
+    msg = f"Invalid type for environment variable {field_name}: {field_type}. This is probably an issue in Reflex."
+    raise ValueError(msg)
 
 
 T = TypeVar("T")
@@ -982,9 +977,8 @@ If you are not using tailwind, set `tailwind` to `None` in rxconfig.py.""",
             self.state_manager_mode == constants.StateManagerMode.REDIS
             and not self.redis_url
         ):
-            raise ConfigError(
-                f"{self._prefixes[0]}REDIS_URL is required when using the redis state manager."
-            )
+            msg = f"{self._prefixes[0]}REDIS_URL is required when using the redis state manager."
+            raise ConfigError(msg)
 
     @property
     def app_module(self) -> ModuleType | None:
@@ -1008,7 +1002,7 @@ If you are not using tailwind, set `tailwind` to `None` in rxconfig.py.""",
         """
         if self.app_module_import is not None:
             return self.app_module_import
-        return ".".join([self.app_name, self.app_name])
+        return self.app_name + "." + self.app_name
 
     def update_from_env(self) -> dict[str, Any]:
         """Update the config values based on set environment variables.

+ 3 - 3
reflex/constants/base.py

@@ -33,11 +33,11 @@ class Dirs(SimpleNamespace):
     # The name of the utils file.
     UTILS = "utils"
     # The name of the state file.
-    STATE_PATH = "/".join([UTILS, "state"])
+    STATE_PATH = UTILS + "/state"
     # The name of the components file.
-    COMPONENTS_PATH = "/".join([UTILS, "components"])
+    COMPONENTS_PATH = UTILS + "/components"
     # The name of the contexts file.
-    CONTEXTS_PATH = "/".join([UTILS, "context"])
+    CONTEXTS_PATH = UTILS + "/context"
     # The name of the output static directory.
     STATIC = "_static"
     # The name of the public html directory served at "/"

+ 8 - 6
reflex/constants/compiler.py

@@ -176,6 +176,13 @@ DATA_DASH = "data-"
 ARIA_UNDERSCORE = "aria_"
 ARIA_DASH = "aria-"
 
+SPECIAL_ATTRS = (
+    DATA_UNDERSCORE,
+    DATA_DASH,
+    ARIA_UNDERSCORE,
+    ARIA_DASH,
+)
+
 
 class SpecialAttributes(enum.Enum):
     """Special attributes for components.
@@ -194,9 +201,4 @@ class SpecialAttributes(enum.Enum):
         Returns:
             True if the attribute is special.
         """
-        return (
-            attr.startswith(DATA_UNDERSCORE)
-            or attr.startswith(DATA_DASH)
-            or attr.startswith(ARIA_UNDERSCORE)
-            or attr.startswith(ARIA_DASH)
-        )
+        return attr.startswith(SPECIAL_ATTRS)

+ 1 - 2
reflex/custom_components/custom_components.py

@@ -35,7 +35,6 @@ def set_loglevel(ctx: Any, self: Any, value: str | None):
 @click.group
 def custom_components_cli():
     """CLI for creating custom components."""
-    pass
 
 
 loglevel_option = click.option(
@@ -575,7 +574,7 @@ def _validate_url_with_protocol_prefix(url: str | None) -> bool:
     Returns:
         Whether the entered URL is acceptable.
     """
-    return not url or (url.startswith("http://") or url.startswith("https://"))
+    return not url or (url.startswith(("http://", "https://")))
 
 
 def _get_file_from_prompt_in_loop() -> tuple[bytes, str] | None:

+ 58 - 60
reflex/event.py

@@ -228,9 +228,8 @@ class EventHandler(EventActionsMixin):
             ),
             Unset,
         ):
-            raise EventHandlerTypeError(
-                f"Event handler {self.fn.__name__} received repeated argument {repeated_arg}."
-            )
+            msg = f"Event handler {self.fn.__name__} received repeated argument {repeated_arg}."
+            raise EventHandlerTypeError(msg)
 
         if not isinstance(
             extra_arg := next(
@@ -238,9 +237,10 @@ class EventHandler(EventActionsMixin):
             ),
             Unset,
         ):
-            raise EventHandlerTypeError(
+            msg = (
                 f"Event handler {self.fn.__name__} received extra argument {extra_arg}."
             )
+            raise EventHandlerTypeError(msg)
 
         fn_args = fn_args[: len(args)] + list(kwargs)
 
@@ -257,9 +257,8 @@ class EventHandler(EventActionsMixin):
             try:
                 values.append(LiteralVar.create(arg))
             except TypeError as e:
-                raise EventHandlerTypeError(
-                    f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
-                ) from e
+                msg = f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
+                raise EventHandlerTypeError(msg) from e
         payload = tuple(zip(fn_args, values, strict=False))
 
         # Return the event spec.
@@ -353,9 +352,8 @@ class EventSpec(EventActionsMixin):
             for arg in args:
                 values.append(LiteralVar.create(value=arg))  # noqa: PERF401, RUF100
         except TypeError as e:
-            raise EventHandlerTypeError(
-                f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
-            ) from e
+            msg = f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
+            raise EventHandlerTypeError(msg) from e
         new_payload = tuple(zip(fn_args, values, strict=False))
         return self.with_args(self.args + new_payload)
 
@@ -408,7 +406,8 @@ class CallableEventSpec(EventSpec):
         from reflex.utils.exceptions import EventHandlerTypeError
 
         if self.fn is None:
-            raise EventHandlerTypeError("CallableEventSpec has no associated function.")
+            msg = "CallableEventSpec has no associated function."
+            raise EventHandlerTypeError(msg)
         return self.fn(*args, **kwargs)
 
 
@@ -453,7 +452,7 @@ class EventChain(EventActionsMixin):
         if isinstance(value, Var):
             if isinstance(value, EventChainVar):
                 return value
-            elif isinstance(value, EventVar):
+            if isinstance(value, EventVar):
                 value = [value]
             elif safe_issubclass(value._var_type, (EventChain, EventSpec)):
                 return cls.create(
@@ -463,9 +462,8 @@ class EventChain(EventActionsMixin):
                     **event_chain_kwargs,
                 )
             else:
-                raise ValueError(
-                    f"Invalid event chain: {value!s} of type {value._var_type}"
-                )
+                msg = f"Invalid event chain: {value!s} of type {value._var_type}"
+                raise ValueError(msg)
         elif isinstance(value, EventChain):
             # Trust that the caller knows what they're doing passing an EventChain directly
             return value
@@ -485,15 +483,17 @@ class EventChain(EventActionsMixin):
                     # Call the lambda to get the event chain.
                     result = call_event_fn(v, args_spec, key=key)
                     if isinstance(result, Var):
-                        raise ValueError(
+                        msg = (
                             f"Invalid event chain: {v}. Cannot use a Var-returning "
                             "lambda inside an EventChain list."
                         )
+                        raise ValueError(msg)
                     events.extend(result)
                 elif isinstance(v, EventVar):
                     events.append(v)
                 else:
-                    raise ValueError(f"Invalid event: {v}")
+                    msg = f"Invalid event: {v}"
+                    raise ValueError(msg)
 
         # If the input is a callable, create an event chain.
         elif isinstance(value, Callable):
@@ -507,7 +507,8 @@ class EventChain(EventActionsMixin):
 
         # Otherwise, raise an error.
         else:
-            raise ValueError(f"Invalid event chain: {value}")
+            msg = f"Invalid event chain: {value}"
+            raise ValueError(msg)
 
         # Add args to the event specs if necessary.
         events = [
@@ -783,9 +784,11 @@ class FileUpload:
                     on_upload_progress, self.on_upload_progress_args_spec
                 )
             else:
-                raise ValueError(f"{on_upload_progress} is not a valid event handler.")
+                msg = f"{on_upload_progress} is not a valid event handler."
+                raise ValueError(msg)
             if isinstance(events, Var):
-                raise ValueError(f"{on_upload_progress} cannot return a var {events}.")
+                msg = f"{on_upload_progress} cannot return a var {events}."
+                raise ValueError(msg)
             on_upload_progress_chain = EventChain(
                 events=[*events],
                 args_spec=self.on_upload_progress_args_spec,
@@ -1081,7 +1084,8 @@ def download(
 
     if isinstance(url, str):
         if not url.startswith("/"):
-            raise ValueError("The URL argument should start with a /")
+            msg = "The URL argument should start with a /"
+            raise ValueError(msg)
 
         # if filename is not provided, infer it from url
         if filename is None:
@@ -1092,7 +1096,8 @@ def download(
 
     if data is not None:
         if url is not None:
-            raise ValueError("Cannot provide both URL and data to download.")
+            msg = "Cannot provide both URL and data to download."
+            raise ValueError(msg)
 
         if isinstance(data, str):
             # Caller provided a plain text string to download.
@@ -1115,9 +1120,8 @@ def download(
             b64_data = b64encode(data).decode("utf-8")
             url = "data:application/octet-stream;base64," + b64_data
         else:
-            raise ValueError(
-                f"Invalid data type {type(data)} for download. Use `str` or `bytes`."
-            )
+            msg = f"Invalid data type {type(data)} for download. Use `str` or `bytes`."
+            raise ValueError(msg)
 
     return server_side(
         "_download",
@@ -1323,23 +1327,21 @@ def _check_event_args_subclass_of_callback(
             except TypeError as te:
                 callback_name_context = f" of {callback_name}" if callback_name else ""
                 key_context = f" for {key}" if key else ""
-                raise TypeError(
-                    f"Could not compare types {args_types_without_vars[i]} and {callback_param_name_to_type[arg]} for argument {arg}{callback_name_context}{key_context}."
-                ) from te
+                msg = f"Could not compare types {args_types_without_vars[i]} and {callback_param_name_to_type[arg]} for argument {arg}{callback_name_context}{key_context}."
+                raise TypeError(msg) from te
 
             if compare_result:
                 type_match_found[arg] = True
                 continue
-            else:
-                type_match_found[arg] = False
-                as_annotated_in = (
-                    f" as annotated in {callback_name}" if callback_name else ""
-                )
-                delayed_exceptions.append(
-                    EventHandlerArgTypeMismatchError(
-                        f"Event handler {key} expects {args_types_without_vars[i]} for argument {arg} but got {callback_param_name_to_type[arg]}{as_annotated_in} instead."
-                    )
+            type_match_found[arg] = False
+            as_annotated_in = (
+                f" as annotated in {callback_name}" if callback_name else ""
+            )
+            delayed_exceptions.append(
+                EventHandlerArgTypeMismatchError(
+                    f"Event handler {key} expects {args_types_without_vars[i]} for argument {arg} but got {callback_param_name_to_type[arg]}{as_annotated_in} instead."
                 )
+            )
 
         if all(type_match_found.values()):
             delayed_exceptions.clear()
@@ -1495,8 +1497,7 @@ def resolve_annotation(annotations: dict[str, Any], arg_name: str, spec: ArgsSpe
     if annotation is None:
         if not isinstance(spec, types.LambdaType):
             raise MissingAnnotationError(var_name=arg_name)
-        else:
-            return dict[str, dict]
+        return dict[str, dict]
     return annotation
 
 
@@ -1570,12 +1571,13 @@ def check_fn_match_arg_spec(
     number_of_event_args = len(parsed_event_args)
 
     if number_of_user_args - number_of_user_default_args > number_of_event_args:
-        raise EventFnArgMismatchError(
+        msg = (
             f"Event {key} only provides {number_of_event_args} arguments, but "
             f"{func_name or user_func} requires at least {number_of_user_args - number_of_user_default_args} "
             "arguments to be passed to the event handler.\n"
             "See https://reflex.dev/docs/events/event-arguments/"
         )
+        raise EventFnArgMismatchError(msg)
 
 
 def call_event_fn(
@@ -1630,9 +1632,8 @@ def call_event_fn(
 
         # Make sure the event spec is valid.
         if not isinstance(e, EventSpec):
-            raise EventHandlerValueError(
-                f"Lambda {fn} returned an invalid event spec: {e}."
-            )
+            msg = f"Lambda {fn} returned an invalid event spec: {e}."
+            raise EventHandlerValueError(msg)
 
         # Add the event spec to the chain.
         events.append(e)
@@ -1696,7 +1697,8 @@ def fix_events(
         if isinstance(e, EventHandler):
             e = e()
         if not isinstance(e, EventSpec):
-            raise ValueError(f"Unexpected event type, {type(e)}.")
+            msg = f"Unexpected event type, {type(e)}."
+            raise ValueError(msg)
         name = format.format_event_handler(e.handler)
         payload = {k._js_expr: v._decode() for k, v in e.args}
 
@@ -1749,9 +1751,8 @@ class EventVar(ObjectVar, python_types=(EventSpec, EventHandler)):
         Raises:
             TypeError: EventVar cannot be converted to a boolean.
         """
-        raise TypeError(
-            f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
-        )
+        msg = f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
+        raise TypeError(msg)
 
 
 @dataclasses.dataclass(
@@ -1798,9 +1799,8 @@ class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
             try:
                 value = call_event_handler(value, no_args)
             except EventFnArgMismatchError:
-                raise EventFnArgMismatchError(
-                    f"Event handler {value.fn.__qualname__} used inside of a rx.cond() must not take any arguments."
-                ) from None
+                msg = f"Event handler {value.fn.__qualname__} used inside of a rx.cond() must not take any arguments."
+                raise EventFnArgMismatchError(msg) from None
 
         return cls(
             _js_expr="",
@@ -1835,9 +1835,8 @@ class EventChainVar(BuilderFunctionVar, python_types=EventChain):
         Raises:
             TypeError: EventChainVar cannot be converted to a boolean.
         """
-        raise TypeError(
-            f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
-        )
+        msg = f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
+        raise TypeError(msg)
 
 
 @dataclasses.dataclass(
@@ -1906,9 +1905,8 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
             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}."
-            )
+            msg = f"EventChain invocation must be a FunctionVar, got {invocation!s} of type {invocation._var_type!s}."
+            raise ValueError(msg)
 
         return cls(
             _js_expr="",
@@ -2142,12 +2140,12 @@ class EventNamespace:
                 if not inspect.iscoroutinefunction(
                     func
                 ) and not inspect.isasyncgenfunction(func):
-                    raise TypeError(
-                        "Background task must be async function or generator."
-                    )
+                    msg = "Background task must be async function or generator."
+                    raise TypeError(msg)
                 setattr(func, BACKGROUND_TASK_MARKER, True)
             if getattr(func, "__name__", "").startswith("_"):
-                raise ValueError("Event handlers cannot be private.")
+                msg = "Event handlers cannot be private."
+                raise ValueError(msg)
 
             qualname: str | None = getattr(func, "__qualname__", None)
 

+ 2 - 2
reflex/experimental/__init__.py

@@ -6,9 +6,9 @@ from reflex.components.datadisplay.shiki_code_block import code_block as code_bl
 from reflex.components.props import PropsBase
 from reflex.components.radix.themes.components.progress import progress as progress
 from reflex.components.sonner.toast import toast as toast
+from reflex.utils.console import warn
+from reflex.utils.misc import run_in_thread
 
-from ..utils.console import warn
-from ..utils.misc import run_in_thread
 from . import hooks as hooks
 from .client_state import ClientStateVar as ClientStateVar
 from .layout import layout as layout

+ 6 - 3
reflex/experimental/client_state.py

@@ -111,7 +111,8 @@ class ClientStateVar(Var):
             var_name = get_unique_variable_name()
         id_name = "id_" + get_unique_variable_name()
         if not isinstance(var_name, str):
-            raise ValueError("var_name must be a string.")
+            msg = "var_name must be a string."
+            raise ValueError(msg)
         if default is NoValue:
             default_var = Var(_js_expr="")
         elif not isinstance(default, Var):
@@ -271,7 +272,8 @@ class ClientStateVar(Var):
             ValueError: If the ClientStateVar is not global.
         """
         if not self._global_ref:
-            raise ValueError("ClientStateVar must be global to retrieve the value.")
+            msg = "ClientStateVar must be global to retrieve the value."
+            raise ValueError(msg)
         return run_script(_client_state_ref(self._getter_name), callback=callback)
 
     def push(self, value: Any) -> EventSpec:
@@ -289,6 +291,7 @@ class ClientStateVar(Var):
             ValueError: If the ClientStateVar is not global.
         """
         if not self._global_ref:
-            raise ValueError("ClientStateVar must be global to push the value.")
+            msg = "ClientStateVar must be global to push the value."
+            raise ValueError(msg)
         value = Var.create(value)
         return run_script(f"{_client_state_ref(self._setter_name)}({value})")

+ 15 - 19
reflex/istate/manager.py

@@ -66,9 +66,8 @@ class StateManager(ABC):
                     lock_expiration=config.redis_lock_expiration,
                     lock_warning_threshold=config.redis_lock_warning_threshold,
                 )
-        raise InvalidStateManagerModeError(
-            f"Expected one of: DISK, MEMORY, REDIS, got {config.state_manager_mode}"
-        )
+        msg = f"Expected one of: DISK, MEMORY, REDIS, got {config.state_manager_mode}"
+        raise InvalidStateManagerModeError(msg)
 
     @abstractmethod
     async def get_state(self, token: str) -> BaseState:
@@ -80,7 +79,6 @@ class StateManager(ABC):
         Returns:
             The state for the token.
         """
-        pass
 
     @abstractmethod
     async def set_state(self, token: str, state: BaseState):
@@ -90,7 +88,6 @@ class StateManager(ABC):
             token: The token to set the state for.
             state: The state to set.
         """
-        pass
 
     @abstractmethod
     @contextlib.asynccontextmanager
@@ -145,7 +142,6 @@ class StateManagerMemory(StateManager):
             token: The token to set the state for.
             state: The state to set.
         """
-        pass
 
     @override
     @contextlib.asynccontextmanager
@@ -269,6 +265,7 @@ class StateManagerDisk(StateManager):
                     return BaseState._deserialize(fp=file)
             except Exception:
                 pass
+        return None
 
     async def populate_substates(
         self, client_token: str, state: BaseState, root_state: BaseState
@@ -449,9 +446,8 @@ class StateManagerRedis(StateManager):
             InvalidLockWarningThresholdError: If the lock warning threshold is invalid.
         """
         if self.lock_warning_threshold >= (lock_expiration := self.lock_expiration):
-            raise InvalidLockWarningThresholdError(
-                f"The lock warning threshold({self.lock_warning_threshold}) must be less than the lock expiration time({lock_expiration})."
-            )
+            msg = f"The lock warning threshold({self.lock_warning_threshold}) must be less than the lock expiration time({lock_expiration})."
+            raise InvalidLockWarningThresholdError(msg)
 
     def _get_required_state_classes(
         self,
@@ -557,9 +553,8 @@ class StateManagerRedis(StateManager):
             # Get the State class associated with the given path.
             state_cls = self.state.get_class_substate(state_path)
         else:
-            raise RuntimeError(
-                f"StateManagerRedis requires token to be specified in the form of {{token}}_{{state_full_name}}, but got {token}"
-            )
+            msg = f"StateManagerRedis requires token to be specified in the form of {{token}}_{{state_full_name}}, but got {token}"
+            raise RuntimeError(msg)
 
         # Determine which states we already have.
         flat_state_tree: dict[str, BaseState] = (
@@ -601,11 +596,12 @@ class StateManagerRedis(StateManager):
                 )
                 parent_state = flat_state_tree.get(parent_state_name)
                 if parent_state is None:
-                    raise RuntimeError(
+                    msg = (
                         f"Parent state for {state.get_full_name()} was not found "
                         "in the state tree, but should have already been fetched. "
-                        "This is a bug",
+                        "This is a bug"
                     )
+                    raise RuntimeError(msg)
                 parent_state.substates[state_name] = state
                 state.parent_state = parent_state
 
@@ -638,12 +634,13 @@ class StateManagerRedis(StateManager):
             lock_id is not None
             and await self.redis.get(self._lock_key(token)) != lock_id
         ):
-            raise LockExpiredError(
+            msg = (
                 f"Lock expired for token {token} while processing. Consider increasing "
                 f"`app.state_manager.lock_expiration` (currently {self.lock_expiration}) "
                 "or use `@rx.event(background=True)` decorator for long-running tasks."
             )
-        elif lock_id is not None:
+            raise LockExpiredError(msg)
+        if lock_id is not None:
             time_taken = self.lock_expiration / 1000 - (
                 await self.redis.ttl(self._lock_key(token))
             )
@@ -657,9 +654,8 @@ class StateManagerRedis(StateManager):
         client_token, substate_name = _split_substate_key(token)
         # If the substate name on the token doesn't match the instance name, it cannot have a parent.
         if state.parent_state is not None and state.get_full_name() != substate_name:
-            raise RuntimeError(
-                f"Cannot `set_state` with mismatching token {token} and substate {state.get_full_name()}."
-            )
+            msg = f"Cannot `set_state` with mismatching token {token} and substate {state.get_full_name()}."
+            raise RuntimeError(msg)
 
         # Recursively set_state on all known substates.
         tasks = [

+ 19 - 12
reflex/istate/proxy.py

@@ -122,9 +122,8 @@ class StateProxy(wrapt.ObjectProxy):
             self._self_actx_lock.locked()
             and current_task == self._self_actx_lock_holder
         ):
-            raise ImmutableStateError(
-                "The state is already mutable. Do not nest `async with self` blocks."
-            )
+            msg = "The state is already mutable. Do not nest `async with self` blocks."
+            raise ImmutableStateError(msg)
 
         from reflex.state import _substate_key
 
@@ -173,7 +172,8 @@ class StateProxy(wrapt.ObjectProxy):
         Raises:
             TypeError: always, because only async contextmanager protocol is supported.
         """
-        raise TypeError("Background task must use `async with self` to modify state.")
+        msg = "Background task must use `async with self` to modify state."
+        raise TypeError(msg)
 
     def __exit__(self, *exc_info: Any) -> None:
         """Exit the regular context manager protocol.
@@ -181,7 +181,6 @@ class StateProxy(wrapt.ObjectProxy):
         Args:
             exc_info: The exception info tuple.
         """
-        pass
 
     def __getattr__(self, name: str) -> Any:
         """Get the attribute from the underlying state instance.
@@ -196,10 +195,11 @@ class StateProxy(wrapt.ObjectProxy):
             ImmutableStateError: If the state is not in mutable mode.
         """
         if name in ["substates", "parent_state"] and not self._is_mutable():
-            raise ImmutableStateError(
+            msg = (
                 "Background task StateProxy is immutable outside of a context "
                 "manager. Use `async with self` to modify state."
             )
+            raise ImmutableStateError(msg)
 
         value = super().__getattr__(name)
         if not name.startswith("_self_") and isinstance(value, MutableProxy):
@@ -243,10 +243,11 @@ class StateProxy(wrapt.ObjectProxy):
             super().__setattr__(name, value)
             return
 
-        raise ImmutableStateError(
+        msg = (
             "Background task StateProxy is immutable outside of a context "
             "manager. Use `async with self` to modify state."
         )
+        raise ImmutableStateError(msg)
 
     def get_substate(self, path: Sequence[str]) -> BaseState:
         """Only allow substate access with lock held.
@@ -261,10 +262,11 @@ class StateProxy(wrapt.ObjectProxy):
             ImmutableStateError: If the state is not in mutable mode.
         """
         if not self._is_mutable():
-            raise ImmutableStateError(
+            msg = (
                 "Background task StateProxy is immutable outside of a context "
                 "manager. Use `async with self` to modify state."
             )
+            raise ImmutableStateError(msg)
         return self.__wrapped__.get_substate(path)
 
     async def get_state(self, state_cls: type[BaseState]) -> BaseState:
@@ -280,10 +282,11 @@ class StateProxy(wrapt.ObjectProxy):
             ImmutableStateError: If the state is not in mutable mode.
         """
         if not self._is_mutable():
-            raise ImmutableStateError(
+            msg = (
                 "Background task StateProxy is immutable outside of a context "
                 "manager. Use `async with self` to modify state."
             )
+            raise ImmutableStateError(msg)
         return type(self)(
             await self.__wrapped__.get_state(state_cls), parent_state_proxy=self
         )
@@ -323,7 +326,8 @@ class ReadOnlyStateProxy(StateProxy):
             # Special case attributes of the proxy itself, not applied to the wrapped object.
             super().__setattr__(name, value)
             return
-        raise NotImplementedError("This is a read-only state proxy.")
+        msg = "This is a read-only state proxy."
+        raise NotImplementedError(msg)
 
     def mark_dirty(self):
         """Mark the state as dirty.
@@ -331,7 +335,8 @@ class ReadOnlyStateProxy(StateProxy):
         Raises:
             NotImplementedError: Always raised when trying to mark the proxied state as dirty.
         """
-        raise NotImplementedError("This is a read-only state proxy.")
+        msg = "This is a read-only state proxy."
+        raise NotImplementedError(msg)
 
 
 class MutableProxy(wrapt.ObjectProxy):
@@ -460,6 +465,7 @@ class MutableProxy(wrapt.ObjectProxy):
         self._self_state._mark_dirty()
         if wrapped is not None:
             return wrapped(*args, **(kwargs or {}))
+        return None
 
     @classmethod
     def _is_mutable_type(cls, value: Any) -> bool:
@@ -748,10 +754,11 @@ class ImmutableMutableProxy(MutableProxy):
             ImmutableStateError: if the StateProxy is not mutable.
         """
         if not self._self_state._is_mutable():
-            raise ImmutableStateError(
+            msg = (
                 "Background task StateProxy is immutable outside of a context "
                 "manager. Use `async with self` to modify state."
             )
+            raise ImmutableStateError(msg)
         return super()._mark_dirty(
             wrapped=wrapped, instance=instance, args=args, kwargs=kwargs
         )

+ 6 - 4
reflex/model.py

@@ -83,7 +83,8 @@ def get_engine(url: str | None = None) -> sqlalchemy.engine.Engine:
     conf = get_config()
     url = url or conf.db_url
     if url is None:
-        raise ValueError("No database url configured")
+        msg = "No database url configured"
+        raise ValueError(msg)
 
     global _ENGINE
     if url in _ENGINE:
@@ -125,7 +126,8 @@ def get_async_engine(url: str | None) -> sqlalchemy.ext.asyncio.AsyncEngine:
                     f"db_url `{_safe_db_url_for_logging(conf.db_url)}`."
                 )
     if url is None:
-        raise ValueError("No async database url configured")
+        msg = "No async database url configured"
+        raise ValueError(msg)
 
     global _ASYNC_ENGINE
     if url in _ASYNC_ENGINE:
@@ -271,7 +273,7 @@ class Model(Base, sqlmodel.SQLModel):  # pyright: ignore [reportGeneralTypeIssue
         """
         if hasattr(value, "dict"):
             return value.dict()
-        elif isinstance(value, list):
+        if isinstance(value, list):
             return [cls._dict_recursive(item) for item in value]
         return value
 
@@ -481,7 +483,7 @@ class Model(Base, sqlmodel.SQLModel):  # pyright: ignore [reportGeneralTypeIssue
             None - indicating the process was skipped.
         """
         if not environment.ALEMBIC_CONFIG.get().exists():
-            return
+            return None
 
         with cls.get_db_engine().connect() as connection:
             cls._alembic_upgrade(connection=connection)

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません