reflex 0.8.15a1__py3-none-any.whl → 0.8.16a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

Files changed (139) hide show
  1. reflex/.templates/web/utils/state.js +68 -8
  2. reflex/app.py +45 -51
  3. reflex/app_mixins/lifespan.py +12 -5
  4. reflex/base.py +1 -0
  5. reflex/compiler/compiler.py +4 -6
  6. reflex/compiler/templates.py +25 -31
  7. reflex/compiler/utils.py +6 -5
  8. reflex/components/base/body.pyi +1 -195
  9. reflex/components/base/link.pyi +1 -407
  10. reflex/components/base/meta.pyi +1 -405
  11. reflex/components/base/script.pyi +1 -237
  12. reflex/components/component.py +41 -46
  13. reflex/components/core/auto_scroll.pyi +1 -195
  14. reflex/components/core/banner.pyi +1 -391
  15. reflex/components/core/breakpoints.py +14 -18
  16. reflex/components/core/html.pyi +1 -197
  17. reflex/components/core/match.py +2 -2
  18. reflex/components/core/sticky.py +11 -15
  19. reflex/components/core/sticky.pyi +0 -788
  20. reflex/components/core/upload.py +1 -3
  21. reflex/components/datadisplay/code.pyi +1 -0
  22. reflex/components/datadisplay/dataeditor.py +4 -6
  23. reflex/components/datadisplay/shiki_code_block.py +106 -110
  24. reflex/components/dynamic.py +4 -6
  25. reflex/components/el/elements/__init__.py +5 -7
  26. reflex/components/el/elements/__init__.pyi +5 -7
  27. reflex/components/el/elements/base.py +1 -1
  28. reflex/components/el/elements/base.pyi +1 -195
  29. reflex/components/el/elements/forms.py +7 -9
  30. reflex/components/el/elements/forms.pyi +12 -3112
  31. reflex/components/el/elements/inline.pyi +0 -5481
  32. reflex/components/el/elements/media.pyi +0 -10280
  33. reflex/components/el/elements/metadata.pyi +1 -835
  34. reflex/components/el/elements/other.pyi +1 -1365
  35. reflex/components/el/elements/scripts.pyi +1 -625
  36. reflex/components/el/elements/sectioning.pyi +1 -2911
  37. reflex/components/el/elements/tables.pyi +1 -1973
  38. reflex/components/el/elements/typography.pyi +1 -3125
  39. reflex/components/lucide/icon.py +4 -4
  40. reflex/components/lucide/icon.pyi +0 -4
  41. reflex/components/markdown/markdown.py +15 -19
  42. reflex/components/markdown/markdown.pyi +1 -0
  43. reflex/components/moment/moment.pyi +0 -49
  44. reflex/components/props.py +3 -3
  45. reflex/components/radix/primitives/accordion.py +4 -6
  46. reflex/components/radix/primitives/accordion.pyi +0 -14
  47. reflex/components/radix/primitives/base.pyi +0 -5
  48. reflex/components/radix/primitives/dialog.py +2 -0
  49. reflex/components/radix/primitives/dialog.pyi +1 -233
  50. reflex/components/radix/primitives/drawer.pyi +0 -18
  51. reflex/components/radix/primitives/form.pyi +30 -632
  52. reflex/components/radix/primitives/progress.pyi +0 -10
  53. reflex/components/radix/primitives/slider.pyi +0 -10
  54. reflex/components/radix/themes/color_mode.pyi +1 -284
  55. reflex/components/radix/themes/components/alert_dialog.pyi +0 -207
  56. reflex/components/radix/themes/components/aspect_ratio.pyi +0 -2
  57. reflex/components/radix/themes/components/avatar.pyi +0 -80
  58. reflex/components/radix/themes/components/badge.pyi +1 -270
  59. reflex/components/radix/themes/components/button.pyi +1 -274
  60. reflex/components/radix/themes/components/callout.pyi +0 -1197
  61. reflex/components/radix/themes/components/card.pyi +1 -209
  62. reflex/components/radix/themes/components/checkbox.pyi +0 -261
  63. reflex/components/radix/themes/components/checkbox_cards.pyi +1 -96
  64. reflex/components/radix/themes/components/checkbox_group.pyi +1 -80
  65. reflex/components/radix/themes/components/context_menu.pyi +13 -321
  66. reflex/components/radix/themes/components/data_list.pyi +1 -107
  67. reflex/components/radix/themes/components/dialog.pyi +1 -210
  68. reflex/components/radix/themes/components/dropdown_menu.pyi +0 -209
  69. reflex/components/radix/themes/components/hover_card.pyi +1 -246
  70. reflex/components/radix/themes/components/icon_button.pyi +1 -195
  71. reflex/components/radix/themes/components/inset.pyi +0 -252
  72. reflex/components/radix/themes/components/popover.pyi +1 -234
  73. reflex/components/radix/themes/components/progress.pyi +1 -84
  74. reflex/components/radix/themes/components/radio.pyi +1 -72
  75. reflex/components/radix/themes/components/radio_cards.pyi +1 -123
  76. reflex/components/radix/themes/components/scroll_area.pyi +1 -11
  77. reflex/components/radix/themes/components/select.pyi +1 -376
  78. reflex/components/radix/themes/components/separator.pyi +0 -77
  79. reflex/components/radix/themes/components/skeleton.pyi +0 -30
  80. reflex/components/radix/themes/components/slider.py +3 -5
  81. reflex/components/radix/themes/components/spinner.pyi +0 -5
  82. reflex/components/radix/themes/components/switch.pyi +0 -89
  83. reflex/components/radix/themes/components/table.pyi +0 -1453
  84. reflex/components/radix/themes/components/text_area.pyi +7 -282
  85. reflex/components/radix/themes/components/text_field.pyi +6 -392
  86. reflex/components/radix/themes/components/tooltip.pyi +0 -42
  87. reflex/components/radix/themes/layout/box.pyi +1 -195
  88. reflex/components/radix/themes/layout/center.pyi +0 -194
  89. reflex/components/radix/themes/layout/container.pyi +0 -178
  90. reflex/components/radix/themes/layout/flex.pyi +0 -194
  91. reflex/components/radix/themes/layout/grid.pyi +0 -194
  92. reflex/components/radix/themes/layout/list.pyi +0 -978
  93. reflex/components/radix/themes/layout/section.pyi +0 -194
  94. reflex/components/radix/themes/layout/spacer.pyi +0 -194
  95. reflex/components/radix/themes/layout/stack.pyi +0 -582
  96. reflex/components/radix/themes/typography/blockquote.pyi +0 -196
  97. reflex/components/radix/themes/typography/code.pyi +0 -194
  98. reflex/components/radix/themes/typography/heading.pyi +0 -194
  99. reflex/components/radix/themes/typography/link.pyi +0 -237
  100. reflex/components/radix/themes/typography/text.pyi +0 -1360
  101. reflex/components/react_router/dom.pyi +0 -237
  102. reflex/components/recharts/cartesian.py +12 -18
  103. reflex/components/recharts/general.py +12 -18
  104. reflex/constants/installer.py +5 -5
  105. reflex/custom_components/custom_components.py +6 -5
  106. reflex/environment.py +30 -7
  107. reflex/event.py +14 -12
  108. reflex/experimental/client_state.py +11 -12
  109. reflex/istate/data.py +8 -10
  110. reflex/istate/manager/__init__.py +3 -0
  111. reflex/istate/manager/disk.py +151 -5
  112. reflex/model.py +1 -1
  113. reflex/plugins/_screenshot.py +2 -2
  114. reflex/plugins/shared_tailwind.py +9 -14
  115. reflex/reflex.py +7 -9
  116. reflex/state.py +30 -37
  117. reflex/style.py +6 -6
  118. reflex/testing.py +54 -30
  119. reflex/utils/codespaces.py +31 -2
  120. reflex/utils/compat.py +1 -0
  121. reflex/utils/decorator.py +3 -3
  122. reflex/utils/format.py +18 -22
  123. reflex/utils/prerequisites.py +1 -1
  124. reflex/utils/pyi_generator.py +51 -57
  125. reflex/utils/serializers.py +1 -1
  126. reflex/utils/telemetry.py +1 -1
  127. reflex/utils/templates.py +4 -4
  128. reflex/utils/types.py +11 -4
  129. reflex/vars/base.py +26 -29
  130. reflex/vars/color.py +6 -8
  131. reflex/vars/dep_tracking.py +5 -3
  132. reflex/vars/function.py +3 -3
  133. reflex/vars/object.py +9 -13
  134. reflex/vars/sequence.py +18 -24
  135. {reflex-0.8.15a1.dist-info → reflex-0.8.16a1.dist-info}/METADATA +1 -1
  136. {reflex-0.8.15a1.dist-info → reflex-0.8.16a1.dist-info}/RECORD +139 -139
  137. {reflex-0.8.15a1.dist-info → reflex-0.8.16a1.dist-info}/WHEEL +0 -0
  138. {reflex-0.8.15a1.dist-info → reflex-0.8.16a1.dist-info}/entry_points.txt +0 -0
  139. {reflex-0.8.15a1.dist-info → reflex-0.8.16a1.dist-info}/licenses/LICENSE +0 -0
@@ -26,11 +26,40 @@ def redirect_script() -> str:
26
26
  const thisUrl = new URL(window.location.href);
27
27
  const params = new URLSearchParams(thisUrl.search)
28
28
 
29
+ function sameHostnameDifferentPort(one, two) {{
30
+ const hostnameOne = one.hostname;
31
+ const hostnameTwo = two.hostname;
32
+ const partsOne = hostnameOne.split(".");
33
+ const partsTwo = hostnameTwo.split(".");
34
+ if (partsOne.length !== partsTwo.length) {{ return false; }}
35
+ for (let i = 1; i < partsOne.length; i++) {{
36
+ if (partsOne[i] !== partsTwo[i]) {{ return false; }}
37
+ }}
38
+ const uniqueNameOne = partsOne[0];
39
+ const uniqueNameTwo = partsTwo[0];
40
+ const uniqueNamePartsOne = uniqueNameOne.split("-");
41
+ const uniqueNamePartsTwo = uniqueNameTwo.split("-");
42
+ if (uniqueNamePartsOne.length !== uniqueNamePartsTwo.length) {{ return false; }}
43
+ for (let i = 0; i < uniqueNamePartsOne.length - 1; i++) {{
44
+ if (uniqueNamePartsOne[i] !== uniqueNamePartsTwo[i]) {{ return false; }}
45
+ }}
46
+ return true;
47
+ }}
48
+
29
49
  function doRedirect(url) {{
30
50
  if (!window.sessionStorage.getItem("authenticated_github_codespaces")) {{
31
51
  const a = document.createElement("a");
32
52
  if (params.has("redirect_to")) {{
33
- a.href = params.get("redirect_to")
53
+ const redirect_to = new URL(params.get("redirect_to"));
54
+ if (!sameHostnameDifferentPort(thisUrl, redirect_to)) {{
55
+ console.warn("Reflex: Not redirecting to different hostname");
56
+ return;
57
+ }}
58
+ if (!redirect_to.hostname.endsWith(".app.github.dev")) {{
59
+ console.warn("Reflex: Not redirecting to non .app.github.dev hostname");
60
+ return;
61
+ }}
62
+ a.href = redirect_to.href;
34
63
  }} else if (!window.location.href.startsWith(url)) {{
35
64
  a.href = url + `?redirect_to=${{window.location.href}}`
36
65
  }} else {{
@@ -75,7 +104,7 @@ def codespaces_auto_redirect() -> list[Component]:
75
104
  return []
76
105
 
77
106
 
78
- async def auth_codespace(_request: Request) -> HTMLResponse:
107
+ def auth_codespace(_request: Request) -> HTMLResponse:
79
108
  """Page automatically redirecting back to the app after authenticating a codespace port forward.
80
109
 
81
110
  Args:
reflex/utils/compat.py CHANGED
@@ -74,6 +74,7 @@ if find_spec("pydantic") and find_spec("pydantic.v1"):
74
74
  """
75
75
  namespace["__annotations__"] = annotations_from_namespace(namespace)
76
76
  return super().__new__(mcs, name, bases, namespace, **kwargs)
77
+
77
78
  else:
78
79
  ModelMetaclassLazyAnnotations = type # type: ignore[assignment]
79
80
 
reflex/utils/decorator.py CHANGED
@@ -110,14 +110,14 @@ def cached_procedure(
110
110
 
111
111
  def _inner_decorator(func: Callable[P, Picklable]) -> Callable[P, Picklable]:
112
112
  def _inner(*args: P.args, **kwargs: P.kwargs) -> Picklable:
113
- _cache_file = cache_file_path()
113
+ cache_file = cache_file_path()
114
114
 
115
- payload, value = _read_cached_procedure_file(_cache_file)
115
+ payload, value = _read_cached_procedure_file(cache_file)
116
116
  new_payload = payload_fn(*args, **kwargs)
117
117
 
118
118
  if payload != new_payload:
119
119
  new_value = func(*args, **kwargs)
120
- _write_cached_procedure_file(new_payload, _cache_file, new_value)
120
+ _write_cached_procedure_file(new_payload, cache_file, new_value)
121
121
  return new_value
122
122
 
123
123
  from reflex.utils import console
reflex/utils/format.py CHANGED
@@ -165,8 +165,8 @@ def to_snake_case(text: str) -> str:
165
165
  Returns:
166
166
  The snake case string.
167
167
  """
168
- s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", text)
169
- return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower().replace("-", "_")
168
+ s1 = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", text)
169
+ return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s1).lower().replace("-", "_")
170
170
 
171
171
 
172
172
  def to_camel_case(text: str, treat_hyphens_as_underscores: bool = True) -> str:
@@ -349,9 +349,9 @@ def format_match(
349
349
  for case in match_cases:
350
350
  conditions, return_value = case
351
351
 
352
- case_conditions = " ".join(
353
- [f"case JSON.stringify({condition!s}):" for condition in conditions]
354
- )
352
+ case_conditions = " ".join([
353
+ f"case JSON.stringify({condition!s}):" for condition in conditions
354
+ ])
355
355
  case_code = f"{case_conditions} return ({return_value!s}); break;"
356
356
  switch_code += case_code
357
357
 
@@ -493,24 +493,20 @@ def format_event(event_spec: EventSpec) -> str:
493
493
  Returns:
494
494
  The compiled event.
495
495
  """
496
- args = ",".join(
497
- [
498
- ":".join(
499
- (
500
- name._js_expr,
501
- (
502
- wrap(
503
- json.dumps(val._js_expr).strip('"').replace("`", "\\`"),
504
- "`",
505
- )
506
- if val._var_is_string
507
- else str(val)
508
- ),
496
+ args = ",".join([
497
+ ":".join((
498
+ name._js_expr,
499
+ (
500
+ wrap(
501
+ json.dumps(val._js_expr).strip('"').replace("`", "\\`"),
502
+ "`",
509
503
  )
510
- )
511
- for name, val in event_spec.args
512
- ]
513
- )
504
+ if val._var_is_string
505
+ else str(val)
506
+ ),
507
+ ))
508
+ for name, val in event_spec.args
509
+ ])
514
510
  event_args = [
515
511
  wrap(format_event_handler(event_spec.handler), '"'),
516
512
  ]
@@ -458,7 +458,7 @@ def validate_app_name(app_name: str | None = None) -> str:
458
458
  Raises:
459
459
  SystemExit: if the app directory name is reflex or if the name is not standard for a python package name.
460
460
  """
461
- app_name = app_name if app_name else Path.cwd().name.replace("-", "_")
461
+ app_name = app_name or Path.cwd().name.replace("-", "_")
462
462
  # Make sure the app is not named "reflex".
463
463
  if app_name.lower() == constants.Reflex.MODULE_NAME:
464
464
  console.error(
@@ -193,9 +193,9 @@ def _get_type_hint(
193
193
 
194
194
  if value.__name__ == "Var":
195
195
  args = list(
196
- chain.from_iterable(
197
- [get_args(arg) if rx_types.is_union(arg) else [arg] for arg in args]
198
- )
196
+ chain.from_iterable([
197
+ get_args(arg) if rx_types.is_union(arg) else [arg] for arg in args
198
+ ])
199
199
  )
200
200
 
201
201
  # For Var types, Union with the inner args so they can be passed directly.
@@ -270,7 +270,7 @@ def _generate_docstrings(clzs: list[type[Component]], props: list[str]) -> str:
270
270
  comments = []
271
271
  for clz in clzs:
272
272
  for line in inspect.getsource(clz).splitlines():
273
- reached_functions = re.search("def ", line)
273
+ reached_functions = re.search(r"def ", line)
274
274
  if reached_functions:
275
275
  # We've reached the functions, so stop.
276
276
  break
@@ -288,7 +288,7 @@ def _generate_docstrings(clzs: list[type[Component]], props: list[str]) -> str:
288
288
  continue
289
289
 
290
290
  # Check if this line has a prop.
291
- match = re.search("\\w+:", line)
291
+ match = re.search(r"\w+:", line)
292
292
  if match is None:
293
293
  # This line doesn't have a var, so continue.
294
294
  continue
@@ -307,9 +307,9 @@ def _generate_docstrings(clzs: list[type[Component]], props: list[str]) -> str:
307
307
  for line in (clz.create.__doc__ or "").splitlines():
308
308
  if "**" in line:
309
309
  indent = line.split("**")[0]
310
- new_docstring.extend(
311
- [f"{indent}{n}:{' '.join(c)}" for n, c in props_comments.items()]
312
- )
310
+ new_docstring.extend([
311
+ f"{indent}{n}:{' '.join(c)}" for n, c in props_comments.items()
312
+ ])
313
313
  new_docstring.append(line)
314
314
  return "\n".join(new_docstring)
315
315
 
@@ -394,23 +394,21 @@ def _extract_class_props_as_ast_nodes(
394
394
  for module in modules:
395
395
  available_vars.update(sys.modules[module].__dict__)
396
396
 
397
- kwargs.append(
398
- (
399
- ast.arg(
400
- arg=name,
401
- annotation=ast.Name(
402
- id=OVERWRITE_TYPES.get(
403
- name,
404
- _get_type_hint(
405
- value,
406
- type_hint_globals | available_vars,
407
- ),
408
- )
409
- ),
397
+ kwargs.append((
398
+ ast.arg(
399
+ arg=name,
400
+ annotation=ast.Name(
401
+ id=OVERWRITE_TYPES.get(
402
+ name,
403
+ _get_type_hint(
404
+ value,
405
+ type_hint_globals | available_vars,
406
+ ),
407
+ )
410
408
  ),
411
- ast.Constant(value=default), # pyright: ignore [reportArgumentType]
412
- )
413
- )
409
+ ),
410
+ ast.Constant(value=default), # pyright: ignore [reportArgumentType]
411
+ ))
414
412
  return kwargs
415
413
 
416
414
 
@@ -489,7 +487,7 @@ def type_to_ast(typ: Any, cls: type) -> ast.expr:
489
487
 
490
488
 
491
489
  def _get_parent_imports(func: Callable):
492
- _imports = {"reflex.vars": ["Var"]}
490
+ imports_ = {"reflex.vars": ["Var"]}
493
491
  for type_hint in inspect.get_annotations(func).values():
494
492
  try:
495
493
  match = re.match(r"\w+\[([\w\d]+)\]", type_hint)
@@ -498,8 +496,8 @@ def _get_parent_imports(func: Callable):
498
496
  if match:
499
497
  type_hint = match.group(1)
500
498
  if type_hint in importlib.import_module(func.__module__).__dir__():
501
- _imports.setdefault(func.__module__, []).append(type_hint)
502
- return _imports
499
+ imports_.setdefault(func.__module__, []).append(type_hint)
500
+ return imports_
503
501
 
504
502
 
505
503
  def _generate_component_create_functiondef(
@@ -527,13 +525,13 @@ def _generate_component_create_functiondef(
527
525
  raise TypeError(msg)
528
526
 
529
527
  # add the imports needed by get_type_hint later
530
- type_hint_globals.update(
531
- {name: getattr(typing, name) for name in DEFAULT_TYPING_IMPORTS}
532
- )
528
+ type_hint_globals.update({
529
+ name: getattr(typing, name) for name in DEFAULT_TYPING_IMPORTS
530
+ })
533
531
 
534
532
  if clz.__module__ != clz.create.__module__:
535
- _imports = _get_parent_imports(clz.create)
536
- for name, values in _imports.items():
533
+ imports_ = _get_parent_imports(clz.create)
534
+ for name, values in imports_.items():
537
535
  exec(f"from {name} import {','.join(values)}", type_hint_globals)
538
536
 
539
537
  kwargs = _extract_func_kwargs_as_ast_nodes(clz.create, type_hint_globals)
@@ -637,16 +635,12 @@ def _generate_component_create_functiondef(
637
635
  )
638
636
  else ast.Subscript(
639
637
  ast.Name("Union"),
640
- ast.Tuple(
641
- [
642
- figure_out_return_type(
643
- inspect.signature(
644
- event_spec
645
- ).return_annotation
646
- )
647
- for event_spec in event_specs
648
- ]
649
- ),
638
+ ast.Tuple([
639
+ figure_out_return_type(
640
+ inspect.signature(event_spec).return_annotation
641
+ )
642
+ for event_spec in event_specs
643
+ ]),
650
644
  )
651
645
  )
652
646
  ),
@@ -759,9 +753,9 @@ def _generate_namespace_call_functiondef(
759
753
  The create functiondef node for the ast.
760
754
  """
761
755
  # add the imports needed by get_type_hint later
762
- type_hint_globals.update(
763
- {name: getattr(typing, name) for name in DEFAULT_TYPING_IMPORTS}
764
- )
756
+ type_hint_globals.update({
757
+ name: getattr(typing, name) for name in DEFAULT_TYPING_IMPORTS
758
+ })
765
759
 
766
760
  clz = classes[clz_name]
767
761
 
@@ -1093,15 +1087,13 @@ class PyiGenerator:
1093
1087
  def _write_pyi_file(self, module_path: Path, source: str) -> str:
1094
1088
  relpath = str(_relative_to_pwd(module_path)).replace("\\", "/")
1095
1089
  pyi_content = (
1096
- "\n".join(
1097
- [
1098
- f'"""Stub file for {relpath}"""',
1099
- "# ------------------- DO NOT EDIT ----------------------",
1100
- "# This file was generated by `reflex/utils/pyi_generator.py`!",
1101
- "# ------------------------------------------------------",
1102
- "",
1103
- ]
1104
- )
1090
+ "\n".join([
1091
+ f'"""Stub file for {relpath}"""',
1092
+ "# ------------------- DO NOT EDIT ----------------------",
1093
+ "# This file was generated by `reflex/utils/pyi_generator.py`!",
1094
+ "# ------------------------------------------------------",
1095
+ "",
1096
+ ])
1105
1097
  + source
1106
1098
  )
1107
1099
 
@@ -1159,9 +1151,11 @@ class PyiGenerator:
1159
1151
 
1160
1152
  text = (
1161
1153
  "\n"
1162
- + "\n".join(
1163
- [*sub_mods_imports, *sub_mod_attrs_imports, *extra_mappings_imports]
1164
- )
1154
+ + "\n".join([
1155
+ *sub_mods_imports,
1156
+ *sub_mod_attrs_imports,
1157
+ *extra_mappings_imports,
1158
+ ])
1165
1159
  + "\n"
1166
1160
  )
1167
1161
  text += ast.unparse(new_tree) + "\n\n"
@@ -137,7 +137,7 @@ def serialize(value: Any) -> SerializedType | None: ...
137
137
 
138
138
  def serialize(
139
139
  value: Any, get_type: bool = False
140
- ) -> SerializedType | None | tuple[SerializedType | None, types.GenericType | None]:
140
+ ) -> SerializedType | tuple[SerializedType | None, types.GenericType | None] | None:
141
141
  """Serialize the value to a JSON string.
142
142
 
143
143
  Args:
reflex/utils/telemetry.py CHANGED
@@ -346,7 +346,7 @@ def send(event: str, telemetry_enabled: bool | None = None, **kwargs):
346
346
  kwargs: Additional data to send with the event.
347
347
  """
348
348
 
349
- async def async_send(event: str, telemetry_enabled: bool | None, **kwargs):
349
+ async def async_send(event: str, telemetry_enabled: bool | None, **kwargs): # noqa: RUF029
350
350
  return _send(event, telemetry_enabled, **kwargs)
351
351
 
352
352
  try:
reflex/utils/templates.py CHANGED
@@ -285,9 +285,9 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
285
285
  if tp["hidden"] or tp["code_url"] is None:
286
286
  continue
287
287
  known_fields = {f.name for f in dataclasses.fields(Template)}
288
- filtered_templates[tp["name"]] = Template(
289
- **{k: v for k, v in tp.items() if k in known_fields}
290
- )
288
+ filtered_templates[tp["name"]] = Template(**{
289
+ k: v for k, v in tp.items() if k in known_fields
290
+ })
291
291
  return filtered_templates
292
292
 
293
293
 
@@ -383,7 +383,7 @@ def initialize_app(app_name: str, template: str | None = None) -> str | None:
383
383
  templates: dict[str, Template] = {}
384
384
 
385
385
  # Don't fetch app templates if the user directly asked for DEFAULT.
386
- if template is not None and (template not in (constants.Templates.DEFAULT,)):
386
+ if template is not None and template != constants.Templates.DEFAULT:
387
387
  template, templates = fetch_remote_templates(template)
388
388
 
389
389
  if template is None:
reflex/utils/types.py CHANGED
@@ -443,6 +443,13 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
443
443
 
444
444
  from reflex.model import Model
445
445
 
446
+ if find_spec("sqlmodel"):
447
+ from sqlmodel import SQLModel
448
+
449
+ sqlmodel_types = (Model, SQLModel)
450
+ else:
451
+ sqlmodel_types = (Model,)
452
+
446
453
  if isinstance(cls, type) and issubclass(cls, DeclarativeBase):
447
454
  insp = sqlalchemy.inspect(cls)
448
455
  if name in insp.columns:
@@ -486,7 +493,7 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
486
493
  elif (
487
494
  isinstance(cls, type)
488
495
  and not is_generic_alias(cls)
489
- and issubclass(cls, Model)
496
+ and issubclass(cls, sqlmodel_types)
490
497
  ):
491
498
  # Check in the annotations directly (for sqlmodel.Relationship)
492
499
  hints = get_type_hints(cls) # pyright: ignore [reportArgumentType]
@@ -984,9 +991,9 @@ def validate_literal(key: str, value: Any, expected_type: type, comp_name: str):
984
991
  ):
985
992
  allowed_values = expected_type.__args__
986
993
  if value not in allowed_values:
987
- allowed_value_str = ",".join(
988
- [str(v) if not isinstance(v, str) else f"'{v}'" for v in allowed_values]
989
- )
994
+ allowed_value_str = ",".join([
995
+ str(v) if not isinstance(v, str) else f"'{v}'" for v in allowed_values
996
+ ])
990
997
  value_str = f"'{value}'" if isinstance(value, str) else value
991
998
  msg = f"prop value for {key!s} of the `{comp_name}` component should be one of the following: {allowed_value_str}. Got {value_str} instead"
992
999
  raise ValueError(msg)
reflex/vars/base.py CHANGED
@@ -233,7 +233,7 @@ class VarData:
233
233
  hook: None for var_data in all_var_datas for hook in var_data.hooks
234
234
  }
235
235
 
236
- _imports = imports.merge_imports(
236
+ imports_ = imports.merge_imports(
237
237
  *(var_data.imports for var_data in all_var_datas)
238
238
  )
239
239
 
@@ -261,7 +261,7 @@ class VarData:
261
261
  return VarData(
262
262
  state=state,
263
263
  field_name=field_name,
264
- imports=_imports,
264
+ imports=imports_,
265
265
  hooks=hooks,
266
266
  deps=deps,
267
267
  position=position,
@@ -488,13 +488,13 @@ class Var(Generic[VAR_TYPE], metaclass=MetaclassVar):
488
488
  raise TypeError(msg)
489
489
 
490
490
  # Decode any inline Var markup and apply it to the instance
491
- _var_data, _js_expr = _decode_var_immutable(self._js_expr)
491
+ var_data_, js_expr_ = _decode_var_immutable(self._js_expr)
492
492
 
493
- if _var_data or _js_expr != self._js_expr:
493
+ if var_data_ or js_expr_ != self._js_expr:
494
494
  self.__init__(
495
- _js_expr=_js_expr,
495
+ _js_expr=js_expr_,
496
496
  _var_type=self._var_type,
497
- _var_data=VarData.merge(self._var_data, _var_data),
497
+ _var_data=VarData.merge(self._var_data, var_data_),
498
498
  )
499
499
 
500
500
  def __hash__(self) -> int:
@@ -1590,12 +1590,10 @@ class LiteralVar(Var):
1590
1590
  )
1591
1591
 
1592
1592
  if dataclasses.is_dataclass(value) and not isinstance(value, type):
1593
- return LiteralObjectVar._get_all_var_data_without_creating_var(
1594
- {
1595
- k: (None if callable(v) else v)
1596
- for k, v in dataclasses.asdict(value).items()
1597
- }
1598
- )
1593
+ return LiteralObjectVar._get_all_var_data_without_creating_var({
1594
+ k: (None if callable(v) else v)
1595
+ for k, v in dataclasses.asdict(value).items()
1596
+ })
1599
1597
 
1600
1598
  if isinstance(value, range):
1601
1599
  return None
@@ -1949,16 +1947,14 @@ class CachedVarOperation:
1949
1947
  Returns:
1950
1948
  The hash of the object.
1951
1949
  """
1952
- return hash(
1953
- (
1954
- type(self).__name__,
1955
- *[
1956
- getattr(self, field.name)
1957
- for field in dataclasses.fields(self)
1958
- if field.name not in ["_js_expr", "_var_data", "_var_type"]
1959
- ],
1960
- )
1961
- )
1950
+ return hash((
1951
+ type(self).__name__,
1952
+ *[
1953
+ getattr(self, field.name)
1954
+ for field in dataclasses.fields(self)
1955
+ if field.name not in ["_js_expr", "_var_data", "_var_type"]
1956
+ ],
1957
+ ))
1962
1958
 
1963
1959
 
1964
1960
  def and_operation(
@@ -2171,11 +2167,11 @@ class ComputedVar(Var[RETURN_TYPE]):
2171
2167
  if isinstance(deps, dict):
2172
2168
  # Assume a dict is coming from _replace, so no special processing.
2173
2169
  return deps
2174
- _static_deps = {}
2170
+ static_deps = {}
2175
2171
  if deps is not None:
2176
2172
  for dep in deps:
2177
- _static_deps = self._add_static_dep(dep, _static_deps)
2178
- return _static_deps
2173
+ static_deps = self._add_static_dep(dep, static_deps)
2174
+ return static_deps
2179
2175
 
2180
2176
  def _add_static_dep(
2181
2177
  self, dep: str | Var, deps: dict[str | None, set[str]] | None = None
@@ -2494,9 +2490,10 @@ class ComputedVar(Var[RETURN_TYPE]):
2494
2490
  self._static_deps.setdefault(state_name, set()).add(var_name)
2495
2491
  objclass.get_root_state().get_class_substate(
2496
2492
  state_name
2497
- )._var_dependencies.setdefault(var_name, set()).add(
2498
- (objclass.get_full_name(), self._name)
2499
- )
2493
+ )._var_dependencies.setdefault(var_name, set()).add((
2494
+ objclass.get_full_name(),
2495
+ self._name,
2496
+ ))
2500
2497
  return
2501
2498
  msg = (
2502
2499
  "ComputedVar dependencies must be Var instances with a state and "
@@ -2538,7 +2535,7 @@ class DynamicRouteVar(ComputedVar[str | list[str]]):
2538
2535
  """A ComputedVar that represents a dynamic route."""
2539
2536
 
2540
2537
 
2541
- async def _default_async_computed_var(_self: BaseState) -> Any:
2538
+ async def _default_async_computed_var(_self: BaseState) -> Any: # noqa: RUF029
2542
2539
  return None
2543
2540
 
2544
2541
 
reflex/vars/color.py CHANGED
@@ -76,14 +76,12 @@ class LiteralColorVar(CachedVarOperation, LiteralVar, ColorVar):
76
76
  Returns:
77
77
  The hash of the var.
78
78
  """
79
- return hash(
80
- (
81
- self.__class__.__name__,
82
- self._var_value.color,
83
- self._var_value.alpha,
84
- self._var_value.shade,
85
- )
86
- )
79
+ return hash((
80
+ self.__class__.__name__,
81
+ self._var_value.color,
82
+ self._var_value.alpha,
83
+ self._var_value.shade,
84
+ ))
87
85
 
88
86
  @cached_property_no_lock
89
87
  def _cached_var_name(self) -> str:
@@ -255,9 +255,11 @@ class DependencyTracker:
255
255
  source = inspect.getsource(module).splitlines(True)[start_line - 1 : end_line]
256
256
  # Create a python source string snippet.
257
257
  if len(source) > 1:
258
- snipped_source = "".join(
259
- [*source[0][start_column:], *source[1:-1], *source[-1][:end_column]]
260
- )
258
+ snipped_source = "".join([
259
+ *source[0][start_column:],
260
+ *source[1:-1],
261
+ *source[-1][:end_column],
262
+ ])
261
263
  else:
262
264
  snipped_source = source[0][start_column:end_column]
263
265
  # Evaluate the string in the context of the function's globals and closure.
reflex/vars/function.py CHANGED
@@ -331,9 +331,9 @@ def format_args_function_operation(
331
331
  Returns:
332
332
  The formatted args function operation.
333
333
  """
334
- arg_names_str = ", ".join(
335
- [arg if isinstance(arg, str) else arg.to_javascript() for arg in args.args]
336
- ) + (f", ...{args.rest}" if args.rest else "")
334
+ arg_names_str = ", ".join([
335
+ arg if isinstance(arg, str) else arg.to_javascript() for arg in args.args
336
+ ]) + (f", ...{args.rest}" if args.rest else "")
337
337
 
338
338
  return_expr_str = str(LiteralVar.create(return_expr))
339
339
 
reflex/vars/object.py CHANGED
@@ -56,13 +56,11 @@ def _determine_value_type(var_type: GenericType):
56
56
  origin_var_type = get_origin(var_type) or var_type
57
57
 
58
58
  if origin_var_type in types.UnionTypes:
59
- return unionize(
60
- *[
61
- _determine_value_type(arg)
62
- for arg in get_args(var_type)
63
- if arg is not type(None)
64
- ]
65
- )
59
+ return unionize(*[
60
+ _determine_value_type(arg)
61
+ for arg in get_args(var_type)
62
+ if arg is not type(None)
63
+ ])
66
64
 
67
65
  if is_typeddict(origin_var_type) or dataclasses.is_dataclass(origin_var_type):
68
66
  annotations = get_type_hints(origin_var_type)
@@ -401,12 +399,10 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
401
399
  """
402
400
  return (
403
401
  "({ "
404
- + ", ".join(
405
- [
406
- f"[{LiteralVar.create(key)!s}] : {LiteralVar.create(value)!s}"
407
- for key, value in self._var_value.items()
408
- ]
409
- )
402
+ + ", ".join([
403
+ f"[{LiteralVar.create(key)!s}] : {LiteralVar.create(value)!s}"
404
+ for key, value in self._var_value.items()
405
+ ])
410
406
  + " })"
411
407
  )
412
408