123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955 |
- """Collection of base classes."""
- from __future__ import annotations
- import dataclasses
- import json
- import re
- import sys
- from functools import cached_property
- from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
- from reflex import constants
- from reflex.base import Base
- from reflex.constants.base import REFLEX_VAR_CLOSING_TAG, REFLEX_VAR_OPENING_TAG
- from reflex.utils import serializers, types
- from reflex.utils.exceptions import VarTypeError
- from reflex.vars import (
- ImmutableVarData,
- Var,
- VarData,
- _decode_var_immutable,
- _extract_var_data,
- _global_vars,
- )
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class ImmutableVar(Var):
- """Base class for immutable vars."""
- # The name of the var.
- _var_name: str = dataclasses.field()
- # The type of the var.
- _var_type: Type = dataclasses.field(default=Any)
- # Extra metadata associated with the Var
- _var_data: Optional[ImmutableVarData] = dataclasses.field(default=None)
- def __str__(self) -> str:
- """String representation of the var. Guaranteed to be a valid Javascript expression.
- Returns:
- The name of the var.
- """
- return self._var_name
- @property
- def _var_is_local(self) -> bool:
- """Whether this is a local javascript variable.
- Returns:
- False
- """
- return False
- @property
- def _var_is_string(self) -> bool:
- """Whether the var is a string literal.
- Returns:
- False
- """
- return False
- @property
- def _var_full_name_needs_state_prefix(self) -> bool:
- """Whether the full name of the var needs a _var_state prefix.
- Returns:
- False
- """
- return False
- def __post_init__(self):
- """Post-initialize the var."""
- # Decode any inline Var markup and apply it to the instance
- _var_data, _var_name = _decode_var_immutable(self._var_name)
- if _var_data:
- self.__init__(
- _var_name,
- self._var_type,
- ImmutableVarData.merge(self._var_data, _var_data),
- )
- def __hash__(self) -> int:
- """Define a hash function for the var.
- Returns:
- The hash of the var.
- """
- return hash((self._var_name, self._var_type, self._var_data))
- def _get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the Var.
- Returns:
- The VarData of the components and all of its children.
- """
- return self._var_data
- def _replace(self, merge_var_data=None, **kwargs: Any):
- """Make a copy of this Var with updated fields.
- Args:
- merge_var_data: VarData to merge into the existing VarData.
- **kwargs: Var fields to update.
- Returns:
- A new ImmutableVar with the updated fields overwriting the corresponding fields in this Var.
- Raises:
- TypeError: If _var_is_local, _var_is_string, or _var_full_name_needs_state_prefix is not None.
- """
- if kwargs.get("_var_is_local", False) is not False:
- raise TypeError(
- "The _var_is_local argument is not supported for ImmutableVar."
- )
- if kwargs.get("_var_is_string", False) is not False:
- raise TypeError(
- "The _var_is_string argument is not supported for ImmutableVar."
- )
- if kwargs.get("_var_full_name_needs_state_prefix", False) is not False:
- raise TypeError(
- "The _var_full_name_needs_state_prefix argument is not supported for ImmutableVar."
- )
- field_values = dict(
- _var_name=kwargs.pop("_var_name", self._var_name),
- _var_type=kwargs.pop("_var_type", self._var_type),
- _var_data=ImmutableVarData.merge(
- kwargs.get("_var_data", self._var_data), merge_var_data
- ),
- )
- return type(self)(**field_values)
- @classmethod
- def create(
- cls,
- value: Any,
- _var_is_local: bool | None = None,
- _var_is_string: bool | None = None,
- _var_data: VarData | None = None,
- ) -> ImmutableVar | Var | None:
- """Create a var from a value.
- Args:
- value: The value to create the var from.
- _var_is_local: Whether the var is local. Deprecated.
- _var_is_string: Whether the var is a string literal. Deprecated.
- _var_data: Additional hooks and imports associated with the Var.
- Returns:
- The var.
- Raises:
- VarTypeError: If the value is JSON-unserializable.
- TypeError: If _var_is_local or _var_is_string is not None.
- """
- if _var_is_local is not None:
- raise TypeError(
- "The _var_is_local argument is not supported for ImmutableVar."
- )
- if _var_is_string is not None:
- raise TypeError(
- "The _var_is_string argument is not supported for ImmutableVar."
- )
- from reflex.utils import format
- # Check for none values.
- if value is None:
- return None
- # If the value is already a var, do nothing.
- if isinstance(value, Var):
- return value
- # Try to pull the imports and hooks from contained values.
- if not isinstance(value, str):
- _var_data = VarData.merge(*_extract_var_data(value), _var_data)
- # Try to serialize the value.
- type_ = type(value)
- if type_ in types.JSONType:
- name = value
- else:
- name, _serialized_type = serializers.serialize(value, get_type=True)
- if name is None:
- raise VarTypeError(
- f"No JSON serializer found for var {value} of type {type_}."
- )
- name = name if isinstance(name, str) else format.json_dumps(name)
- return cls(
- _var_name=name,
- _var_type=type_,
- _var_data=(
- ImmutableVarData(
- state=_var_data.state,
- imports=_var_data.imports,
- hooks=_var_data.hooks,
- )
- if _var_data
- else None
- ),
- )
- @classmethod
- def create_safe(
- cls,
- value: Any,
- _var_is_local: bool | None = None,
- _var_is_string: bool | None = None,
- _var_data: VarData | None = None,
- ) -> Var | ImmutableVar:
- """Create a var from a value, asserting that it is not None.
- Args:
- value: The value to create the var from.
- _var_is_local: Whether the var is local. Deprecated.
- _var_is_string: Whether the var is a string literal. Deprecated.
- _var_data: Additional hooks and imports associated with the Var.
- Returns:
- The var.
- """
- var = cls.create(
- value,
- _var_is_local=_var_is_local,
- _var_is_string=_var_is_string,
- _var_data=_var_data,
- )
- assert var is not None
- return var
- def __format__(self, format_spec: str) -> str:
- """Format the var into a Javascript equivalent to an f-string.
- Args:
- format_spec: The format specifier (Ignored for now).
- Returns:
- The formatted var.
- """
- hashed_var = hash(self)
- _global_vars[hashed_var] = self
- # Encode the _var_data into the formatted output for tracking purposes.
- return f"{REFLEX_VAR_OPENING_TAG}{hashed_var}{REFLEX_VAR_CLOSING_TAG}{self._var_name}"
- class StringVar(ImmutableVar):
- """Base class for immutable string vars."""
- class NumberVar(ImmutableVar):
- """Base class for immutable number vars."""
- class BooleanVar(ImmutableVar):
- """Base class for immutable boolean vars."""
- class ObjectVar(ImmutableVar):
- """Base class for immutable object vars."""
- class ArrayVar(ImmutableVar):
- """Base class for immutable array vars."""
- class FunctionVar(ImmutableVar):
- """Base class for immutable function vars."""
- def __call__(self, *args: Var | Any) -> ArgsFunctionOperation:
- """Call the function with the given arguments.
- Args:
- *args: The arguments to call the function with.
- Returns:
- The function call operation.
- """
- return ArgsFunctionOperation(
- ("...args",),
- VarOperationCall(self, *args, ImmutableVar.create_safe("...args")),
- )
- def call(self, *args: Var | Any) -> VarOperationCall:
- """Call the function with the given arguments.
- Args:
- *args: The arguments to call the function with.
- Returns:
- The function call operation.
- """
- return VarOperationCall(self, *args)
- class FunctionStringVar(FunctionVar):
- """Base class for immutable function vars from a string."""
- def __init__(self, func: str, _var_data: VarData | None = None) -> None:
- """Initialize the function var.
- Args:
- func: The function to call.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(FunctionVar, self).__init__(
- _var_name=func,
- _var_type=Callable,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class VarOperationCall(ImmutableVar):
- """Base class for immutable vars that are the result of a function call."""
- _func: Optional[FunctionVar] = dataclasses.field(default=None)
- _args: Tuple[Union[Var, Any], ...] = dataclasses.field(default_factory=tuple)
- def __init__(
- self, func: FunctionVar, *args: Var | Any, _var_data: VarData | None = None
- ):
- """Initialize the function call var.
- Args:
- func: The function to call.
- *args: The arguments to call the function with.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(VarOperationCall, self).__init__(
- _var_name="",
- _var_type=Callable,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "_func", func)
- object.__setattr__(self, "_args", args)
- object.__delattr__(self, "_var_name")
- def __getattr__(self, name):
- """Get an attribute of the var.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the var.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the var.
- Returns:
- The name of the var.
- """
- return f"({str(self._func)}({', '.join([str(LiteralVar.create(arg)) for arg in self._args])}))"
- @cached_property
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the Var.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- self._func._get_all_var_data() if self._func is not None else None,
- *[var._get_all_var_data() for var in self._args],
- self._var_data,
- )
- def _get_all_var_data(self) -> ImmutableVarData | None:
- """Wrapper method for cached property.
- Returns:
- The VarData of the components and all of its children.
- """
- return self._cached_get_all_var_data
- def __post_init__(self):
- """Post-initialize the var."""
- pass
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class ArgsFunctionOperation(FunctionVar):
- """Base class for immutable function defined via arguments and return expression."""
- _args_names: Tuple[str, ...] = dataclasses.field(default_factory=tuple)
- _return_expr: Union[Var, Any] = dataclasses.field(default=None)
- def __init__(
- self,
- args_names: Tuple[str, ...],
- return_expr: Var | Any,
- _var_data: VarData | None = None,
- ) -> None:
- """Initialize the function with arguments var.
- Args:
- args_names: The names of the arguments.
- return_expr: The return expression of the function.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(ArgsFunctionOperation, self).__init__(
- _var_name=f"",
- _var_type=Callable,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "_args_names", args_names)
- object.__setattr__(self, "_return_expr", return_expr)
- object.__delattr__(self, "_var_name")
- def __getattr__(self, name):
- """Get an attribute of the var.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the var.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the var.
- Returns:
- The name of the var.
- """
- return f"(({', '.join(self._args_names)}) => ({str(LiteralVar.create(self._return_expr))}))"
- @cached_property
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the Var.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- self._return_expr._get_all_var_data(),
- self._var_data,
- )
- def _get_all_var_data(self) -> ImmutableVarData | None:
- """Wrapper method for cached property.
- Returns:
- The VarData of the components and all of its children.
- """
- return self._cached_get_all_var_data
- def __post_init__(self):
- """Post-initialize the var."""
- class LiteralVar(ImmutableVar):
- """Base class for immutable literal vars."""
- @classmethod
- def create(
- cls,
- value: Any,
- _var_data: VarData | None = None,
- ) -> Var:
- """Create a var from a value.
- Args:
- value: The value to create the var from.
- _var_data: Additional hooks and imports associated with the Var.
- Returns:
- The var.
- Raises:
- TypeError: If the value is not a supported type for LiteralVar.
- """
- if isinstance(value, Var):
- if _var_data is None:
- return value
- return value._replace(merge_var_data=_var_data)
- if value is None:
- return ImmutableVar.create_safe("null", _var_data=_var_data)
- if isinstance(value, Base):
- return LiteralObjectVar(
- value.dict(), _var_type=type(value), _var_data=_var_data
- )
- if isinstance(value, str):
- return LiteralStringVar.create(value, _var_data=_var_data)
- constructor = type_mapping.get(type(value))
- if constructor is None:
- raise TypeError(f"Unsupported type {type(value)} for LiteralVar.")
- return constructor(value, _var_data=_var_data)
- def __post_init__(self):
- """Post-initialize the var."""
- # Compile regex for finding reflex var tags.
- _decode_var_pattern_re = (
- rf"{constants.REFLEX_VAR_OPENING_TAG}(.*?){constants.REFLEX_VAR_CLOSING_TAG}"
- )
- _decode_var_pattern = re.compile(_decode_var_pattern_re, flags=re.DOTALL)
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class LiteralStringVar(LiteralVar):
- """Base class for immutable literal string vars."""
- _var_value: str = dataclasses.field(default="")
- def __init__(
- self,
- _var_value: str,
- _var_data: VarData | None = None,
- ):
- """Initialize the string var.
- Args:
- _var_value: The value of the var.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(LiteralStringVar, self).__init__(
- _var_name=f'"{_var_value}"',
- _var_type=str,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "_var_value", _var_value)
- @classmethod
- def create(
- cls,
- value: str,
- _var_data: VarData | None = None,
- ) -> LiteralStringVar | ConcatVarOperation:
- """Create a var from a string value.
- Args:
- value: The value to create the var from.
- _var_data: Additional hooks and imports associated with the Var.
- Returns:
- The var.
- """
- if REFLEX_VAR_OPENING_TAG in value:
- strings_and_vals: list[Var | str] = []
- offset = 0
- # Initialize some methods for reading json.
- var_data_config = VarData().__config__
- def json_loads(s):
- try:
- return var_data_config.json_loads(s)
- except json.decoder.JSONDecodeError:
- return var_data_config.json_loads(
- var_data_config.json_loads(f'"{s}"')
- )
- # Find all tags.
- while m := _decode_var_pattern.search(value):
- start, end = m.span()
- if start > 0:
- strings_and_vals.append(value[:start])
- serialized_data = m.group(1)
- if serialized_data[1:].isnumeric():
- # This is a global immutable var.
- var = _global_vars[int(serialized_data)]
- strings_and_vals.append(var)
- value = value[(end + len(var._var_name)) :]
- else:
- data = json_loads(serialized_data)
- string_length = data.pop("string_length", None)
- var_data = VarData.parse_obj(data)
- # Use string length to compute positions of interpolations.
- if string_length is not None:
- realstart = start + offset
- var_data.interpolations = [
- (realstart, realstart + string_length)
- ]
- strings_and_vals.append(
- ImmutableVar.create_safe(
- value[end : (end + string_length)], _var_data=var_data
- )
- )
- value = value[(end + string_length) :]
- offset += end - start
- if value:
- strings_and_vals.append(value)
- return ConcatVarOperation(*strings_and_vals, _var_data=_var_data)
- return LiteralStringVar(
- value,
- _var_data=_var_data,
- )
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class ConcatVarOperation(StringVar):
- """Representing a concatenation of literal string vars."""
- _var_value: Tuple[Union[Var, str], ...] = dataclasses.field(default_factory=tuple)
- def __init__(self, *value: Var | str, _var_data: VarData | None = None):
- """Initialize the operation of concatenating literal string vars.
- Args:
- value: The values to concatenate.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(ConcatVarOperation, self).__init__(
- _var_name="", _var_data=ImmutableVarData.merge(_var_data), _var_type=str
- )
- object.__setattr__(self, "_var_value", value)
- object.__delattr__(self, "_var_name")
- def __getattr__(self, name):
- """Get an attribute of the var.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the var.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the var.
- Returns:
- The name of the var.
- """
- return (
- "("
- + "+".join(
- [
- str(element) if isinstance(element, Var) else f'"{element}"'
- for element in self._var_value
- ]
- )
- + ")"
- )
- @cached_property
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the Var.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- *[
- var._get_all_var_data()
- for var in self._var_value
- if isinstance(var, Var)
- ],
- self._var_data,
- )
- def _get_all_var_data(self) -> ImmutableVarData | None:
- """Wrapper method for cached property.
- Returns:
- The VarData of the components and all of its children.
- """
- return self._cached_get_all_var_data
- def __post_init__(self):
- """Post-initialize the var."""
- pass
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class LiteralBooleanVar(LiteralVar):
- """Base class for immutable literal boolean vars."""
- _var_value: bool = dataclasses.field(default=False)
- def __init__(
- self,
- _var_value: bool,
- _var_data: VarData | None = None,
- ):
- """Initialize the boolean var.
- Args:
- _var_value: The value of the var.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(LiteralBooleanVar, self).__init__(
- _var_name="true" if _var_value else "false",
- _var_type=bool,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "_var_value", _var_value)
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class LiteralNumberVar(LiteralVar):
- """Base class for immutable literal number vars."""
- _var_value: float | int = dataclasses.field(default=0)
- def __init__(
- self,
- _var_value: float | int,
- _var_data: VarData | None = None,
- ):
- """Initialize the number var.
- Args:
- _var_value: The value of the var.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(LiteralNumberVar, self).__init__(
- _var_name=str(_var_value),
- _var_type=type(_var_value),
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "_var_value", _var_value)
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class LiteralObjectVar(LiteralVar):
- """Base class for immutable literal object vars."""
- _var_value: Dict[Union[Var, Any], Union[Var, Any]] = dataclasses.field(
- default_factory=dict
- )
- def __init__(
- self,
- _var_value: dict[Var | Any, Var | Any],
- _var_type: Type = dict,
- _var_data: VarData | None = None,
- ):
- """Initialize the object var.
- Args:
- _var_value: The value of the var.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(LiteralObjectVar, self).__init__(
- _var_name="",
- _var_type=_var_type,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(
- self,
- "_var_value",
- _var_value,
- )
- object.__delattr__(self, "_var_name")
- def __getattr__(self, name):
- """Get an attribute of the var.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the var.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the var.
- Returns:
- The name of the var.
- """
- return (
- "{ "
- + ", ".join(
- [
- f"[{str(LiteralVar.create(key))}] : {str(LiteralVar.create(value))}"
- for key, value in self._var_value.items()
- ]
- )
- + " }"
- )
- @cached_property
- def _get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the Var.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- *[
- value._get_all_var_data()
- for key, value in self._var_value
- if isinstance(value, Var)
- ],
- *[
- key._get_all_var_data()
- for key, value in self._var_value
- if isinstance(key, Var)
- ],
- self._var_data,
- )
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class LiteralArrayVar(LiteralVar):
- """Base class for immutable literal array vars."""
- _var_value: Union[
- List[Union[Var, Any]], Set[Union[Var, Any]], Tuple[Union[Var, Any], ...]
- ] = dataclasses.field(default_factory=list)
- def __init__(
- self,
- _var_value: list[Var | Any] | tuple[Var | Any] | set[Var | Any],
- _var_data: VarData | None = None,
- ):
- """Initialize the array var.
- Args:
- _var_value: The value of the var.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(LiteralArrayVar, self).__init__(
- _var_name="",
- _var_data=ImmutableVarData.merge(_var_data),
- _var_type=list,
- )
- object.__setattr__(self, "_var_value", _var_value)
- object.__delattr__(self, "_var_name")
- def __getattr__(self, name):
- """Get an attribute of the var.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the var.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the var.
- Returns:
- The name of the var.
- """
- return (
- "["
- + ", ".join(
- [str(LiteralVar.create(element)) for element in self._var_value]
- )
- + "]"
- )
- @cached_property
- def _get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the Var.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- *[
- var._get_all_var_data()
- for var in self._var_value
- if isinstance(var, Var)
- ],
- self._var_data,
- )
- type_mapping = {
- int: LiteralNumberVar,
- float: LiteralNumberVar,
- bool: LiteralBooleanVar,
- dict: LiteralObjectVar,
- list: LiteralArrayVar,
- tuple: LiteralArrayVar,
- set: LiteralArrayVar,
- }
|