reflex 0.5.8a1__py3-none-any.whl → 0.5.9a1__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.

@@ -4,23 +4,49 @@ from __future__ import annotations
4
4
 
5
5
  import dataclasses
6
6
  import functools
7
+ import inspect
7
8
  import json
8
9
  import re
9
10
  import sys
11
+ import typing
10
12
  from functools import cached_property
11
- from typing import Any, List, Set, Tuple, Union
13
+ from typing import (
14
+ TYPE_CHECKING,
15
+ Any,
16
+ Dict,
17
+ List,
18
+ Literal,
19
+ Set,
20
+ Tuple,
21
+ TypeVar,
22
+ Union,
23
+ overload,
24
+ )
25
+
26
+ from typing_extensions import get_origin
12
27
 
13
28
  from reflex import constants
14
29
  from reflex.constants.base import REFLEX_VAR_OPENING_TAG
15
30
  from reflex.experimental.vars.base import (
16
31
  ImmutableVar,
17
32
  LiteralVar,
33
+ figure_out_type,
34
+ unionize,
18
35
  )
19
- from reflex.experimental.vars.number import BooleanVar, NotEqualOperation, NumberVar
36
+ from reflex.experimental.vars.number import (
37
+ BooleanVar,
38
+ LiteralNumberVar,
39
+ NotEqualOperation,
40
+ NumberVar,
41
+ )
42
+ from reflex.utils.types import GenericType
20
43
  from reflex.vars import ImmutableVarData, Var, VarData, _global_vars
21
44
 
45
+ if TYPE_CHECKING:
46
+ from .object import ObjectVar
47
+
22
48
 
23
- class StringVar(ImmutableVar):
49
+ class StringVar(ImmutableVar[str]):
24
50
  """Base class for immutable string vars."""
25
51
 
26
52
  def __add__(self, other: StringVar | str) -> ConcatVarOperation:
@@ -67,7 +93,15 @@ class StringVar(ImmutableVar):
67
93
  """
68
94
  return ConcatVarOperation(*[self for _ in range(other)])
69
95
 
70
- def __getitem__(self, i: slice | int) -> StringSliceOperation | StringItemOperation:
96
+ @overload
97
+ def __getitem__(self, i: slice) -> ArrayJoinOperation: ...
98
+
99
+ @overload
100
+ def __getitem__(self, i: int | NumberVar) -> StringItemOperation: ...
101
+
102
+ def __getitem__(
103
+ self, i: slice | int | NumberVar
104
+ ) -> ArrayJoinOperation | StringItemOperation:
71
105
  """Get a slice of the string.
72
106
 
73
107
  Args:
@@ -77,16 +111,16 @@ class StringVar(ImmutableVar):
77
111
  The string slice operation.
78
112
  """
79
113
  if isinstance(i, slice):
80
- return StringSliceOperation(self, i)
114
+ return self.split()[i].join()
81
115
  return StringItemOperation(self, i)
82
116
 
83
- def length(self) -> StringLengthOperation:
117
+ def length(self) -> NumberVar:
84
118
  """Get the length of the string.
85
119
 
86
120
  Returns:
87
121
  The string length operation.
88
122
  """
89
- return StringLengthOperation(self)
123
+ return self.split().length()
90
124
 
91
125
  def lower(self) -> StringLowerOperation:
92
126
  """Convert the string to lowercase.
@@ -120,13 +154,13 @@ class StringVar(ImmutableVar):
120
154
  """
121
155
  return NotEqualOperation(self.length(), 0)
122
156
 
123
- def reversed(self) -> StringReverseOperation:
157
+ def reversed(self) -> ArrayJoinOperation:
124
158
  """Reverse the string.
125
159
 
126
160
  Returns:
127
161
  The string reverse operation.
128
162
  """
129
- return StringReverseOperation(self)
163
+ return self.split().reverse().join()
130
164
 
131
165
  def contains(self, other: StringVar | str) -> StringContainsOperation:
132
166
  """Check if the string contains another string.
@@ -151,85 +185,6 @@ class StringVar(ImmutableVar):
151
185
  return StringSplitOperation(self, separator)
152
186
 
153
187
 
154
- @dataclasses.dataclass(
155
- eq=False,
156
- frozen=True,
157
- **{"slots": True} if sys.version_info >= (3, 10) else {},
158
- )
159
- class StringToNumberOperation(NumberVar):
160
- """Base class for immutable number vars that are the result of a string to number operation."""
161
-
162
- a: StringVar = dataclasses.field(
163
- default_factory=lambda: LiteralStringVar.create("")
164
- )
165
-
166
- def __init__(self, a: StringVar | str, _var_data: VarData | None = None):
167
- """Initialize the string to number operation var.
168
-
169
- Args:
170
- a: The string.
171
- _var_data: Additional hooks and imports associated with the Var.
172
- """
173
- super(StringToNumberOperation, self).__init__(
174
- _var_name="",
175
- _var_type=float,
176
- _var_data=ImmutableVarData.merge(_var_data),
177
- )
178
- object.__setattr__(
179
- self, "a", a if isinstance(a, Var) else LiteralStringVar.create(a)
180
- )
181
- object.__delattr__(self, "_var_name")
182
-
183
- @cached_property
184
- def _cached_var_name(self) -> str:
185
- """The name of the var.
186
-
187
- Raises:
188
- NotImplementedError: Must be implemented by subclasses.
189
- """
190
- raise NotImplementedError(
191
- "StringToNumberOperation must implement _cached_var_name"
192
- )
193
-
194
- def __getattr__(self, name: str) -> Any:
195
- """Get an attribute of the var.
196
-
197
- Args:
198
- name: The name of the attribute.
199
-
200
- Returns:
201
- The attribute value.
202
- """
203
- if name == "_var_name":
204
- return self._cached_var_name
205
- getattr(super(StringToNumberOperation, self), name)
206
-
207
- @cached_property
208
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
209
- """Get all VarData associated with the Var.
210
-
211
- Returns:
212
- The VarData of the components and all of its children.
213
- """
214
- return ImmutableVarData.merge(self.a._get_all_var_data(), self._var_data)
215
-
216
- def _get_all_var_data(self) -> ImmutableVarData | None:
217
- return self._cached_get_all_var_data
218
-
219
-
220
- class StringLengthOperation(StringToNumberOperation):
221
- """Base class for immutable number vars that are the result of a string length operation."""
222
-
223
- @cached_property
224
- def _cached_var_name(self) -> str:
225
- """The name of the var.
226
-
227
- Returns:
228
- The name of the var.
229
- """
230
- return f"{str(self.a)}.length"
231
-
232
-
233
188
  @dataclasses.dataclass(
234
189
  eq=False,
235
190
  frozen=True,
@@ -338,19 +293,6 @@ class StringStripOperation(StringToStringOperation):
338
293
  return f"{str(self.a)}.trim()"
339
294
 
340
295
 
341
- class StringReverseOperation(StringToStringOperation):
342
- """Base class for immutable string vars that are the result of a string reverse operation."""
343
-
344
- @cached_property
345
- def _cached_var_name(self) -> str:
346
- """The name of the var.
347
-
348
- Returns:
349
- The name of the var.
350
- """
351
- return f"{str(self.a)}.split('').reverse().join('')"
352
-
353
-
354
296
  @dataclasses.dataclass(
355
297
  eq=False,
356
298
  frozen=True,
@@ -426,112 +368,6 @@ class StringContainsOperation(BooleanVar):
426
368
  return self._cached_get_all_var_data
427
369
 
428
370
 
429
- @dataclasses.dataclass(
430
- eq=False,
431
- frozen=True,
432
- **{"slots": True} if sys.version_info >= (3, 10) else {},
433
- )
434
- class StringSliceOperation(StringVar):
435
- """Base class for immutable string vars that are the result of a string slice operation."""
436
-
437
- a: StringVar = dataclasses.field(
438
- default_factory=lambda: LiteralStringVar.create("")
439
- )
440
- _slice: slice = dataclasses.field(default_factory=lambda: slice(None, None, None))
441
-
442
- def __init__(
443
- self, a: StringVar | str, _slice: slice, _var_data: VarData | None = None
444
- ):
445
- """Initialize the string slice operation var.
446
-
447
- Args:
448
- a: The string.
449
- _slice: The slice.
450
- _var_data: Additional hooks and imports associated with the Var.
451
- """
452
- super(StringSliceOperation, self).__init__(
453
- _var_name="",
454
- _var_type=str,
455
- _var_data=ImmutableVarData.merge(_var_data),
456
- )
457
- object.__setattr__(
458
- self, "a", a if isinstance(a, Var) else LiteralStringVar.create(a)
459
- )
460
- object.__setattr__(self, "_slice", _slice)
461
- object.__delattr__(self, "_var_name")
462
-
463
- @cached_property
464
- def _cached_var_name(self) -> str:
465
- """The name of the var.
466
-
467
- Returns:
468
- The name of the var.
469
-
470
- Raises:
471
- ValueError: If the slice step is zero.
472
- """
473
- start, end, step = self._slice.start, self._slice.stop, self._slice.step
474
-
475
- if step is not None and step < 0:
476
- actual_start = end + 1 if end is not None else 0
477
- actual_end = start + 1 if start is not None else self.a.length()
478
- return str(
479
- StringSliceOperation(
480
- StringReverseOperation(
481
- StringSliceOperation(self.a, slice(actual_start, actual_end))
482
- ),
483
- slice(None, None, -step),
484
- )
485
- )
486
-
487
- start = (
488
- LiteralVar.create(start)
489
- if start is not None
490
- else ImmutableVar.create_safe("undefined")
491
- )
492
- end = (
493
- LiteralVar.create(end)
494
- if end is not None
495
- else ImmutableVar.create_safe("undefined")
496
- )
497
-
498
- if step is None:
499
- return f"{str(self.a)}.slice({str(start)}, {str(end)})"
500
- if step == 0:
501
- raise ValueError("slice step cannot be zero")
502
- return f"{str(self.a)}.slice({str(start)}, {str(end)}).split('').filter((_, i) => i % {str(step)} === 0).join('')"
503
-
504
- def __getattr__(self, name: str) -> Any:
505
- """Get an attribute of the var.
506
-
507
- Args:
508
- name: The name of the attribute.
509
-
510
- Returns:
511
- The attribute value.
512
- """
513
- if name == "_var_name":
514
- return self._cached_var_name
515
- getattr(super(StringSliceOperation, self), name)
516
-
517
- @cached_property
518
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
519
- """Get all VarData associated with the Var.
520
-
521
- Returns:
522
- The VarData of the components and all of its children.
523
- """
524
- return ImmutableVarData.merge(
525
- self.a._get_all_var_data(),
526
- self.start._get_all_var_data(),
527
- self.end._get_all_var_data(),
528
- self._var_data,
529
- )
530
-
531
- def _get_all_var_data(self) -> ImmutableVarData | None:
532
- return self._cached_get_all_var_data
533
-
534
-
535
371
  @dataclasses.dataclass(
536
372
  eq=False,
537
373
  frozen=True,
@@ -543,9 +379,11 @@ class StringItemOperation(StringVar):
543
379
  a: StringVar = dataclasses.field(
544
380
  default_factory=lambda: LiteralStringVar.create("")
545
381
  )
546
- i: int = dataclasses.field(default=0)
382
+ i: NumberVar = dataclasses.field(default_factory=lambda: LiteralNumberVar(0))
547
383
 
548
- def __init__(self, a: StringVar | str, i: int, _var_data: VarData | None = None):
384
+ def __init__(
385
+ self, a: StringVar | str, i: int | NumberVar, _var_data: VarData | None = None
386
+ ):
549
387
  """Initialize the string item operation var.
550
388
 
551
389
  Args:
@@ -561,7 +399,7 @@ class StringItemOperation(StringVar):
561
399
  object.__setattr__(
562
400
  self, "a", a if isinstance(a, Var) else LiteralStringVar.create(a)
563
401
  )
564
- object.__setattr__(self, "i", i)
402
+ object.__setattr__(self, "i", i if isinstance(i, Var) else LiteralNumberVar(i))
565
403
  object.__delattr__(self, "_var_name")
566
404
 
567
405
  @cached_property
@@ -593,7 +431,9 @@ class StringItemOperation(StringVar):
593
431
  Returns:
594
432
  The VarData of the components and all of its children.
595
433
  """
596
- return ImmutableVarData.merge(self.a._get_all_var_data(), self._var_data)
434
+ return ImmutableVarData.merge(
435
+ self.a._get_all_var_data(), self.i._get_all_var_data(), self._var_data
436
+ )
597
437
 
598
438
  def _get_all_var_data(self) -> ImmutableVarData | None:
599
439
  return self._cached_get_all_var_data
@@ -608,7 +448,7 @@ class ArrayJoinOperation(StringVar):
608
448
  )
609
449
 
610
450
  def __init__(
611
- self, a: ArrayVar | list, b: StringVar | str, _var_data: VarData | None = None
451
+ self, a: ArrayVar, b: StringVar | str, _var_data: VarData | None = None
612
452
  ):
613
453
  """Initialize the array join operation var.
614
454
 
@@ -622,9 +462,7 @@ class ArrayJoinOperation(StringVar):
622
462
  _var_type=str,
623
463
  _var_data=ImmutableVarData.merge(_var_data),
624
464
  )
625
- object.__setattr__(
626
- self, "a", a if isinstance(a, Var) else LiteralArrayVar.create(a)
627
- )
465
+ object.__setattr__(self, "a", a)
628
466
  object.__setattr__(
629
467
  self, "b", b if isinstance(b, Var) else LiteralStringVar.create(b)
630
468
  )
@@ -777,6 +615,22 @@ class LiteralStringVar(LiteralVar, StringVar):
777
615
  _var_data=_var_data,
778
616
  )
779
617
 
618
+ def __hash__(self) -> int:
619
+ """Get the hash of the var.
620
+
621
+ Returns:
622
+ The hash of the var.
623
+ """
624
+ return hash((self.__class__.__name__, self._var_value))
625
+
626
+ def json(self) -> str:
627
+ """Get the JSON representation of the var.
628
+
629
+ Returns:
630
+ The JSON representation of the var.
631
+ """
632
+ return json.dumps(self._var_value)
633
+
780
634
 
781
635
  @dataclasses.dataclass(
782
636
  eq=False,
@@ -861,7 +715,17 @@ class ConcatVarOperation(StringVar):
861
715
  pass
862
716
 
863
717
 
864
- class ArrayVar(ImmutableVar):
718
+ ARRAY_VAR_TYPE = TypeVar("ARRAY_VAR_TYPE", bound=Union[List, Tuple, Set])
719
+
720
+ OTHER_TUPLE = TypeVar("OTHER_TUPLE")
721
+
722
+ INNER_ARRAY_VAR = TypeVar("INNER_ARRAY_VAR")
723
+
724
+ KEY_TYPE = TypeVar("KEY_TYPE")
725
+ VALUE_TYPE = TypeVar("VALUE_TYPE")
726
+
727
+
728
+ class ArrayVar(ImmutableVar[ARRAY_VAR_TYPE]):
865
729
  """Base class for immutable array vars."""
866
730
 
867
731
  from reflex.experimental.vars.sequence import StringVar
@@ -879,13 +743,194 @@ class ArrayVar(ImmutableVar):
879
743
 
880
744
  return ArrayJoinOperation(self, sep)
881
745
 
746
+ def reverse(self) -> ArrayVar[ARRAY_VAR_TYPE]:
747
+ """Reverse the array.
748
+
749
+ Returns:
750
+ The reversed array.
751
+ """
752
+ return ArrayReverseOperation(self)
753
+
754
+ @overload
755
+ def __getitem__(self, i: slice) -> ArrayVar[ARRAY_VAR_TYPE]: ...
756
+
757
+ @overload
758
+ def __getitem__(
759
+ self: (
760
+ ArrayVar[Tuple[int, OTHER_TUPLE]]
761
+ | ArrayVar[Tuple[float, OTHER_TUPLE]]
762
+ | ArrayVar[Tuple[int | float, OTHER_TUPLE]]
763
+ ),
764
+ i: Literal[0, -2],
765
+ ) -> NumberVar: ...
766
+
767
+ @overload
768
+ def __getitem__(
769
+ self: (
770
+ ArrayVar[Tuple[OTHER_TUPLE, int]]
771
+ | ArrayVar[Tuple[OTHER_TUPLE, float]]
772
+ | ArrayVar[Tuple[OTHER_TUPLE, int | float]]
773
+ ),
774
+ i: Literal[1, -1],
775
+ ) -> NumberVar: ...
776
+
777
+ @overload
778
+ def __getitem__(
779
+ self: ArrayVar[Tuple[str, OTHER_TUPLE]], i: Literal[0, -2]
780
+ ) -> StringVar: ...
781
+
782
+ @overload
783
+ def __getitem__(
784
+ self: ArrayVar[Tuple[OTHER_TUPLE, str]], i: Literal[1, -1]
785
+ ) -> StringVar: ...
786
+
787
+ @overload
788
+ def __getitem__(
789
+ self: ArrayVar[Tuple[bool, OTHER_TUPLE]], i: Literal[0, -2]
790
+ ) -> BooleanVar: ...
791
+
792
+ @overload
793
+ def __getitem__(
794
+ self: ArrayVar[Tuple[OTHER_TUPLE, bool]], i: Literal[1, -1]
795
+ ) -> BooleanVar: ...
796
+
797
+ @overload
798
+ def __getitem__(
799
+ self: (
800
+ ARRAY_VAR_OF_LIST_ELEMENT[int]
801
+ | ARRAY_VAR_OF_LIST_ELEMENT[float]
802
+ | ARRAY_VAR_OF_LIST_ELEMENT[int | float]
803
+ ),
804
+ i: int | NumberVar,
805
+ ) -> NumberVar: ...
806
+
807
+ @overload
808
+ def __getitem__(
809
+ self: ARRAY_VAR_OF_LIST_ELEMENT[str], i: int | NumberVar
810
+ ) -> StringVar: ...
811
+
812
+ @overload
813
+ def __getitem__(
814
+ self: ARRAY_VAR_OF_LIST_ELEMENT[bool], i: int | NumberVar
815
+ ) -> BooleanVar: ...
816
+
817
+ @overload
818
+ def __getitem__(
819
+ self: ARRAY_VAR_OF_LIST_ELEMENT[List[INNER_ARRAY_VAR]],
820
+ i: int | NumberVar,
821
+ ) -> ArrayVar[List[INNER_ARRAY_VAR]]: ...
822
+
823
+ @overload
824
+ def __getitem__(
825
+ self: ARRAY_VAR_OF_LIST_ELEMENT[Set[INNER_ARRAY_VAR]],
826
+ i: int | NumberVar,
827
+ ) -> ArrayVar[Set[INNER_ARRAY_VAR]]: ...
828
+
829
+ @overload
830
+ def __getitem__(
831
+ self: ARRAY_VAR_OF_LIST_ELEMENT[Tuple[INNER_ARRAY_VAR, ...]],
832
+ i: int | NumberVar,
833
+ ) -> ArrayVar[Tuple[INNER_ARRAY_VAR, ...]]: ...
834
+
835
+ @overload
836
+ def __getitem__(
837
+ self: ARRAY_VAR_OF_LIST_ELEMENT[Dict[KEY_TYPE, VALUE_TYPE]],
838
+ i: int | NumberVar,
839
+ ) -> ObjectVar[Dict[KEY_TYPE, VALUE_TYPE]]: ...
840
+
841
+ @overload
842
+ def __getitem__(self, i: int | NumberVar) -> ImmutableVar: ...
843
+
844
+ def __getitem__(
845
+ self, i: slice | int | NumberVar
846
+ ) -> ArrayVar[ARRAY_VAR_TYPE] | ImmutableVar:
847
+ """Get a slice of the array.
848
+
849
+ Args:
850
+ i: The slice.
851
+
852
+ Returns:
853
+ The array slice operation.
854
+ """
855
+ if isinstance(i, slice):
856
+ return ArraySliceOperation(self, i)
857
+ return ArrayItemOperation(self, i).guess_type()
858
+
859
+ def length(self) -> NumberVar:
860
+ """Get the length of the array.
861
+
862
+ Returns:
863
+ The length of the array.
864
+ """
865
+ return ArrayLengthOperation(self)
866
+
867
+ @overload
868
+ @classmethod
869
+ def range(cls, stop: int | NumberVar, /) -> ArrayVar[List[int]]: ...
870
+
871
+ @overload
872
+ @classmethod
873
+ def range(
874
+ cls,
875
+ start: int | NumberVar,
876
+ end: int | NumberVar,
877
+ step: int | NumberVar = 1,
878
+ /,
879
+ ) -> ArrayVar[List[int]]: ...
880
+
881
+ @classmethod
882
+ def range(
883
+ cls,
884
+ first_endpoint: int | NumberVar,
885
+ second_endpoint: int | NumberVar | None = None,
886
+ step: int | NumberVar | None = None,
887
+ ) -> ArrayVar[List[int]]:
888
+ """Create a range of numbers.
889
+
890
+ Args:
891
+ first_endpoint: The end of the range if second_endpoint is not provided, otherwise the start of the range.
892
+ second_endpoint: The end of the range.
893
+ step: The step of the range.
894
+
895
+ Returns:
896
+ The range of numbers.
897
+ """
898
+ if second_endpoint is None:
899
+ start = 0
900
+ end = first_endpoint
901
+ else:
902
+ start = first_endpoint
903
+ end = second_endpoint
904
+
905
+ return RangeOperation(start, end, step or 1)
906
+
907
+ def contains(self, other: Any) -> BooleanVar:
908
+ """Check if the array contains an element.
909
+
910
+ Args:
911
+ other: The element to check for.
912
+
913
+ Returns:
914
+ The array contains operation.
915
+ """
916
+ return ArrayContainsOperation(self, other)
917
+
918
+
919
+ LIST_ELEMENT = TypeVar("LIST_ELEMENT")
920
+
921
+ ARRAY_VAR_OF_LIST_ELEMENT = Union[
922
+ ArrayVar[List[LIST_ELEMENT]],
923
+ ArrayVar[Set[LIST_ELEMENT]],
924
+ ArrayVar[Tuple[LIST_ELEMENT, ...]],
925
+ ]
926
+
882
927
 
883
928
  @dataclasses.dataclass(
884
929
  eq=False,
885
930
  frozen=True,
886
931
  **{"slots": True} if sys.version_info >= (3, 10) else {},
887
932
  )
888
- class LiteralArrayVar(LiteralVar, ArrayVar):
933
+ class LiteralArrayVar(LiteralVar, ArrayVar[ARRAY_VAR_TYPE]):
889
934
  """Base class for immutable literal array vars."""
890
935
 
891
936
  _var_value: Union[
@@ -893,20 +938,22 @@ class LiteralArrayVar(LiteralVar, ArrayVar):
893
938
  ] = dataclasses.field(default_factory=list)
894
939
 
895
940
  def __init__(
896
- self,
897
- _var_value: list[Var | Any] | tuple[Var | Any] | set[Var | Any],
941
+ self: LiteralArrayVar[ARRAY_VAR_TYPE],
942
+ _var_value: ARRAY_VAR_TYPE,
943
+ _var_type: type[ARRAY_VAR_TYPE] | None = None,
898
944
  _var_data: VarData | None = None,
899
945
  ):
900
946
  """Initialize the array var.
901
947
 
902
948
  Args:
903
949
  _var_value: The value of the var.
950
+ _var_type: The type of the var.
904
951
  _var_data: Additional hooks and imports associated with the Var.
905
952
  """
906
953
  super(LiteralArrayVar, self).__init__(
907
954
  _var_name="",
908
955
  _var_data=ImmutableVarData.merge(_var_data),
909
- _var_type=list,
956
+ _var_type=(figure_out_type(_var_value) if _var_type is None else _var_type),
910
957
  )
911
958
  object.__setattr__(self, "_var_value", _var_value)
912
959
  object.__delattr__(self, "_var_name")
@@ -963,6 +1010,28 @@ class LiteralArrayVar(LiteralVar, ArrayVar):
963
1010
  """
964
1011
  return self._cached_get_all_var_data
965
1012
 
1013
+ def __hash__(self) -> int:
1014
+ """Get the hash of the var.
1015
+
1016
+ Returns:
1017
+ The hash of the var.
1018
+ """
1019
+ return hash((self.__class__.__name__, self._var_name))
1020
+
1021
+ def json(self) -> str:
1022
+ """Get the JSON representation of the var.
1023
+
1024
+ Returns:
1025
+ The JSON representation of the var.
1026
+ """
1027
+ return (
1028
+ "["
1029
+ + ", ".join(
1030
+ [LiteralVar.create(element).json() for element in self._var_value]
1031
+ )
1032
+ + "]"
1033
+ )
1034
+
966
1035
 
967
1036
  @dataclasses.dataclass(
968
1037
  eq=False,
@@ -991,7 +1060,7 @@ class StringSplitOperation(ArrayVar):
991
1060
  """
992
1061
  super(StringSplitOperation, self).__init__(
993
1062
  _var_name="",
994
- _var_type=list,
1063
+ _var_type=List[str],
995
1064
  _var_data=ImmutableVarData.merge(_var_data),
996
1065
  )
997
1066
  object.__setattr__(
@@ -1037,3 +1106,659 @@ class StringSplitOperation(ArrayVar):
1037
1106
 
1038
1107
  def _get_all_var_data(self) -> ImmutableVarData | None:
1039
1108
  return self._cached_get_all_var_data
1109
+
1110
+
1111
+ @dataclasses.dataclass(
1112
+ eq=False,
1113
+ frozen=True,
1114
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1115
+ )
1116
+ class ArrayToArrayOperation(ArrayVar):
1117
+ """Base class for immutable array vars that are the result of an array to array operation."""
1118
+
1119
+ a: ArrayVar = dataclasses.field(default_factory=lambda: LiteralArrayVar([]))
1120
+
1121
+ def __init__(self, a: ArrayVar, _var_data: VarData | None = None):
1122
+ """Initialize the array to array operation var.
1123
+
1124
+ Args:
1125
+ a: The string.
1126
+ _var_data: Additional hooks and imports associated with the Var.
1127
+ """
1128
+ super(ArrayToArrayOperation, self).__init__(
1129
+ _var_name="",
1130
+ _var_type=a._var_type,
1131
+ _var_data=ImmutableVarData.merge(_var_data),
1132
+ )
1133
+ object.__setattr__(self, "a", a)
1134
+ object.__delattr__(self, "_var_name")
1135
+
1136
+ @cached_property
1137
+ def _cached_var_name(self) -> str:
1138
+ """The name of the var.
1139
+
1140
+ Raises:
1141
+ NotImplementedError: Must be implemented by subclasses.
1142
+ """
1143
+ raise NotImplementedError(
1144
+ "ArrayToArrayOperation must implement _cached_var_name"
1145
+ )
1146
+
1147
+ def __getattr__(self, name: str) -> Any:
1148
+ """Get an attribute of the var.
1149
+
1150
+ Args:
1151
+ name: The name of the attribute.
1152
+
1153
+ Returns:
1154
+ The attribute value.
1155
+ """
1156
+ if name == "_var_name":
1157
+ return self._cached_var_name
1158
+ getattr(super(ArrayToArrayOperation, self), name)
1159
+
1160
+ @cached_property
1161
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1162
+ """Get all VarData associated with the Var.
1163
+
1164
+ Returns:
1165
+ The VarData of the components and all of its children.
1166
+ """
1167
+ return ImmutableVarData.merge(
1168
+ self.a._get_all_var_data() if isinstance(self.a, Var) else None,
1169
+ self._var_data,
1170
+ )
1171
+
1172
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1173
+ return self._cached_get_all_var_data
1174
+
1175
+
1176
+ @dataclasses.dataclass(
1177
+ eq=False,
1178
+ frozen=True,
1179
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1180
+ )
1181
+ class ArraySliceOperation(ArrayVar):
1182
+ """Base class for immutable string vars that are the result of a string slice operation."""
1183
+
1184
+ a: ArrayVar = dataclasses.field(default_factory=lambda: LiteralArrayVar([]))
1185
+ _slice: slice = dataclasses.field(default_factory=lambda: slice(None, None, None))
1186
+
1187
+ def __init__(self, a: ArrayVar, _slice: slice, _var_data: VarData | None = None):
1188
+ """Initialize the string slice operation var.
1189
+
1190
+ Args:
1191
+ a: The string.
1192
+ _slice: The slice.
1193
+ _var_data: Additional hooks and imports associated with the Var.
1194
+ """
1195
+ super(ArraySliceOperation, self).__init__(
1196
+ _var_name="",
1197
+ _var_type=a._var_type,
1198
+ _var_data=ImmutableVarData.merge(_var_data),
1199
+ )
1200
+ object.__setattr__(self, "a", a)
1201
+ object.__setattr__(self, "_slice", _slice)
1202
+ object.__delattr__(self, "_var_name")
1203
+
1204
+ @cached_property
1205
+ def _cached_var_name(self) -> str:
1206
+ """The name of the var.
1207
+
1208
+ Returns:
1209
+ The name of the var.
1210
+
1211
+ Raises:
1212
+ ValueError: If the slice step is zero.
1213
+ """
1214
+ start, end, step = self._slice.start, self._slice.stop, self._slice.step
1215
+
1216
+ normalized_start = (
1217
+ LiteralVar.create(start)
1218
+ if start is not None
1219
+ else ImmutableVar.create_safe("undefined")
1220
+ )
1221
+ normalized_end = (
1222
+ LiteralVar.create(end)
1223
+ if end is not None
1224
+ else ImmutableVar.create_safe("undefined")
1225
+ )
1226
+ if step is None:
1227
+ return (
1228
+ f"{str(self.a)}.slice({str(normalized_start)}, {str(normalized_end)})"
1229
+ )
1230
+ if not isinstance(step, Var):
1231
+ if step < 0:
1232
+ actual_start = end + 1 if end is not None else 0
1233
+ actual_end = start + 1 if start is not None else self.a.length()
1234
+ return str(
1235
+ ArraySliceOperation(
1236
+ ArrayReverseOperation(
1237
+ ArraySliceOperation(self.a, slice(actual_start, actual_end))
1238
+ ),
1239
+ slice(None, None, -step),
1240
+ )
1241
+ )
1242
+ if step == 0:
1243
+ raise ValueError("slice step cannot be zero")
1244
+ return f"{str(self.a)}.slice({str(normalized_start)}, {str(normalized_end)}).filter((_, i) => i % {str(step)} === 0)"
1245
+
1246
+ actual_start_reverse = end + 1 if end is not None else 0
1247
+ actual_end_reverse = start + 1 if start is not None else self.a.length()
1248
+
1249
+ return f"{str(self.step)} > 0 ? {str(self.a)}.slice({str(normalized_start)}, {str(normalized_end)}).filter((_, i) => i % {str(step)} === 0) : {str(self.a)}.slice({str(actual_start_reverse)}, {str(actual_end_reverse)}).reverse().filter((_, i) => i % {str(-step)} === 0)"
1250
+
1251
+ def __getattr__(self, name: str) -> Any:
1252
+ """Get an attribute of the var.
1253
+
1254
+ Args:
1255
+ name: The name of the attribute.
1256
+
1257
+ Returns:
1258
+ The attribute value.
1259
+ """
1260
+ if name == "_var_name":
1261
+ return self._cached_var_name
1262
+ getattr(super(ArraySliceOperation, self), name)
1263
+
1264
+ @cached_property
1265
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1266
+ """Get all VarData associated with the Var.
1267
+
1268
+ Returns:
1269
+ The VarData of the components and all of its children.
1270
+ """
1271
+ return ImmutableVarData.merge(
1272
+ self.a._get_all_var_data(),
1273
+ *[
1274
+ slice_value._get_all_var_data()
1275
+ for slice_value in (
1276
+ self._slice.start,
1277
+ self._slice.stop,
1278
+ self._slice.step,
1279
+ )
1280
+ if slice_value is not None and isinstance(slice_value, Var)
1281
+ ],
1282
+ self._var_data,
1283
+ )
1284
+
1285
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1286
+ return self._cached_get_all_var_data
1287
+
1288
+
1289
+ class ArrayReverseOperation(ArrayToArrayOperation):
1290
+ """Base class for immutable string vars that are the result of a string reverse operation."""
1291
+
1292
+ @cached_property
1293
+ def _cached_var_name(self) -> str:
1294
+ """The name of the var.
1295
+
1296
+ Returns:
1297
+ The name of the var.
1298
+ """
1299
+ return f"{str(self.a)}.reverse()"
1300
+
1301
+
1302
+ @dataclasses.dataclass(
1303
+ eq=False,
1304
+ frozen=True,
1305
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1306
+ )
1307
+ class ArrayToNumberOperation(NumberVar):
1308
+ """Base class for immutable number vars that are the result of an array to number operation."""
1309
+
1310
+ a: ArrayVar = dataclasses.field(
1311
+ default_factory=lambda: LiteralArrayVar([]),
1312
+ )
1313
+
1314
+ def __init__(self, a: ArrayVar, _var_data: VarData | None = None):
1315
+ """Initialize the string to number operation var.
1316
+
1317
+ Args:
1318
+ a: The array.
1319
+ _var_data: Additional hooks and imports associated with the Var.
1320
+ """
1321
+ super(ArrayToNumberOperation, self).__init__(
1322
+ _var_name="",
1323
+ _var_type=int,
1324
+ _var_data=ImmutableVarData.merge(_var_data),
1325
+ )
1326
+ object.__setattr__(self, "a", a if isinstance(a, Var) else LiteralArrayVar(a))
1327
+ object.__delattr__(self, "_var_name")
1328
+
1329
+ @cached_property
1330
+ def _cached_var_name(self) -> str:
1331
+ """The name of the var.
1332
+
1333
+ Raises:
1334
+ NotImplementedError: Must be implemented by subclasses.
1335
+ """
1336
+ raise NotImplementedError(
1337
+ "StringToNumberOperation must implement _cached_var_name"
1338
+ )
1339
+
1340
+ def __getattr__(self, name: str) -> Any:
1341
+ """Get an attribute of the var.
1342
+
1343
+ Args:
1344
+ name: The name of the attribute.
1345
+
1346
+ Returns:
1347
+ The attribute value.
1348
+ """
1349
+ if name == "_var_name":
1350
+ return self._cached_var_name
1351
+ getattr(super(ArrayToNumberOperation, self), name)
1352
+
1353
+ @cached_property
1354
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1355
+ """Get all VarData associated with the Var.
1356
+
1357
+ Returns:
1358
+ The VarData of the components and all of its children.
1359
+ """
1360
+ return ImmutableVarData.merge(self.a._get_all_var_data(), self._var_data)
1361
+
1362
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1363
+ return self._cached_get_all_var_data
1364
+
1365
+
1366
+ class ArrayLengthOperation(ArrayToNumberOperation):
1367
+ """Base class for immutable number vars that are the result of an array length operation."""
1368
+
1369
+ @cached_property
1370
+ def _cached_var_name(self) -> str:
1371
+ """The name of the var.
1372
+
1373
+ Returns:
1374
+ The name of the var.
1375
+ """
1376
+ return f"{str(self.a)}.length"
1377
+
1378
+
1379
+ def is_tuple_type(t: GenericType) -> bool:
1380
+ """Check if a type is a tuple type.
1381
+
1382
+ Args:
1383
+ t: The type to check.
1384
+
1385
+ Returns:
1386
+ Whether the type is a tuple type.
1387
+ """
1388
+ if inspect.isclass(t):
1389
+ return issubclass(t, tuple)
1390
+ return get_origin(t) is tuple
1391
+
1392
+
1393
+ @dataclasses.dataclass(
1394
+ eq=False,
1395
+ frozen=True,
1396
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1397
+ )
1398
+ class ArrayItemOperation(ImmutableVar):
1399
+ """Base class for immutable array vars that are the result of an array item operation."""
1400
+
1401
+ a: ArrayVar = dataclasses.field(default_factory=lambda: LiteralArrayVar([]))
1402
+ i: NumberVar = dataclasses.field(default_factory=lambda: LiteralNumberVar(0))
1403
+
1404
+ def __init__(
1405
+ self,
1406
+ a: ArrayVar,
1407
+ i: NumberVar | int,
1408
+ _var_data: VarData | None = None,
1409
+ ):
1410
+ """Initialize the array item operation var.
1411
+
1412
+ Args:
1413
+ a: The array.
1414
+ i: The index.
1415
+ _var_data: Additional hooks and imports associated with the Var.
1416
+ """
1417
+ args = typing.get_args(a._var_type)
1418
+ if args and isinstance(i, int) and is_tuple_type(a._var_type):
1419
+ element_type = args[i % len(args)]
1420
+ else:
1421
+ element_type = unionize(*args)
1422
+ super(ArrayItemOperation, self).__init__(
1423
+ _var_name="",
1424
+ _var_type=element_type,
1425
+ _var_data=ImmutableVarData.merge(_var_data),
1426
+ )
1427
+ object.__setattr__(self, "a", a if isinstance(a, Var) else LiteralArrayVar(a))
1428
+ object.__setattr__(
1429
+ self,
1430
+ "i",
1431
+ i if isinstance(i, Var) else LiteralNumberVar(i),
1432
+ )
1433
+ object.__delattr__(self, "_var_name")
1434
+
1435
+ @cached_property
1436
+ def _cached_var_name(self) -> str:
1437
+ """The name of the var.
1438
+
1439
+ Returns:
1440
+ The name of the var.
1441
+ """
1442
+ return f"{str(self.a)}.at({str(self.i)})"
1443
+
1444
+ def __getattr__(self, name: str) -> Any:
1445
+ """Get an attribute of the var.
1446
+
1447
+ Args:
1448
+ name: The name of the attribute.
1449
+
1450
+ Returns:
1451
+ The attribute value.
1452
+ """
1453
+ if name == "_var_name":
1454
+ return self._cached_var_name
1455
+ getattr(super(ArrayItemOperation, self), name)
1456
+
1457
+ @cached_property
1458
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1459
+ """Get all VarData associated with the Var.
1460
+
1461
+ Returns:
1462
+ The VarData of the components and all of its children.
1463
+ """
1464
+ return ImmutableVarData.merge(
1465
+ self.a._get_all_var_data(), self.i._get_all_var_data(), self._var_data
1466
+ )
1467
+
1468
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1469
+ return self._cached_get_all_var_data
1470
+
1471
+
1472
+ @dataclasses.dataclass(
1473
+ eq=False,
1474
+ frozen=True,
1475
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1476
+ )
1477
+ class RangeOperation(ArrayVar):
1478
+ """Base class for immutable array vars that are the result of a range operation."""
1479
+
1480
+ start: NumberVar = dataclasses.field(default_factory=lambda: LiteralNumberVar(0))
1481
+ end: NumberVar = dataclasses.field(default_factory=lambda: LiteralNumberVar(0))
1482
+ step: NumberVar = dataclasses.field(default_factory=lambda: LiteralNumberVar(1))
1483
+
1484
+ def __init__(
1485
+ self,
1486
+ start: NumberVar | int,
1487
+ end: NumberVar | int,
1488
+ step: NumberVar | int,
1489
+ _var_data: VarData | None = None,
1490
+ ):
1491
+ """Initialize the range operation var.
1492
+
1493
+ Args:
1494
+ start: The start of the range.
1495
+ end: The end of the range.
1496
+ step: The step of the range.
1497
+ _var_data: Additional hooks and imports associated with the Var.
1498
+ """
1499
+ super(RangeOperation, self).__init__(
1500
+ _var_name="",
1501
+ _var_type=List[int],
1502
+ _var_data=ImmutableVarData.merge(_var_data),
1503
+ )
1504
+ object.__setattr__(
1505
+ self,
1506
+ "start",
1507
+ start if isinstance(start, Var) else LiteralNumberVar(start),
1508
+ )
1509
+ object.__setattr__(
1510
+ self,
1511
+ "end",
1512
+ end if isinstance(end, Var) else LiteralNumberVar(end),
1513
+ )
1514
+ object.__setattr__(
1515
+ self,
1516
+ "step",
1517
+ step if isinstance(step, Var) else LiteralNumberVar(step),
1518
+ )
1519
+ object.__delattr__(self, "_var_name")
1520
+
1521
+ @cached_property
1522
+ def _cached_var_name(self) -> str:
1523
+ """The name of the var.
1524
+
1525
+ Returns:
1526
+ The name of the var.
1527
+ """
1528
+ start, end, step = self.start, self.end, self.step
1529
+ return f"Array.from({{ length: ({str(end)} - {str(start)}) / {str(step)} }}, (_, i) => {str(start)} + i * {str(step)})"
1530
+
1531
+ def __getattr__(self, name: str) -> Any:
1532
+ """Get an attribute of the var.
1533
+
1534
+ Args:
1535
+ name: The name of the attribute.
1536
+
1537
+ Returns:
1538
+ The attribute value.
1539
+ """
1540
+ if name == "_var_name":
1541
+ return self._cached_var_name
1542
+ getattr(super(RangeOperation, self), name)
1543
+
1544
+ @cached_property
1545
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1546
+ """Get all VarData associated with the Var.
1547
+
1548
+ Returns:
1549
+ The VarData of the components and all of its children.
1550
+ """
1551
+ return ImmutableVarData.merge(
1552
+ self.start._get_all_var_data(),
1553
+ self.end._get_all_var_data(),
1554
+ self.step._get_all_var_data(),
1555
+ self._var_data,
1556
+ )
1557
+
1558
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1559
+ return self._cached_get_all_var_data
1560
+
1561
+
1562
+ @dataclasses.dataclass(
1563
+ eq=False,
1564
+ frozen=True,
1565
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1566
+ )
1567
+ class ArrayContainsOperation(BooleanVar):
1568
+ """Base class for immutable boolean vars that are the result of an array contains operation."""
1569
+
1570
+ a: ArrayVar = dataclasses.field(default_factory=lambda: LiteralArrayVar([]))
1571
+ b: Var = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
1572
+
1573
+ def __init__(self, a: ArrayVar, b: Any | Var, _var_data: VarData | None = None):
1574
+ """Initialize the array contains operation var.
1575
+
1576
+ Args:
1577
+ a: The array.
1578
+ b: The element to check for.
1579
+ _var_data: Additional hooks and imports associated with the Var.
1580
+ """
1581
+ super(ArrayContainsOperation, self).__init__(
1582
+ _var_name="",
1583
+ _var_type=bool,
1584
+ _var_data=ImmutableVarData.merge(_var_data),
1585
+ )
1586
+ object.__setattr__(self, "a", a)
1587
+ object.__setattr__(self, "b", b if isinstance(b, Var) else LiteralVar.create(b))
1588
+ object.__delattr__(self, "_var_name")
1589
+
1590
+ @cached_property
1591
+ def _cached_var_name(self) -> str:
1592
+ """The name of the var.
1593
+
1594
+ Returns:
1595
+ The name of the var.
1596
+ """
1597
+ return f"{str(self.a)}.includes({str(self.b)})"
1598
+
1599
+ def __getattr__(self, name: str) -> Any:
1600
+ """Get an attribute of the var.
1601
+
1602
+ Args:
1603
+ name: The name of the attribute.
1604
+
1605
+ Returns:
1606
+ The attribute value.
1607
+ """
1608
+ if name == "_var_name":
1609
+ return self._cached_var_name
1610
+ getattr(super(ArrayContainsOperation, self), name)
1611
+
1612
+ @cached_property
1613
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1614
+ """Get all VarData associated with the Var.
1615
+
1616
+ Returns:
1617
+ The VarData of the components and all of its children.
1618
+ """
1619
+ return ImmutableVarData.merge(
1620
+ self.a._get_all_var_data(), self.b._get_all_var_data(), self._var_data
1621
+ )
1622
+
1623
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1624
+ return self._cached_get_all_var_data
1625
+
1626
+
1627
+ @dataclasses.dataclass(
1628
+ eq=False,
1629
+ frozen=True,
1630
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1631
+ )
1632
+ class ToStringOperation(StringVar):
1633
+ """Base class for immutable string vars that are the result of a to string operation."""
1634
+
1635
+ original_var: Var = dataclasses.field(
1636
+ default_factory=lambda: LiteralStringVar.create("")
1637
+ )
1638
+
1639
+ def __init__(self, original_var: Var, _var_data: VarData | None = None):
1640
+ """Initialize the to string operation var.
1641
+
1642
+ Args:
1643
+ original_var: The original var.
1644
+ _var_data: Additional hooks and imports associated with the Var.
1645
+ """
1646
+ super(ToStringOperation, self).__init__(
1647
+ _var_name="",
1648
+ _var_type=str,
1649
+ _var_data=ImmutableVarData.merge(_var_data),
1650
+ )
1651
+ object.__setattr__(
1652
+ self,
1653
+ "original_var",
1654
+ original_var,
1655
+ )
1656
+ object.__delattr__(self, "_var_name")
1657
+
1658
+ @cached_property
1659
+ def _cached_var_name(self) -> str:
1660
+ """The name of the var.
1661
+
1662
+ Returns:
1663
+ The name of the var.
1664
+ """
1665
+ return str(self.original_var)
1666
+
1667
+ def __getattr__(self, name: str) -> Any:
1668
+ """Get an attribute of the var.
1669
+
1670
+ Args:
1671
+ name: The name of the attribute.
1672
+
1673
+ Returns:
1674
+ The attribute value.
1675
+ """
1676
+ if name == "_var_name":
1677
+ return self._cached_var_name
1678
+ getattr(super(ToStringOperation, self), name)
1679
+
1680
+ @cached_property
1681
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1682
+ """Get all VarData associated with the Var.
1683
+
1684
+ Returns:
1685
+ The VarData of the components and all of its children.
1686
+ """
1687
+ return ImmutableVarData.merge(
1688
+ self.original_var._get_all_var_data(), self._var_data
1689
+ )
1690
+
1691
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1692
+ return self._cached_get_all_var_data
1693
+
1694
+
1695
+ @dataclasses.dataclass(
1696
+ eq=False,
1697
+ frozen=True,
1698
+ **{"slots": True} if sys.version_info >= (3, 10) else {},
1699
+ )
1700
+ class ToArrayOperation(ArrayVar):
1701
+ """Base class for immutable array vars that are the result of a to array operation."""
1702
+
1703
+ original_var: Var = dataclasses.field(default_factory=lambda: LiteralArrayVar([]))
1704
+
1705
+ def __init__(
1706
+ self,
1707
+ original_var: Var,
1708
+ _var_type: type[list] | type[set] | type[tuple] = list,
1709
+ _var_data: VarData | None = None,
1710
+ ):
1711
+ """Initialize the to array operation var.
1712
+
1713
+ Args:
1714
+ original_var: The original var.
1715
+ _var_type: The type of the array.
1716
+ _var_data: Additional hooks and imports associated with the Var.
1717
+ """
1718
+ super(ToArrayOperation, self).__init__(
1719
+ _var_name="",
1720
+ _var_type=_var_type,
1721
+ _var_data=ImmutableVarData.merge(_var_data),
1722
+ )
1723
+ object.__setattr__(
1724
+ self,
1725
+ "original_var",
1726
+ original_var,
1727
+ )
1728
+ object.__delattr__(self, "_var_name")
1729
+
1730
+ @cached_property
1731
+ def _cached_var_name(self) -> str:
1732
+ """The name of the var.
1733
+
1734
+ Returns:
1735
+ The name of the var.
1736
+ """
1737
+ return str(self.original_var)
1738
+
1739
+ def __getattr__(self, name: str) -> Any:
1740
+ """Get an attribute of the var.
1741
+
1742
+ Args:
1743
+ name: The name of the attribute.
1744
+
1745
+ Returns:
1746
+ The attribute value.
1747
+ """
1748
+ if name == "_var_name":
1749
+ return self._cached_var_name
1750
+ getattr(super(ToArrayOperation, self), name)
1751
+
1752
+ @cached_property
1753
+ def _cached_get_all_var_data(self) -> ImmutableVarData | None:
1754
+ """Get all VarData associated with the Var.
1755
+
1756
+ Returns:
1757
+ The VarData of the components and all of its children.
1758
+ """
1759
+ return ImmutableVarData.merge(
1760
+ self.original_var._get_all_var_data(), self._var_data
1761
+ )
1762
+
1763
+ def _get_all_var_data(self) -> ImmutableVarData | None:
1764
+ return self._cached_get_all_var_data