reflex 0.5.0a3__py3-none-any.whl → 0.5.1__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.
- reflex/.templates/web/utils/state.js +7 -2
- reflex/app.py +68 -50
- reflex/app_module_for_backend.py +3 -0
- reflex/base.py +5 -2
- reflex/components/component.py +49 -13
- reflex/components/core/__init__.py +7 -1
- reflex/components/core/banner.py +79 -6
- reflex/components/core/banner.pyi +130 -0
- reflex/components/core/cond.py +10 -4
- reflex/components/core/debounce.py +2 -4
- reflex/components/core/foreach.py +11 -0
- reflex/components/core/upload.py +9 -10
- reflex/components/el/elements/forms.py +12 -6
- reflex/components/el/elements/media.py +19 -0
- reflex/components/el/elements/media.pyi +3 -1
- reflex/components/gridjs/datatable.py +4 -2
- reflex/components/props.py +30 -0
- reflex/components/radix/themes/components/tabs.py +1 -1
- reflex/components/sonner/toast.py +102 -35
- reflex/components/sonner/toast.pyi +27 -14
- reflex/config.py +5 -3
- reflex/constants/compiler.py +3 -3
- reflex/constants/installer.py +1 -1
- reflex/event.py +38 -24
- reflex/experimental/__init__.py +4 -0
- reflex/experimental/client_state.py +198 -0
- reflex/state.py +59 -21
- reflex/style.py +3 -3
- reflex/testing.py +28 -9
- reflex/utils/exceptions.py +64 -8
- reflex/utils/format.py +73 -2
- reflex/utils/prerequisites.py +68 -23
- reflex/utils/processes.py +34 -4
- reflex/utils/telemetry.py +42 -16
- reflex/utils/types.py +16 -0
- reflex/vars.py +104 -61
- reflex/vars.pyi +7 -6
- {reflex-0.5.0a3.dist-info → reflex-0.5.1.dist-info}/METADATA +1 -1
- {reflex-0.5.0a3.dist-info → reflex-0.5.1.dist-info}/RECORD +42 -40
- {reflex-0.5.0a3.dist-info → reflex-0.5.1.dist-info}/LICENSE +0 -0
- {reflex-0.5.0a3.dist-info → reflex-0.5.1.dist-info}/WHEEL +0 -0
- {reflex-0.5.0a3.dist-info → reflex-0.5.1.dist-info}/entry_points.txt +0 -0
reflex/vars.py
CHANGED
|
@@ -35,13 +35,16 @@ from typing import (
|
|
|
35
35
|
from reflex import constants
|
|
36
36
|
from reflex.base import Base
|
|
37
37
|
from reflex.utils import console, format, imports, serializers, types
|
|
38
|
+
from reflex.utils.exceptions import VarAttributeError, VarTypeError, VarValueError
|
|
38
39
|
|
|
39
40
|
# This module used to export ImportVar itself, so we still import it for export here
|
|
40
41
|
from reflex.utils.imports import ImportDict, ImportVar
|
|
42
|
+
from reflex.utils.types import override
|
|
41
43
|
|
|
42
44
|
if TYPE_CHECKING:
|
|
43
45
|
from reflex.state import BaseState
|
|
44
46
|
|
|
47
|
+
|
|
45
48
|
# Set of unique variable names.
|
|
46
49
|
USED_VARIABLES = set()
|
|
47
50
|
|
|
@@ -340,7 +343,11 @@ class Var:
|
|
|
340
343
|
|
|
341
344
|
@classmethod
|
|
342
345
|
def create(
|
|
343
|
-
cls,
|
|
346
|
+
cls,
|
|
347
|
+
value: Any,
|
|
348
|
+
_var_is_local: bool = True,
|
|
349
|
+
_var_is_string: bool = False,
|
|
350
|
+
_var_data: Optional[VarData] = None,
|
|
344
351
|
) -> Var | None:
|
|
345
352
|
"""Create a var from a value.
|
|
346
353
|
|
|
@@ -348,12 +355,13 @@ class Var:
|
|
|
348
355
|
value: The value to create the var from.
|
|
349
356
|
_var_is_local: Whether the var is local.
|
|
350
357
|
_var_is_string: Whether the var is a string literal.
|
|
358
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
351
359
|
|
|
352
360
|
Returns:
|
|
353
361
|
The var.
|
|
354
362
|
|
|
355
363
|
Raises:
|
|
356
|
-
|
|
364
|
+
VarTypeError: If the value is JSON-unserializable.
|
|
357
365
|
"""
|
|
358
366
|
# Check for none values.
|
|
359
367
|
if value is None:
|
|
@@ -364,15 +372,14 @@ class Var:
|
|
|
364
372
|
return value
|
|
365
373
|
|
|
366
374
|
# Try to pull the imports and hooks from contained values.
|
|
367
|
-
_var_data = None
|
|
368
375
|
if not isinstance(value, str):
|
|
369
|
-
_var_data = VarData.merge(*_extract_var_data(value))
|
|
376
|
+
_var_data = VarData.merge(*_extract_var_data(value), _var_data)
|
|
370
377
|
|
|
371
378
|
# Try to serialize the value.
|
|
372
379
|
type_ = type(value)
|
|
373
380
|
name = value if type_ in types.JSONType else serializers.serialize(value)
|
|
374
381
|
if name is None:
|
|
375
|
-
raise
|
|
382
|
+
raise VarTypeError(
|
|
376
383
|
f"No JSON serializer found for var {value} of type {type_}."
|
|
377
384
|
)
|
|
378
385
|
name = name if isinstance(name, str) else format.json_dumps(name)
|
|
@@ -387,7 +394,11 @@ class Var:
|
|
|
387
394
|
|
|
388
395
|
@classmethod
|
|
389
396
|
def create_safe(
|
|
390
|
-
cls,
|
|
397
|
+
cls,
|
|
398
|
+
value: Any,
|
|
399
|
+
_var_is_local: bool = True,
|
|
400
|
+
_var_is_string: bool = False,
|
|
401
|
+
_var_data: Optional[VarData] = None,
|
|
391
402
|
) -> Var:
|
|
392
403
|
"""Create a var from a value, asserting that it is not None.
|
|
393
404
|
|
|
@@ -395,6 +406,7 @@ class Var:
|
|
|
395
406
|
value: The value to create the var from.
|
|
396
407
|
_var_is_local: Whether the var is local.
|
|
397
408
|
_var_is_string: Whether the var is a string literal.
|
|
409
|
+
_var_data: Additional hooks and imports associated with the Var.
|
|
398
410
|
|
|
399
411
|
Returns:
|
|
400
412
|
The var.
|
|
@@ -403,6 +415,7 @@ class Var:
|
|
|
403
415
|
value,
|
|
404
416
|
_var_is_local=_var_is_local,
|
|
405
417
|
_var_is_string=_var_is_string,
|
|
418
|
+
_var_data=_var_data,
|
|
406
419
|
)
|
|
407
420
|
assert var is not None
|
|
408
421
|
return var
|
|
@@ -542,9 +555,9 @@ class Var:
|
|
|
542
555
|
"""Raise exception if using Var in a boolean context.
|
|
543
556
|
|
|
544
557
|
Raises:
|
|
545
|
-
|
|
558
|
+
VarTypeError: when attempting to bool-ify the Var.
|
|
546
559
|
"""
|
|
547
|
-
raise
|
|
560
|
+
raise VarTypeError(
|
|
548
561
|
f"Cannot convert Var {self._var_full_name!r} to bool for use with `if`, `and`, `or`, and `not`. "
|
|
549
562
|
"Instead use `rx.cond` and bitwise operators `&` (and), `|` (or), `~` (invert)."
|
|
550
563
|
)
|
|
@@ -553,9 +566,9 @@ class Var:
|
|
|
553
566
|
"""Raise exception if using Var in an iterable context.
|
|
554
567
|
|
|
555
568
|
Raises:
|
|
556
|
-
|
|
569
|
+
VarTypeError: when attempting to iterate over the Var.
|
|
557
570
|
"""
|
|
558
|
-
raise
|
|
571
|
+
raise VarTypeError(
|
|
559
572
|
f"Cannot iterate over Var {self._var_full_name!r}. Instead use `rx.foreach`."
|
|
560
573
|
)
|
|
561
574
|
|
|
@@ -584,7 +597,7 @@ class Var:
|
|
|
584
597
|
The indexed var.
|
|
585
598
|
|
|
586
599
|
Raises:
|
|
587
|
-
|
|
600
|
+
VarTypeError: If the var is not indexable.
|
|
588
601
|
"""
|
|
589
602
|
# Indexing is only supported for strings, lists, tuples, dicts, and dataframes.
|
|
590
603
|
if not (
|
|
@@ -592,11 +605,11 @@ class Var:
|
|
|
592
605
|
or types.is_dataframe(self._var_type)
|
|
593
606
|
):
|
|
594
607
|
if self._var_type == Any:
|
|
595
|
-
raise
|
|
608
|
+
raise VarTypeError(
|
|
596
609
|
"Could not index into var of type Any. (If you are trying to index into a state var, "
|
|
597
610
|
"add the correct type annotation to the var.)"
|
|
598
611
|
)
|
|
599
|
-
raise
|
|
612
|
+
raise VarTypeError(
|
|
600
613
|
f"Var {self._var_name} of type {self._var_type} does not support indexing."
|
|
601
614
|
)
|
|
602
615
|
|
|
@@ -615,7 +628,7 @@ class Var:
|
|
|
615
628
|
or isinstance(i, Var)
|
|
616
629
|
and not i._var_type == int
|
|
617
630
|
):
|
|
618
|
-
raise
|
|
631
|
+
raise VarTypeError("Index must be an integer or an integer var.")
|
|
619
632
|
|
|
620
633
|
# Handle slices first.
|
|
621
634
|
if isinstance(i, slice):
|
|
@@ -658,7 +671,7 @@ class Var:
|
|
|
658
671
|
i._var_type, types.get_args(Union[int, str, float])
|
|
659
672
|
)
|
|
660
673
|
):
|
|
661
|
-
raise
|
|
674
|
+
raise VarTypeError(
|
|
662
675
|
"Index must be one of the following types: int, str, int or str Var"
|
|
663
676
|
)
|
|
664
677
|
# Get the type of the indexed var.
|
|
@@ -687,7 +700,7 @@ class Var:
|
|
|
687
700
|
The var attribute.
|
|
688
701
|
|
|
689
702
|
Raises:
|
|
690
|
-
|
|
703
|
+
VarAttributeError: If the attribute cannot be found, or if __getattr__ fallback should be used.
|
|
691
704
|
"""
|
|
692
705
|
try:
|
|
693
706
|
var_attribute = super().__getattribute__(name)
|
|
@@ -698,10 +711,12 @@ class Var:
|
|
|
698
711
|
super().__getattribute__("_var_type"), name
|
|
699
712
|
)
|
|
700
713
|
if type_ is not None:
|
|
701
|
-
raise
|
|
714
|
+
raise VarAttributeError(
|
|
715
|
+
f"{name} is being accessed through the Var."
|
|
716
|
+
)
|
|
702
717
|
# Return the attribute as-is.
|
|
703
718
|
return var_attribute
|
|
704
|
-
except
|
|
719
|
+
except VarAttributeError:
|
|
705
720
|
raise # fall back to __getattr__ anyway
|
|
706
721
|
|
|
707
722
|
def __getattr__(self, name: str) -> Var:
|
|
@@ -714,13 +729,13 @@ class Var:
|
|
|
714
729
|
The var attribute.
|
|
715
730
|
|
|
716
731
|
Raises:
|
|
717
|
-
|
|
718
|
-
|
|
732
|
+
VarAttributeError: If the var is wrongly annotated or can't find attribute.
|
|
733
|
+
VarTypeError: If an annotation to the var isn't provided.
|
|
719
734
|
"""
|
|
720
735
|
# Check if the attribute is one of the class fields.
|
|
721
736
|
if not name.startswith("_"):
|
|
722
737
|
if self._var_type == Any:
|
|
723
|
-
raise
|
|
738
|
+
raise VarTypeError(
|
|
724
739
|
f"You must provide an annotation for the state var `{self._var_full_name}`. Annotation cannot be `{self._var_type}`"
|
|
725
740
|
) from None
|
|
726
741
|
is_optional = types.is_optional(self._var_type)
|
|
@@ -734,16 +749,16 @@ class Var:
|
|
|
734
749
|
)
|
|
735
750
|
|
|
736
751
|
if name in REPLACED_NAMES:
|
|
737
|
-
raise
|
|
752
|
+
raise VarAttributeError(
|
|
738
753
|
f"Field {name!r} was renamed to {REPLACED_NAMES[name]!r}"
|
|
739
754
|
)
|
|
740
755
|
|
|
741
|
-
raise
|
|
756
|
+
raise VarAttributeError(
|
|
742
757
|
f"The State var `{self._var_full_name}` has no attribute '{name}' or may have been annotated "
|
|
743
758
|
f"wrongly."
|
|
744
759
|
)
|
|
745
760
|
|
|
746
|
-
raise
|
|
761
|
+
raise VarAttributeError(
|
|
747
762
|
f"The State var has no attribute '{name}' or may have been annotated wrongly.",
|
|
748
763
|
)
|
|
749
764
|
|
|
@@ -770,8 +785,8 @@ class Var:
|
|
|
770
785
|
The operation result.
|
|
771
786
|
|
|
772
787
|
Raises:
|
|
773
|
-
|
|
774
|
-
|
|
788
|
+
VarTypeError: If the operation between two operands is invalid.
|
|
789
|
+
VarValueError: If flip is set to true and value of operand is not provided
|
|
775
790
|
"""
|
|
776
791
|
if isinstance(other, str):
|
|
777
792
|
other = Var.create(json.dumps(other))
|
|
@@ -781,7 +796,7 @@ class Var:
|
|
|
781
796
|
type_ = type_ or self._var_type
|
|
782
797
|
|
|
783
798
|
if other is None and flip:
|
|
784
|
-
raise
|
|
799
|
+
raise VarValueError(
|
|
785
800
|
"flip_operands cannot be set to True if the value of 'other' operand is not provided"
|
|
786
801
|
)
|
|
787
802
|
|
|
@@ -804,7 +819,7 @@ class Var:
|
|
|
804
819
|
types.get_base_class(right_operand._var_type), # type: ignore
|
|
805
820
|
op,
|
|
806
821
|
):
|
|
807
|
-
raise
|
|
822
|
+
raise VarTypeError(
|
|
808
823
|
f"Unsupported Operand type(s) for {op}: `{left_operand._var_full_name}` of type {left_operand._var_type.__name__} and `{right_operand._var_full_name}` of type {right_operand._var_type.__name__}" # type: ignore
|
|
809
824
|
)
|
|
810
825
|
|
|
@@ -819,19 +834,19 @@ class Var:
|
|
|
819
834
|
if invoke_fn:
|
|
820
835
|
# invoke the function on left operand.
|
|
821
836
|
operation_name = (
|
|
822
|
-
f"{left_operand_full_name}.{fn}({right_operand_full_name})"
|
|
823
|
-
)
|
|
837
|
+
f"{left_operand_full_name}.{fn}({right_operand_full_name})" # type: ignore
|
|
838
|
+
)
|
|
824
839
|
else:
|
|
825
840
|
# pass the operands as arguments to the function.
|
|
826
841
|
operation_name = (
|
|
827
|
-
f"{left_operand_full_name} {op} {right_operand_full_name}"
|
|
828
|
-
)
|
|
842
|
+
f"{left_operand_full_name} {op} {right_operand_full_name}" # type: ignore
|
|
843
|
+
)
|
|
829
844
|
operation_name = f"{fn}({operation_name})"
|
|
830
845
|
else:
|
|
831
846
|
# apply operator to operands (left operand <operator> right_operand)
|
|
832
847
|
operation_name = (
|
|
833
|
-
f"{left_operand_full_name} {op} {right_operand_full_name}"
|
|
834
|
-
)
|
|
848
|
+
f"{left_operand_full_name} {op} {right_operand_full_name}" # type: ignore
|
|
849
|
+
)
|
|
835
850
|
operation_name = format.wrap(operation_name, "(")
|
|
836
851
|
else:
|
|
837
852
|
# apply operator to left operand (<operator> left_operand)
|
|
@@ -925,10 +940,10 @@ class Var:
|
|
|
925
940
|
A var with the absolute value.
|
|
926
941
|
|
|
927
942
|
Raises:
|
|
928
|
-
|
|
943
|
+
VarTypeError: If the var is not a list.
|
|
929
944
|
"""
|
|
930
945
|
if not types._issubclass(self._var_type, List):
|
|
931
|
-
raise
|
|
946
|
+
raise VarTypeError(f"Cannot get length of non-list var {self}.")
|
|
932
947
|
return self._replace(
|
|
933
948
|
_var_name=f"{self._var_name}.length",
|
|
934
949
|
_var_type=int,
|
|
@@ -1328,9 +1343,9 @@ class Var:
|
|
|
1328
1343
|
"""Override the 'in' operator to alert the user that it is not supported.
|
|
1329
1344
|
|
|
1330
1345
|
Raises:
|
|
1331
|
-
|
|
1346
|
+
VarTypeError: the operation is not supported
|
|
1332
1347
|
"""
|
|
1333
|
-
raise
|
|
1348
|
+
raise VarTypeError(
|
|
1334
1349
|
"'in' operator not supported for Var types, use Var.contains() instead."
|
|
1335
1350
|
)
|
|
1336
1351
|
|
|
@@ -1341,13 +1356,13 @@ class Var:
|
|
|
1341
1356
|
other: The object to check.
|
|
1342
1357
|
|
|
1343
1358
|
Raises:
|
|
1344
|
-
|
|
1359
|
+
VarTypeError: If the var is not a valid type: dict, list, tuple or str.
|
|
1345
1360
|
|
|
1346
1361
|
Returns:
|
|
1347
1362
|
A var representing the contain check.
|
|
1348
1363
|
"""
|
|
1349
1364
|
if not (types._issubclass(self._var_type, Union[dict, list, tuple, str, set])):
|
|
1350
|
-
raise
|
|
1365
|
+
raise VarTypeError(
|
|
1351
1366
|
f"Var {self._var_full_name} of type {self._var_type} does not support contains check."
|
|
1352
1367
|
)
|
|
1353
1368
|
method = (
|
|
@@ -1371,7 +1386,7 @@ class Var:
|
|
|
1371
1386
|
if types._issubclass(self._var_type, str) and not types._issubclass(
|
|
1372
1387
|
other._var_type, str
|
|
1373
1388
|
):
|
|
1374
|
-
raise
|
|
1389
|
+
raise VarTypeError(
|
|
1375
1390
|
f"'in <string>' requires string as left operand, not {other._var_type}"
|
|
1376
1391
|
)
|
|
1377
1392
|
return self._replace(
|
|
@@ -1385,13 +1400,13 @@ class Var:
|
|
|
1385
1400
|
"""Reverse a list var.
|
|
1386
1401
|
|
|
1387
1402
|
Raises:
|
|
1388
|
-
|
|
1403
|
+
VarTypeError: If the var is not a list.
|
|
1389
1404
|
|
|
1390
1405
|
Returns:
|
|
1391
1406
|
A var with the reversed list.
|
|
1392
1407
|
"""
|
|
1393
1408
|
if not types._issubclass(self._var_type, list):
|
|
1394
|
-
raise
|
|
1409
|
+
raise VarTypeError(f"Cannot reverse non-list var {self._var_full_name}.")
|
|
1395
1410
|
|
|
1396
1411
|
return self._replace(
|
|
1397
1412
|
_var_name=f"[...{self._var_full_name}].reverse()",
|
|
@@ -1406,10 +1421,10 @@ class Var:
|
|
|
1406
1421
|
A var with the lowercase string.
|
|
1407
1422
|
|
|
1408
1423
|
Raises:
|
|
1409
|
-
|
|
1424
|
+
VarTypeError: If the var is not a string.
|
|
1410
1425
|
"""
|
|
1411
1426
|
if not types._issubclass(self._var_type, str):
|
|
1412
|
-
raise
|
|
1427
|
+
raise VarTypeError(
|
|
1413
1428
|
f"Cannot convert non-string var {self._var_full_name} to lowercase."
|
|
1414
1429
|
)
|
|
1415
1430
|
|
|
@@ -1426,10 +1441,10 @@ class Var:
|
|
|
1426
1441
|
A var with the uppercase string.
|
|
1427
1442
|
|
|
1428
1443
|
Raises:
|
|
1429
|
-
|
|
1444
|
+
VarTypeError: If the var is not a string.
|
|
1430
1445
|
"""
|
|
1431
1446
|
if not types._issubclass(self._var_type, str):
|
|
1432
|
-
raise
|
|
1447
|
+
raise VarTypeError(
|
|
1433
1448
|
f"Cannot convert non-string var {self._var_full_name} to uppercase."
|
|
1434
1449
|
)
|
|
1435
1450
|
|
|
@@ -1449,10 +1464,10 @@ class Var:
|
|
|
1449
1464
|
A var with the stripped string.
|
|
1450
1465
|
|
|
1451
1466
|
Raises:
|
|
1452
|
-
|
|
1467
|
+
VarTypeError: If the var is not a string.
|
|
1453
1468
|
"""
|
|
1454
1469
|
if not types._issubclass(self._var_type, str):
|
|
1455
|
-
raise
|
|
1470
|
+
raise VarTypeError(f"Cannot strip non-string var {self._var_full_name}.")
|
|
1456
1471
|
|
|
1457
1472
|
other = Var.create_safe(json.dumps(other)) if isinstance(other, str) else other
|
|
1458
1473
|
|
|
@@ -1472,10 +1487,10 @@ class Var:
|
|
|
1472
1487
|
A var with the list.
|
|
1473
1488
|
|
|
1474
1489
|
Raises:
|
|
1475
|
-
|
|
1490
|
+
VarTypeError: If the var is not a string.
|
|
1476
1491
|
"""
|
|
1477
1492
|
if not types._issubclass(self._var_type, str):
|
|
1478
|
-
raise
|
|
1493
|
+
raise VarTypeError(f"Cannot split non-string var {self._var_full_name}.")
|
|
1479
1494
|
|
|
1480
1495
|
other = Var.create_safe(json.dumps(other)) if isinstance(other, str) else other
|
|
1481
1496
|
|
|
@@ -1496,10 +1511,10 @@ class Var:
|
|
|
1496
1511
|
A var with the string.
|
|
1497
1512
|
|
|
1498
1513
|
Raises:
|
|
1499
|
-
|
|
1514
|
+
VarTypeError: If the var is not a list.
|
|
1500
1515
|
"""
|
|
1501
1516
|
if not types._issubclass(self._var_type, list):
|
|
1502
|
-
raise
|
|
1517
|
+
raise VarTypeError(f"Cannot join non-list var {self._var_full_name}.")
|
|
1503
1518
|
|
|
1504
1519
|
if other is None:
|
|
1505
1520
|
other = Var.create_safe('""')
|
|
@@ -1525,11 +1540,11 @@ class Var:
|
|
|
1525
1540
|
A var representing foreach operation.
|
|
1526
1541
|
|
|
1527
1542
|
Raises:
|
|
1528
|
-
|
|
1543
|
+
VarTypeError: If the var is not a list.
|
|
1529
1544
|
"""
|
|
1530
1545
|
inner_types = get_args(self._var_type)
|
|
1531
1546
|
if not inner_types:
|
|
1532
|
-
raise
|
|
1547
|
+
raise VarTypeError(
|
|
1533
1548
|
f"Cannot foreach over non-sequence var {self._var_full_name} of type {self._var_type}."
|
|
1534
1549
|
)
|
|
1535
1550
|
arg = BaseVar(
|
|
@@ -1566,25 +1581,27 @@ class Var:
|
|
|
1566
1581
|
A var representing range operation.
|
|
1567
1582
|
|
|
1568
1583
|
Raises:
|
|
1569
|
-
|
|
1584
|
+
VarTypeError: If the var is not an int.
|
|
1570
1585
|
"""
|
|
1571
1586
|
if not isinstance(v1, Var):
|
|
1572
1587
|
v1 = Var.create_safe(v1)
|
|
1573
1588
|
if v1._var_type != int:
|
|
1574
|
-
raise
|
|
1589
|
+
raise VarTypeError(f"Cannot get range on non-int var {v1._var_full_name}.")
|
|
1575
1590
|
if not isinstance(v2, Var):
|
|
1576
1591
|
v2 = Var.create(v2)
|
|
1577
1592
|
if v2 is None:
|
|
1578
1593
|
v2 = Var.create_safe("undefined")
|
|
1579
1594
|
elif v2._var_type != int:
|
|
1580
|
-
raise
|
|
1595
|
+
raise VarTypeError(f"Cannot get range on non-int var {v2._var_full_name}.")
|
|
1581
1596
|
|
|
1582
1597
|
if not isinstance(step, Var):
|
|
1583
1598
|
step = Var.create(step)
|
|
1584
1599
|
if step is None:
|
|
1585
1600
|
step = Var.create_safe(1)
|
|
1586
1601
|
elif step._var_type != int:
|
|
1587
|
-
raise
|
|
1602
|
+
raise VarTypeError(
|
|
1603
|
+
f"Cannot get range on non-int var {step._var_full_name}."
|
|
1604
|
+
)
|
|
1588
1605
|
|
|
1589
1606
|
return BaseVar(
|
|
1590
1607
|
_var_name=f"Array.from(range({v1._var_full_name}, {v2._var_full_name}, {step._var_name}))",
|
|
@@ -1867,6 +1884,32 @@ class ComputedVar(Var, property):
|
|
|
1867
1884
|
kwargs["_var_type"] = kwargs.pop("_var_type", self._determine_var_type())
|
|
1868
1885
|
BaseVar.__init__(self, **kwargs) # type: ignore
|
|
1869
1886
|
|
|
1887
|
+
@override
|
|
1888
|
+
def _replace(self, merge_var_data=None, **kwargs: Any) -> ComputedVar:
|
|
1889
|
+
"""Replace the attributes of the ComputedVar.
|
|
1890
|
+
|
|
1891
|
+
Args:
|
|
1892
|
+
merge_var_data: VarData to merge into the existing VarData.
|
|
1893
|
+
**kwargs: Var fields to update.
|
|
1894
|
+
|
|
1895
|
+
Returns:
|
|
1896
|
+
The new ComputedVar instance.
|
|
1897
|
+
"""
|
|
1898
|
+
return ComputedVar(
|
|
1899
|
+
fget=kwargs.get("fget", self.fget),
|
|
1900
|
+
initial_value=kwargs.get("initial_value", self._initial_value),
|
|
1901
|
+
cache=kwargs.get("cache", self._cache),
|
|
1902
|
+
_var_name=kwargs.get("_var_name", self._var_name),
|
|
1903
|
+
_var_type=kwargs.get("_var_type", self._var_type),
|
|
1904
|
+
_var_is_local=kwargs.get("_var_is_local", self._var_is_local),
|
|
1905
|
+
_var_is_string=kwargs.get("_var_is_string", self._var_is_string),
|
|
1906
|
+
_var_full_name_needs_state_prefix=kwargs.get(
|
|
1907
|
+
"_var_full_name_needs_state_prefix",
|
|
1908
|
+
self._var_full_name_needs_state_prefix,
|
|
1909
|
+
),
|
|
1910
|
+
_var_data=VarData.merge(self._var_data, merge_var_data),
|
|
1911
|
+
)
|
|
1912
|
+
|
|
1870
1913
|
@property
|
|
1871
1914
|
def _cache_attr(self) -> str:
|
|
1872
1915
|
"""Get the attribute used to cache the value on the instance.
|
|
@@ -1919,7 +1962,7 @@ class ComputedVar(Var, property):
|
|
|
1919
1962
|
A set of variable names accessed by the given obj.
|
|
1920
1963
|
|
|
1921
1964
|
Raises:
|
|
1922
|
-
|
|
1965
|
+
VarValueError: if the function references the get_state, parent_state, or substates attributes
|
|
1923
1966
|
(cannot track deps in a related state, only implicitly via parent state).
|
|
1924
1967
|
"""
|
|
1925
1968
|
d = set()
|
|
@@ -1966,7 +2009,7 @@ class ComputedVar(Var, property):
|
|
|
1966
2009
|
except Exception:
|
|
1967
2010
|
ref_obj = None
|
|
1968
2011
|
if instruction.argval in invalid_names:
|
|
1969
|
-
raise
|
|
2012
|
+
raise VarValueError(
|
|
1970
2013
|
f"Cached var {self._var_full_name} cannot access arbitrary state via `{instruction.argval}`."
|
|
1971
2014
|
)
|
|
1972
2015
|
if callable(ref_obj):
|
reflex/vars.pyi
CHANGED
|
@@ -34,10 +34,10 @@ def _decode_var(value: str) -> tuple[VarData, str]: ...
|
|
|
34
34
|
def _extract_var_data(value: Iterable) -> list[VarData | None]: ...
|
|
35
35
|
|
|
36
36
|
class VarData(Base):
|
|
37
|
-
state: str
|
|
38
|
-
imports: dict[str,
|
|
39
|
-
hooks: Dict[str, None]
|
|
40
|
-
interpolations: List[Tuple[int, int]]
|
|
37
|
+
state: str = ""
|
|
38
|
+
imports: dict[str, List[ImportVar]] = {}
|
|
39
|
+
hooks: Dict[str, None] = {}
|
|
40
|
+
interpolations: List[Tuple[int, int]] = []
|
|
41
41
|
@classmethod
|
|
42
42
|
def merge(cls, *others: VarData | None) -> VarData | None: ...
|
|
43
43
|
|
|
@@ -50,11 +50,11 @@ class Var:
|
|
|
50
50
|
_var_data: VarData | None = None
|
|
51
51
|
@classmethod
|
|
52
52
|
def create(
|
|
53
|
-
cls, value: Any, _var_is_local: bool = False, _var_is_string: bool = False
|
|
53
|
+
cls, value: Any, _var_is_local: bool = False, _var_is_string: bool = False, _var_data: VarData | None = None,
|
|
54
54
|
) -> Optional[Var]: ...
|
|
55
55
|
@classmethod
|
|
56
56
|
def create_safe(
|
|
57
|
-
cls, value: Any, _var_is_local: bool = False, _var_is_string: bool = False
|
|
57
|
+
cls, value: Any, _var_is_local: bool = False, _var_is_string: bool = False, _var_data: VarData | None = None,
|
|
58
58
|
) -> Var: ...
|
|
59
59
|
@classmethod
|
|
60
60
|
def __class_getitem__(cls, type_: Type) -> _GenericAlias: ...
|
|
@@ -139,6 +139,7 @@ class ComputedVar(Var):
|
|
|
139
139
|
def _cache_attr(self) -> str: ...
|
|
140
140
|
def __get__(self, instance, owner): ...
|
|
141
141
|
def _deps(self, objclass: Type, obj: Optional[FunctionType] = ...) -> Set[str]: ...
|
|
142
|
+
def _replace(self, merge_var_data=None, **kwargs: Any) -> ComputedVar: ...
|
|
142
143
|
def mark_dirty(self, instance) -> None: ...
|
|
143
144
|
def _determine_var_type(self) -> Type: ...
|
|
144
145
|
@overload
|