reflex 0.7.5a1__py3-none-any.whl → 0.7.6a0__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.

@@ -1,16 +1,32 @@
1
- """Module to implement lazy loading in reflex."""
1
+ """Module to implement lazy loading in reflex.
2
+
3
+ BSD 3-Clause License
4
+
5
+ Copyright (c) 2022--2023, Scientific Python project All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8
+
9
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10
+
11
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
12
+
13
+ Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
+ """
2
17
 
3
18
  from __future__ import annotations
4
19
 
5
20
  import copy
6
-
7
- import lazy_loader as lazy
21
+ import importlib
22
+ import os
23
+ import sys
8
24
 
9
25
 
10
26
  def attach(
11
27
  package_name: str,
12
- submodules: set | None = None,
13
- submod_attrs: dict | None = None,
28
+ submodules: set[str] | None = None,
29
+ submod_attrs: dict[str, list[str]] | None = None,
14
30
  ):
15
31
  """Replaces a package's __getattr__, __dir__, and __all__ attributes using lazy.attach.
16
32
  The lazy loader __getattr__ doesn't support tuples as list values. We needed to add
@@ -27,14 +43,49 @@ def attach(
27
43
  Returns:
28
44
  __getattr__, __dir__, __all__
29
45
  """
30
- _submod_attrs = copy.deepcopy(submod_attrs)
31
- if _submod_attrs:
32
- for k, v in _submod_attrs.items():
46
+ submod_attrs = copy.deepcopy(submod_attrs)
47
+ if submod_attrs:
48
+ for k, v in submod_attrs.items():
33
49
  # when flattening the list, only keep the alias in the tuple(mod[1])
34
- _submod_attrs[k] = [
50
+ submod_attrs[k] = [
35
51
  mod if not isinstance(mod, tuple) else mod[1] for mod in v
36
52
  ]
37
53
 
38
- return lazy.attach(
39
- package_name=package_name, submodules=submodules, submod_attrs=_submod_attrs
40
- )
54
+ if submod_attrs is None:
55
+ submod_attrs = {}
56
+
57
+ submodules = set(submodules) if submodules is not None else set()
58
+
59
+ attr_to_modules = {
60
+ attr: mod for mod, attrs in submod_attrs.items() for attr in attrs
61
+ }
62
+
63
+ __all__ = sorted(submodules | attr_to_modules.keys())
64
+
65
+ def __getattr__(name: str): # noqa: N807
66
+ if name in submodules:
67
+ return importlib.import_module(f"{package_name}.{name}")
68
+ elif name in attr_to_modules:
69
+ submod_path = f"{package_name}.{attr_to_modules[name]}"
70
+ submod = importlib.import_module(submod_path)
71
+ attr = getattr(submod, name)
72
+
73
+ # If the attribute lives in a file (module) with the same
74
+ # name as the attribute, ensure that the attribute and *not*
75
+ # the module is accessible on the package.
76
+ if name == attr_to_modules[name]:
77
+ pkg = sys.modules[package_name]
78
+ pkg.__dict__[name] = attr
79
+
80
+ return attr
81
+ else:
82
+ raise AttributeError(f"No {package_name} attribute {name}")
83
+
84
+ def __dir__(): # noqa: N807
85
+ return __all__
86
+
87
+ if os.environ.get("EAGER_IMPORT", ""):
88
+ for attr in set(attr_to_modules.keys()) | submodules:
89
+ __getattr__(attr)
90
+
91
+ return __getattr__, __dir__, list(__all__)
@@ -254,7 +254,7 @@ def get_nodejs_compatible_package_managers(
254
254
 
255
255
  package_managers = list(filter(None, package_managers))
256
256
 
257
- if not package_managers and not raise_on_none:
257
+ if not package_managers and raise_on_none:
258
258
  raise FileNotFoundError(
259
259
  "Bun or npm not found. You might need to rerun `reflex init` or install either."
260
260
  )
@@ -831,44 +831,48 @@ def initialize_gitignore(
831
831
  gitignore_file.write_text("\n".join(files_to_ignore) + "\n")
832
832
 
833
833
 
834
- def initialize_requirements_txt():
834
+ def initialize_requirements_txt() -> bool:
835
835
  """Initialize the requirements.txt file.
836
836
  If absent, generate one for the user.
837
837
  If the requirements.txt does not have reflex as dependency,
838
838
  generate a requirement pinning current version and append to
839
839
  the requirements.txt file.
840
+
841
+ Returns:
842
+ True if the requirements.txt file was created or updated, False otherwise.
843
+
844
+ Raises:
845
+ Exit: If the requirements.txt file cannot be read or written to.
840
846
  """
841
- fp = Path(constants.RequirementsTxt.FILE)
842
- encoding = "utf-8"
843
- if not fp.exists():
844
- fp.touch()
847
+ requirements_file_path = Path(constants.RequirementsTxt.FILE)
848
+ requirements_file_path.touch(exist_ok=True)
849
+
850
+ for encoding in [None, "utf-8"]:
851
+ try:
852
+ content = requirements_file_path.read_text(encoding)
853
+ break
854
+ except UnicodeDecodeError:
855
+ continue
856
+ except Exception as e:
857
+ console.error(f"Failed to read {requirements_file_path}.")
858
+ raise typer.Exit(1) from e
845
859
  else:
846
- # Detect the encoding of the original file
847
- import charset_normalizer
860
+ return False
848
861
 
849
- charset_matches = charset_normalizer.from_path(fp)
850
- maybe_charset_match = charset_matches.best()
851
- if maybe_charset_match is None:
852
- console.debug(f"Unable to detect encoding for {fp}, exiting.")
853
- return
854
- encoding = maybe_charset_match.encoding
855
- console.debug(f"Detected encoding for {fp} as {encoding}.")
856
- try:
857
- other_requirements_exist = False
858
- with fp.open("r", encoding=encoding) as f:
859
- for req in f:
860
- # Check if we have a package name that is reflex
861
- if re.match(r"^reflex[^a-zA-Z0-9]", req):
862
- console.debug(f"{fp} already has reflex as dependency.")
863
- return
864
- other_requirements_exist = True
865
- with fp.open("a", encoding=encoding) as f:
866
- preceding_newline = "\n" if other_requirements_exist else ""
867
- f.write(
868
- f"{preceding_newline}{constants.RequirementsTxt.DEFAULTS_STUB}{constants.Reflex.VERSION}\n"
869
- )
870
- except Exception:
871
- console.info(f"Unable to check {fp} for reflex dependency.")
862
+ for line in content.splitlines():
863
+ if re.match(r"^reflex[^a-zA-Z0-9]", line):
864
+ console.debug(f"{requirements_file_path} already has reflex as dependency.")
865
+ return True
866
+
867
+ console.debug(
868
+ f"Appending {constants.RequirementsTxt.DEFAULTS_STUB} to {requirements_file_path}"
869
+ )
870
+ with requirements_file_path.open("a", encoding=encoding) as f:
871
+ f.write(
872
+ "\n" + constants.RequirementsTxt.DEFAULTS_STUB + constants.Reflex.VERSION
873
+ )
874
+
875
+ return True
872
876
 
873
877
 
874
878
  def initialize_app_directory(
@@ -1087,8 +1091,10 @@ def _update_next_config(
1087
1091
  "compress": config.next_compression,
1088
1092
  "trailingSlash": True,
1089
1093
  "staticPageGenerationTimeout": config.static_page_generation_timeout,
1090
- "devIndicators": config.next_dev_indicators,
1091
1094
  }
1095
+ if not config.next_dev_indicators:
1096
+ next_config["devIndicators"] = False
1097
+
1092
1098
  if transpile_packages:
1093
1099
  next_config["transpilePackages"] = list(
1094
1100
  {format_library_name(p) for p in transpile_packages}
@@ -1409,7 +1415,7 @@ def validate_bun():
1409
1415
  raise typer.Exit(1)
1410
1416
  elif bun_version < version.parse(constants.Bun.MIN_VERSION):
1411
1417
  console.error(
1412
- f"Reflex requires bun version {constants.Bun.VERSION} or higher to run, but the detected version is "
1418
+ f"Reflex requires bun version {constants.Bun.MIN_VERSION} or higher to run, but the detected version is "
1413
1419
  f"{bun_version}. If you have specified a custom bun path in your config, make sure to provide one "
1414
1420
  f"that satisfies the minimum version requirement."
1415
1421
  )
reflex/utils/processes.py CHANGED
@@ -294,6 +294,7 @@ def stream_logs(
294
294
 
295
295
  Raises:
296
296
  Exit: If the process failed.
297
+ ValueError: If the process stdout pipe is closed, but the process remains running.
297
298
  """
298
299
  from reflex.utils import telemetry
299
300
 
@@ -303,10 +304,18 @@ def stream_logs(
303
304
  console.debug(message, progress=progress)
304
305
  if process.stdout is None:
305
306
  return
306
- for line in process.stdout:
307
- console.debug(line, end="", progress=progress)
308
- logs.append(line)
309
- yield line
307
+ try:
308
+ for line in process.stdout:
309
+ console.debug(line, end="", progress=progress)
310
+ logs.append(line)
311
+ yield line
312
+ except ValueError:
313
+ # The stream we were reading has been closed,
314
+ if process.poll() is None:
315
+ # But if the process is still running that is weird.
316
+ raise
317
+ # If the process exited, break out of the loop for post processing.
318
+ pass
310
319
 
311
320
  # Check if the process failed (not printing the logs for SIGINT).
312
321
 
@@ -6,11 +6,13 @@ import ast
6
6
  import contextlib
7
7
  import importlib
8
8
  import inspect
9
+ import json
9
10
  import logging
10
11
  import re
11
12
  import subprocess
12
13
  import typing
13
14
  from fileinput import FileInput
15
+ from hashlib import md5
14
16
  from inspect import getfullargspec
15
17
  from itertools import chain
16
18
  from multiprocessing import Pool, cpu_count
@@ -1058,9 +1060,9 @@ class PyiGenerator:
1058
1060
  modules: list = []
1059
1061
  root: str = ""
1060
1062
  current_module: Any = {}
1061
- written_files: list[str] = []
1063
+ written_files: list[tuple[str, str]] = []
1062
1064
 
1063
- def _write_pyi_file(self, module_path: Path, source: str):
1065
+ def _write_pyi_file(self, module_path: Path, source: str) -> str:
1064
1066
  relpath = str(_relative_to_pwd(module_path)).replace("\\", "/")
1065
1067
  pyi_content = (
1066
1068
  "\n".join(
@@ -1078,6 +1080,7 @@ class PyiGenerator:
1078
1080
  pyi_path = module_path.with_suffix(".pyi")
1079
1081
  pyi_path.write_text(pyi_content)
1080
1082
  logger.info(f"Wrote {relpath}")
1083
+ return md5(pyi_content.encode()).hexdigest()
1081
1084
 
1082
1085
  def _get_init_lazy_imports(self, mod: tuple | ModuleType, new_tree: ast.AST):
1083
1086
  # retrieve the _SUBMODULES and _SUBMOD_ATTRS from an init file if present.
@@ -1118,7 +1121,7 @@ class PyiGenerator:
1118
1121
  text += ast.unparse(new_tree) + "\n"
1119
1122
  return text
1120
1123
 
1121
- def _scan_file(self, module_path: Path) -> str | None:
1124
+ def _scan_file(self, module_path: Path) -> tuple[str, str] | None:
1122
1125
  module_import = (
1123
1126
  _relative_to_pwd(module_path)
1124
1127
  .with_suffix("")
@@ -1132,7 +1135,10 @@ class PyiGenerator:
1132
1135
  name: obj
1133
1136
  for name, obj in vars(module).items()
1134
1137
  if inspect.isclass(obj)
1135
- and (issubclass(obj, Component) or issubclass(obj, SimpleNamespace))
1138
+ and (
1139
+ rx_types.safe_issubclass(obj, Component)
1140
+ or rx_types.safe_issubclass(obj, SimpleNamespace)
1141
+ )
1136
1142
  and obj != Component
1137
1143
  and inspect.getmodule(obj) == module
1138
1144
  }
@@ -1147,13 +1153,13 @@ class PyiGenerator:
1147
1153
  init_imports = self._get_init_lazy_imports(module, new_tree)
1148
1154
  if not init_imports:
1149
1155
  return
1150
- self._write_pyi_file(module_path, init_imports)
1156
+ content_hash = self._write_pyi_file(module_path, init_imports)
1151
1157
  else:
1152
1158
  new_tree = StubGenerator(module, class_names).visit(
1153
1159
  ast.parse(inspect.getsource(module))
1154
1160
  )
1155
- self._write_pyi_file(module_path, ast.unparse(new_tree))
1156
- return str(module_path.with_suffix(".pyi").resolve())
1161
+ content_hash = self._write_pyi_file(module_path, ast.unparse(new_tree))
1162
+ return str(module_path.with_suffix(".pyi").resolve()), content_hash
1157
1163
 
1158
1164
  def _scan_files_multiprocess(self, files: list[Path]):
1159
1165
  with Pool(processes=cpu_count()) as pool:
@@ -1165,12 +1171,18 @@ class PyiGenerator:
1165
1171
  if pyi_path:
1166
1172
  self.written_files.append(pyi_path)
1167
1173
 
1168
- def scan_all(self, targets: list, changed_files: list[Path] | None = None):
1174
+ def scan_all(
1175
+ self,
1176
+ targets: list,
1177
+ changed_files: list[Path] | None = None,
1178
+ use_json: bool = False,
1179
+ ):
1169
1180
  """Scan all targets for class inheriting Component and generate the .pyi files.
1170
1181
 
1171
1182
  Args:
1172
1183
  targets: the list of file/folders to scan.
1173
1184
  changed_files (optional): the list of changed files since the last run.
1185
+ use_json: whether to use json to store the hashes.
1174
1186
  """
1175
1187
  file_targets = []
1176
1188
  for target in targets:
@@ -1212,17 +1224,76 @@ class PyiGenerator:
1212
1224
  else:
1213
1225
  self._scan_files_multiprocess(file_targets)
1214
1226
 
1227
+ file_paths, hashes = (
1228
+ [f[0] for f in self.written_files],
1229
+ [f[1] for f in self.written_files],
1230
+ )
1231
+
1215
1232
  # Fix generated pyi files with ruff.
1216
- if self.written_files:
1217
- subprocess.run(["ruff", "format", *self.written_files])
1218
- subprocess.run(["ruff", "check", "--fix", *self.written_files])
1233
+ if file_paths:
1234
+ subprocess.run(["ruff", "format", *file_paths])
1235
+ subprocess.run(["ruff", "check", "--fix", *file_paths])
1219
1236
 
1220
1237
  # For some reason, we need to format the __init__.pyi files again after fixing...
1221
- init_files = [f for f in self.written_files if "/__init__.pyi" in f]
1238
+ init_files = [f for f in file_paths if "/__init__.pyi" in f]
1222
1239
  subprocess.run(["ruff", "format", *init_files])
1223
1240
 
1241
+ if use_json:
1242
+ if file_paths and changed_files is None:
1243
+ file_paths = list(map(Path, file_paths))
1244
+ top_dir = file_paths[0].parent
1245
+ for file_path in file_paths:
1246
+ file_parent = file_path.parent
1247
+ while len(file_parent.parts) > len(top_dir.parts):
1248
+ file_parent = file_parent.parent
1249
+ while not file_parent.samefile(top_dir):
1250
+ file_parent = file_parent.parent
1251
+ top_dir = top_dir.parent
1252
+
1253
+ (top_dir.parent / "pyi_hashes.json").write_text(
1254
+ json.dumps(
1255
+ dict(
1256
+ zip(
1257
+ [
1258
+ str(f.relative_to(top_dir.parent))
1259
+ for f in file_paths
1260
+ ],
1261
+ hashes,
1262
+ strict=True,
1263
+ )
1264
+ ),
1265
+ indent=2,
1266
+ sort_keys=True,
1267
+ )
1268
+ + "\n",
1269
+ )
1270
+ elif file_paths:
1271
+ file_paths = list(map(Path, file_paths))
1272
+ pyi_hashes_parent = file_paths[0].parent
1273
+ while (
1274
+ not any(
1275
+ subfile.name == "pyi_hashes.json"
1276
+ for subfile in pyi_hashes_parent.iterdir()
1277
+ )
1278
+ and pyi_hashes_parent.parent
1279
+ ):
1280
+ pyi_hashes_parent = pyi_hashes_parent.parent
1281
+
1282
+ pyi_hashes_file = pyi_hashes_parent / "pyi_hashes.json"
1283
+ if pyi_hashes_file.exists():
1284
+ pyi_hashes = json.loads(pyi_hashes_file.read_text())
1285
+ for file_path, hashed_content in zip(
1286
+ file_paths, hashes, strict=False
1287
+ ):
1288
+ pyi_hashes[str(file_path.relative_to(pyi_hashes_parent))] = (
1289
+ hashed_content
1290
+ )
1291
+ pyi_hashes_file.write_text(
1292
+ json.dumps(pyi_hashes, indent=2, sort_keys=True) + "\n"
1293
+ )
1294
+
1224
1295
  # Post-process the generated pyi files to add hacky type: ignore comments
1225
- for file_path in self.written_files:
1296
+ for file_path in file_paths:
1226
1297
  with FileInput(file_path, inplace=True) as f:
1227
1298
  for line in f:
1228
1299
  # Hack due to ast not supporting comments in the tree.
@@ -1233,3 +1304,15 @@ class PyiGenerator:
1233
1304
  ):
1234
1305
  line = line.rstrip() + " # type: ignore\n"
1235
1306
  print(line, end="") # noqa: T201
1307
+
1308
+
1309
+ if __name__ == "__main__":
1310
+ logging.basicConfig(level=logging.INFO)
1311
+ logging.getLogger("blib2to3.pgen2.driver").setLevel(logging.INFO)
1312
+
1313
+ gen = PyiGenerator()
1314
+ gen.scan_all(
1315
+ ["reflex/components", "reflex/experimental", "reflex/__init__.py"],
1316
+ None,
1317
+ use_json=True,
1318
+ )
reflex/utils/types.py CHANGED
@@ -607,7 +607,7 @@ def _isinstance(
607
607
  if cls is None or cls is type(None):
608
608
  return obj is None
609
609
 
610
- if cls and is_union(cls):
610
+ if cls is not None and is_union(cls):
611
611
  return any(
612
612
  _isinstance(obj, arg, nested=nested, treat_var_as_type=treat_var_as_type)
613
613
  for arg in get_args(cls)
@@ -643,6 +643,16 @@ def _isinstance(
643
643
  # cls is a simple generic class
644
644
  return isinstance(obj, origin)
645
645
 
646
+ if origin is Var and args:
647
+ # cls is a Var
648
+ return _isinstance(
649
+ obj,
650
+ args[0],
651
+ nested=nested,
652
+ treat_var_as_type=treat_var_as_type,
653
+ treat_mutable_obj_as_immutable=treat_mutable_obj_as_immutable,
654
+ )
655
+
646
656
  if nested > 0 and args:
647
657
  if origin is list:
648
658
  expected_class = Sequence if treat_mutable_obj_as_immutable else list
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reflex
3
- Version: 0.7.5a1
3
+ Version: 0.7.6a0
4
4
  Summary: Web apps in pure Python.
5
5
  Project-URL: homepage, https://reflex.dev
6
6
  Project-URL: repository, https://github.com/reflex-dev/reflex
@@ -19,34 +19,25 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Requires-Python: <4.0,>=3.10
21
21
  Requires-Dist: alembic<2.0,>=1.11.1
22
- Requires-Dist: build<2.0,>=1.0.3
23
- Requires-Dist: charset-normalizer<4.0,>=3.3.2
24
22
  Requires-Dist: distro<2.0,>=1.8.0; platform_system == 'Linux'
25
23
  Requires-Dist: fastapi!=0.111.0,!=0.111.1,>=0.96.0
26
24
  Requires-Dist: granian[reload]>=2.2.0
27
25
  Requires-Dist: gunicorn<24.0.0,>=23.0.0
28
26
  Requires-Dist: httpx<1.0,>=0.25.1
29
27
  Requires-Dist: jinja2<4.0,>=3.1.2
30
- Requires-Dist: lazy-loader>=0.4
31
28
  Requires-Dist: packaging<25.0,>=23.1
32
29
  Requires-Dist: platformdirs<5.0,>=3.10.0
33
30
  Requires-Dist: psutil<8.0,>=5.9.4
34
31
  Requires-Dist: pydantic<3.0,>=1.10.21
35
- Requires-Dist: python-engineio!=4.6.0
36
- Requires-Dist: python-multipart<0.1,>=0.0.5
32
+ Requires-Dist: python-multipart<1.0,>=0.0.20
37
33
  Requires-Dist: python-socketio<6.0,>=5.7.0
38
34
  Requires-Dist: redis<6.0,>=4.3.5
39
35
  Requires-Dist: reflex-hosting-cli>=0.1.29
40
36
  Requires-Dist: rich<14.0,>=13.0.0
41
- Requires-Dist: setuptools>=75.0
42
37
  Requires-Dist: sqlmodel<0.1,>=0.0.14
43
- Requires-Dist: starlette-admin<1.0,>=0.11.0
44
- Requires-Dist: tomlkit<1.0,>=0.12.4
45
- Requires-Dist: twine<7.0,>=4.0.0
46
38
  Requires-Dist: typer<1.0,>=0.15.1
47
39
  Requires-Dist: typing-extensions>=4.6.0
48
40
  Requires-Dist: uvicorn>=0.20.0
49
- Requires-Dist: wheel<1.0,>=0.42.0
50
41
  Requires-Dist: wrapt<2.0,>=1.17.0
51
42
  Description-Content-Type: text/markdown
52
43
 
@@ -1,18 +1,18 @@
1
- reflex/__init__.py,sha256=Aee-Zmrzwp3PfVoBTB1OWugfvzkKZkgynjEdKkBlQfo,10378
1
+ reflex/__init__.py,sha256=viEt38jc1skwOUBwwlwPL02hcGrm9xNQzKExVftZEx4,10365
2
2
  reflex/__init__.pyi,sha256=h9ltlhaz1dySsNYpUkN_VCjEzHGfb1h18ThYh15QjyU,11358
3
3
  reflex/__main__.py,sha256=6cVrGEyT3j3tEvlEVUatpaYfbB5EF3UVY-6vc_Z7-hw,108
4
- reflex/admin.py,sha256=wu_vYqB0rU2njYBJSI0XZgVEkAFVZNQNUkUUXrlFbZc,343
5
- reflex/app.py,sha256=e0gVBtxKZzbPiTy_vulk1U1P7GAZBYstR2rIzM744oI,69644
4
+ reflex/admin.py,sha256=q9F2Z4BCtdjPZDGYpk3ogFysTfDPtlR2gY6XDtVPK8U,436
5
+ reflex/app.py,sha256=ZwVWFBiYjx5_gL5hQ3LFN0-SlIC_0ieRphRwTpRdJlM,69778
6
6
  reflex/assets.py,sha256=PLTKAMYPKMZq8eWXKX8uco6NZ9IiPGWal0bOPLUmU7k,3364
7
7
  reflex/base.py,sha256=UuWQkOgZYvJNSIkYuNpb4wp9WtIBXlfmxXARAnOXiZ4,3889
8
- reflex/config.py,sha256=CsCkB15FRTHgqBzXTgml-Z_GOc_flOVDEOQLzncGtaI,35795
9
- reflex/event.py,sha256=29QU60PutDKIctyA6Umt9wQTAqfxOiRZHop5sAUjQ1c,61239
8
+ reflex/config.py,sha256=HowZkxtWwfYPOG_jFDgM3--5_9Ebv1Hv2AursD_1GvE,35443
9
+ reflex/event.py,sha256=Jn0IJn-uhqxYwv6GLLcAOhQ7R9irwE5iDUOVvqhZ2X0,61431
10
10
  reflex/model.py,sha256=oc1guIVGq-4lZhihY-QQ7VpCzhUY1IpT6z8M8jA68o0,17585
11
11
  reflex/page.py,sha256=qEt8n5EtawSywCzdsiaNQJWhC8ie-vg8ig0JGuVavPI,2386
12
12
  reflex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- reflex/reflex.py,sha256=LPYd38YFZkKQUeNrIymHWmlsYsLLmeTUUa8mogM8BEg,21303
13
+ reflex/reflex.py,sha256=tbQ8evLyoda6-Lz1bKcbj0VHWuVzAM8ApFF6POYl_aM,21576
14
14
  reflex/route.py,sha256=nn_hJwtQdjiqH_dHXfqMGWKllnyPQZTSR-KWdHDhoOs,4210
15
- reflex/state.py,sha256=ZHXK9IPXgPtA8FJhpzgOChhq5UoDabxCgMGeMxqx8XU,141816
15
+ reflex/state.py,sha256=7sd-knf4NWLREhYCPolI82hflnNYuohQpMw5TVOlUlE,142143
16
16
  reflex/style.py,sha256=09ZKOBmBNELIB5O4rgLd511hF0EqDPHgVCTJqWiOT7o,13165
17
17
  reflex/testing.py,sha256=lsW4I5qKrEOYVjGj-hibLi5S6w2wFMpAOMeLEPADiJA,36068
18
18
  reflex/.templates/apps/blank/assets/favicon.ico,sha256=baxxgDAQ2V4-G5Q4S2yK5uUJTUGkv-AOWBQ0xd6myUo,4286
@@ -26,7 +26,7 @@ reflex/.templates/jinja/custom_components/pyproject.toml.jinja2,sha256=HG-k3pruU
26
26
  reflex/.templates/jinja/custom_components/src.py.jinja2,sha256=e80PwMI6NoeQtGJ0NXWhYrkqUe7jvvJTFuztYQe-R5w,2403
27
27
  reflex/.templates/jinja/web/package.json.jinja2,sha256=Dyg7DbKaEgxUoaV_DUsv_bHcT0h1mXKgO4R_pVzlHQw,707
28
28
  reflex/.templates/jinja/web/tailwind.config.js.jinja2,sha256=uZMIvtL94OZh6h8zsduv3ox6EXnnYgfVXB_5moOe86E,761
29
- reflex/.templates/jinja/web/pages/_app.js.jinja2,sha256=s0pSHZAZB9SUI3PabTB8uB4I3kehMc-L2DXBxSW6iQY,1375
29
+ reflex/.templates/jinja/web/pages/_app.js.jinja2,sha256=6v6XPqbYXNiEDyZmEGfjlg_NKRg4qQkc7j0aaxr-Z1s,1391
30
30
  reflex/.templates/jinja/web/pages/_document.js.jinja2,sha256=E2r3MWp-gimAa6DdRs9ErQpPEyjS_yV5fdid_wdOOlA,182
31
31
  reflex/.templates/jinja/web/pages/base_page.js.jinja2,sha256=-Jykv29ZqzsQyyRe_iR2gUD5ac-X5RhDrGs0-diOMOA,400
32
32
  reflex/.templates/jinja/web/pages/component.js.jinja2,sha256=1Pui62uSL7LYA7FXZrh9ZmhKH8vHYu663eR134hhsAY,86
@@ -58,7 +58,7 @@ reflex/app_mixins/lifespan.py,sha256=fwtaa9NnyENdDa8_RUHUsT8L9qnZKxcpL-mEGLTGldo
58
58
  reflex/app_mixins/middleware.py,sha256=3OTCEF0rjhd2yTSMCS7wi7J50BxZ8ztCg5K7zfdehhs,2828
59
59
  reflex/app_mixins/mixin.py,sha256=si0Pa0U1EtJc-a6iZntqU9B7_NrPILwrGFxk9mKHBCE,317
60
60
  reflex/compiler/__init__.py,sha256=r8jqmDSFf09iV2lHlNhfc9XrTLjNxfDNwPYlxS4cmHE,27
61
- reflex/compiler/compiler.py,sha256=NDX_3RLM8YJiosFEwZxtH17LcV06QdfbRUrEJa01Ubo,26075
61
+ reflex/compiler/compiler.py,sha256=blk-1PSzJSJf4dyZV-dBfVim0pr3Oy4NGhmCofRWV5o,27318
62
62
  reflex/compiler/templates.py,sha256=NX3YUMVGGyDsy2JuDv-AmklMM0pKJHLPsIpdqamgqRQ,5854
63
63
  reflex/compiler/utils.py,sha256=6b8e7Dlb3vyp1YOjmV4tDx66K7A_cTyXrD6EgvP3vgg,16046
64
64
  reflex/components/__init__.py,sha256=zbIXThv1WPI0FdIGf9G9RAmGoCRoGy7nHcSZ8K5D5bA,624
@@ -102,10 +102,10 @@ reflex/components/core/client_side_routing.pyi,sha256=YYa4mgLMUUNGstIumAuqM2c1cc
102
102
  reflex/components/core/clipboard.py,sha256=WH2pagKO0H5G7BaIT1kChRzrMV-aP5ENv1lIKbkRzJ8,3354
103
103
  reflex/components/core/clipboard.pyi,sha256=aYqRcX1JW0OQa1Jj4ZSY3KT7oyhqXswTNENN0wzUrKk,3191
104
104
  reflex/components/core/colors.py,sha256=-hzVGLEq3TiqroqzMi_YzGBCPXMvkNsen3pS_NzIQNk,590
105
- reflex/components/core/cond.py,sha256=j5V-CGjoB6W_Ch0blQYzLuepjLqtX4vXb8e6qvEL_3I,5685
105
+ reflex/components/core/cond.py,sha256=bIF9yBxYiGEFrgpA74BittUX_-_a6YQtdV5hntovDY0,5711
106
106
  reflex/components/core/debounce.py,sha256=qZsnu-7xfxz3NJS4-UnA_2YQz2P8SznJyuwZz98nEwE,4961
107
107
  reflex/components/core/debounce.pyi,sha256=3AajUXQjN1r4VIw4Oejz0rBVe5KxtL7HA4TB8RAFDtg,3043
108
- reflex/components/core/foreach.py,sha256=HxeKVxJ61KX7FQQFHPDQajGr8G2K9dwuxSAHpyUGrSM,5935
108
+ reflex/components/core/foreach.py,sha256=vkrqjcGHWr9n2x2MOslcE9p9ZRI0Zo40EFZ4AIHZ-7Y,6048
109
109
  reflex/components/core/html.py,sha256=RnFLDLSNqNz3ypSEH5CRV3YcjGzuZ33ok2qSYd9LzQQ,1299
110
110
  reflex/components/core/html.pyi,sha256=3wzLgr4x2sWA-GJYwUGli7CEG3ot1RVUcf9-uQ-N4c0,8902
111
111
  reflex/components/core/match.py,sha256=Dgb-IxeHio1sJBkvdPGb5acdZUQytC2YxSCKKbuT3dI,8915
@@ -339,19 +339,19 @@ reflex/components/tags/match_tag.py,sha256=3lba1H5pCcKkqxEHzM6DZb5s9s0yJLN4Se3vd
339
339
  reflex/components/tags/tag.py,sha256=1fopahujLVjH871UOdmau_n1kEddbQotN5MpKW_s8PU,3644
340
340
  reflex/components/tags/tagless.py,sha256=qO7Gm4V0ITDyymHkyltfz53155ZBt-W_WIPDYy93ca0,587
341
341
  reflex/constants/__init__.py,sha256=c5k9wh50zB_zDXkublXepPZsfAmnYx7ZeNSufIX5qKM,2180
342
- reflex/constants/base.py,sha256=dB-gHb19wYdT_oQHxg0rxFIqM7ljtcr2BCOZDgHEawg,7937
342
+ reflex/constants/base.py,sha256=IT1mppa9NPDLsXGmbW8AeNQFlNK9YbDHFipL290ErQI,8156
343
343
  reflex/constants/colors.py,sha256=cgLn8iEWtlpjQgbhhlCOGjbhfOULKnzqqzPph63SJoI,1613
344
- reflex/constants/compiler.py,sha256=7EdvrKNyr-C7e2T6Xmvd5gpTo5rh4SAHZpmQFV1rrM4,5676
344
+ reflex/constants/compiler.py,sha256=S21T7t2nDBRf1NB0diNo1A3AJuH-w5xo8YoNR5ZAzcY,5692
345
345
  reflex/constants/config.py,sha256=4EljK_fD1Nf4-OfJ9HLYeHSW5xTfNPN6AGjzJ5ARZSY,1579
346
346
  reflex/constants/custom_components.py,sha256=joJt4CEt1yKy7wsBH6vYo7_QRW0O_fWXrrTf0VY2q14,1317
347
347
  reflex/constants/event.py,sha256=8PWobGXnUIbkRS73dRiroj5BJw4C3sbo5AHAhJTZFyM,2849
348
- reflex/constants/installer.py,sha256=by6ZCmyB9HR5Ay9pEXeQsGq0A6HDWLSIukzTEI-CAas,3087
348
+ reflex/constants/installer.py,sha256=V----ENlPvKEn9QKLRzllqzzxAQ_1sPjRpADFyc-Rsw,3039
349
349
  reflex/constants/route.py,sha256=J4QVdeeYz9wX0lYT1sgx0m3kLSArDHzmGCDZ2sqy854,2139
350
350
  reflex/constants/state.py,sha256=6Mfr7xVcAZOj5aSy7kp0W6r8oTs7K30URgGDAAFLfPQ,294
351
351
  reflex/constants/style.py,sha256=EPgRYHhAlcrPUBc2HkDTdTj-Q0uDAXHlq8Sp6D35Zf4,475
352
352
  reflex/constants/utils.py,sha256=GJhFj1uba54CDPEm70tWs8B5iS2siHgeNi--oGCjeRc,759
353
353
  reflex/custom_components/__init__.py,sha256=R4zsvOi4dfPmHc18KEphohXnQFBPnUCb50cMR5hSLDE,36
354
- reflex/custom_components/custom_components.py,sha256=NVPKwrn251tQBKqnQ75t_2HYmOVQv04gvkf0q2tWlTo,33731
354
+ reflex/custom_components/custom_components.py,sha256=lzwbTgkuz2-OBnYTu5H5PXtAwTMtjqBRoUTNrSVXCto,20794
355
355
  reflex/experimental/__init__.py,sha256=tL-_HpKnP6HPqur1pQtpyq_B6tXkZPFadBhtT7-8Mm0,2521
356
356
  reflex/experimental/client_state.py,sha256=p_Toz94fNQGMbHY1WlwfQ-i_M01f1ExA9t1iokSvdLc,9880
357
357
  reflex/experimental/hooks.py,sha256=CHYGrAE5t8riltrJmDFgJ4D2Vhmhw-y3B3MSGNlOQow,2366
@@ -368,27 +368,27 @@ reflex/middleware/hydrate_middleware.py,sha256=1ch7bx2ZhojOR15b-LHD2JztrWCnpPJjT
368
368
  reflex/middleware/middleware.py,sha256=p5VVoIgQ_NwOg_GOY6g0S4fmrV76_VE1zt-HiwbMw-s,1158
369
369
  reflex/utils/__init__.py,sha256=y-AHKiRQAhk2oAkvn7W8cRVTZVK625ff8tTwvZtO7S4,24
370
370
  reflex/utils/build.py,sha256=yt6obelsj1MUhTVHoaxdOH--gYtIEpekYjTN97iFrNg,9118
371
- reflex/utils/codespaces.py,sha256=TzDK--pHwP4r8Nzl0iB_8r-cOFmmL6nHfZ9xRQHA-KY,2754
371
+ reflex/utils/codespaces.py,sha256=6oNokBRpH5Qj39LTS9R2hW59ZVLRwDEooeHD_85hmfw,2945
372
372
  reflex/utils/compat.py,sha256=aSJH_M6iomgHPQ4onQ153xh1MWqPi3HSYDzE68N6gZM,2635
373
373
  reflex/utils/console.py,sha256=97QCo1vXFM-B32zrvYH51yzDRyNPkXD5nNriaiCrlpc,9439
374
374
  reflex/utils/decorator.py,sha256=EYdAjPdfgFjqjYSmLlc9qzOYnoihzavG5T4tgVgzsw4,1171
375
375
  reflex/utils/exceptions.py,sha256=Wwu7Ji2xgq521bJKtU2NgjwhmFfnG8erirEVN2h8S-g,8884
376
- reflex/utils/exec.py,sha256=Qnb9pm5e48OLyMkViBfrdAXKopc-ve_ObDUarQLXUJI,19388
376
+ reflex/utils/exec.py,sha256=cZhowK1CD8qUZEyRxhfTljOkKsZCoMXODLv621sQ3b0,19394
377
377
  reflex/utils/export.py,sha256=bcJA0L8lBbjij-5PU93ka2c1d_yJqrIurp5u4mN5f68,2537
378
378
  reflex/utils/format.py,sha256=a8em_yzqp9pLTrPXRsdzFWSO1qL2x25BpJXOf9DV1t8,20638
379
379
  reflex/utils/imports.py,sha256=k16vV5ANvWrKB1a5WYO7v5BVWES3RabEX8xAEnGvHhg,4162
380
- reflex/utils/lazy_loader.py,sha256=-3DcwIqHNft2fb1ikgDYAMiEwNfbiWfrTBAf1gEVX2o,1367
380
+ reflex/utils/lazy_loader.py,sha256=pdirbNnGfB-r21zgjzHk0c6vODXqKLn9vbJiP5Yr5nQ,4138
381
381
  reflex/utils/misc.py,sha256=X0vgTWn72VduWi6p2hMU-gGksRkhu7isDJNJ0kNVaAo,704
382
382
  reflex/utils/net.py,sha256=8ceAC_diguAxVOOJpzax2vb1RA2h4BxS8SJvpgWqGYI,3175
383
383
  reflex/utils/path_ops.py,sha256=idGxUSJRKwYLLi7ppXkq3eV6rvAytJoO-n-FuLkwl3o,7604
384
- reflex/utils/prerequisites.py,sha256=RT69nOwM5Iluof7w5RGGSHqenBkYPbb67pvFDxOaobA,65983
385
- reflex/utils/processes.py,sha256=pH3MKNPXNevXLZRiye0saCzNLmAfO-IX0mC9jsv2JBQ,16185
386
- reflex/utils/pyi_generator.py,sha256=vLCvwR2T7MAgGrZPuqd5DmSnCFfAFlIyJ1EasRKOcv4,41609
384
+ reflex/utils/prerequisites.py,sha256=OdZlAL7EMybK1jD_q7MuBbH_o9nP9z9d12dT7skb3jk,65869
385
+ reflex/utils/processes.py,sha256=OpZafayCw5VhPyD1LIyin_5fu7Oy2mDCqSxAxX4sh08,16617
386
+ reflex/utils/pyi_generator.py,sha256=vWlxNqZDnGOTGpKgH42i_0xKNKTt0a78mOrouEtMY9Y,44698
387
387
  reflex/utils/redir.py,sha256=23OcUTsbThak5VYMQPOkSzyNsMB3VkgtF1bodSnHwbE,1533
388
388
  reflex/utils/registry.py,sha256=ymBScatt5YiQz9tPYHCzSPs-X7z29hGuu2tlZG28YDQ,1877
389
389
  reflex/utils/serializers.py,sha256=mk5U7U-ae4yTvifq17ejaX1qtKhg1UIJiWiXUNWjJfY,13399
390
390
  reflex/utils/telemetry.py,sha256=qwJBwjdtAV-OGKgO4h-NWhgTvfC3gbduBdn1UB8Ikes,5608
391
- reflex/utils/types.py,sha256=DvW4IUxxsUvuuMrstgv-o8EqQhW-dGFl5U2NmmJqQLw,33326
391
+ reflex/utils/types.py,sha256=w4Vh_2VWysBFoBblHyO1HQxuA_Unb_FCrgR1y0T5Zn4,33620
392
392
  reflex/vars/__init__.py,sha256=2Kv6Oh9g3ISZFESjL1al8KiO7QBZUXmLKGMCBsP-DoY,1243
393
393
  reflex/vars/base.py,sha256=bYCCkLp7aa75Wuv4M763K7Xqu2DFd_FbW11M-fw7ykE,101326
394
394
  reflex/vars/datetime.py,sha256=fEc68T0A6XYlAJ3AGteCIb_vDqgoO1O8tpjMzqlp9sc,5104
@@ -397,8 +397,8 @@ reflex/vars/function.py,sha256=2sVnhgetPSwtor8VFtAiYJdzZ9IRNzAKdsUJG6dXQcE,14461
397
397
  reflex/vars/number.py,sha256=__X8C4lwDQNy8RL9-AxVgC6MM1KF-2PClXE0aR9Ldno,27453
398
398
  reflex/vars/object.py,sha256=-fGqHThozjxAAuQL-wTwEItPiFI-ps53P2bKoSlW_As,17081
399
399
  reflex/vars/sequence.py,sha256=zR3Gwi0xkypThKO45KGqu_AYruY1mTK8kmHjzXcm8y8,55289
400
- reflex-0.7.5a1.dist-info/METADATA,sha256=zdut2IOX6O-8orb6mE3EDtOr4fh7TA4NcW_BRZwfw5A,12224
401
- reflex-0.7.5a1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
402
- reflex-0.7.5a1.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
403
- reflex-0.7.5a1.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
404
- reflex-0.7.5a1.dist-info/RECORD,,
400
+ reflex-0.7.6a0.dist-info/METADATA,sha256=LaNz8E8RqaznX4g50CqE0UT2Tax8NK0VVEsMO0cwOuc,11897
401
+ reflex-0.7.6a0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
402
+ reflex-0.7.6a0.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
403
+ reflex-0.7.6a0.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
404
+ reflex-0.7.6a0.dist-info/RECORD,,