123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 |
- """Classes for immutable object vars."""
- from __future__ import annotations
- import dataclasses
- import sys
- import typing
- from functools import cached_property
- from typing import Any, Dict, List, Tuple, Type, Union
- from reflex.experimental.vars.base import ImmutableVar, LiteralVar
- from reflex.experimental.vars.sequence import ArrayVar, unionize
- from reflex.vars import ImmutableVarData, Var, VarData
- class ObjectVar(ImmutableVar):
- """Base class for immutable object vars."""
- def _key_type(self) -> Type:
- """Get the type of the keys of the object.
- Returns:
- The type of the keys of the object.
- """
- return ImmutableVar
- def _value_type(self) -> Type:
- """Get the type of the values of the object.
- Returns:
- The type of the values of the object.
- """
- return ImmutableVar
- def keys(self) -> ObjectKeysOperation:
- """Get the keys of the object.
- Returns:
- The keys of the object.
- """
- return ObjectKeysOperation(self)
- def values(self) -> ObjectValuesOperation:
- """Get the values of the object.
- Returns:
- The values of the object.
- """
- return ObjectValuesOperation(self)
- def entries(self) -> ObjectEntriesOperation:
- """Get the entries of the object.
- Returns:
- The entries of the object.
- """
- return ObjectEntriesOperation(self)
- def merge(self, other: ObjectVar) -> ObjectMergeOperation:
- """Merge two objects.
- Args:
- other: The other object to merge.
- Returns:
- The merged object.
- """
- return ObjectMergeOperation(self, other)
- def __getitem__(self, key: Var | Any) -> ImmutableVar:
- """Get an item from the object.
- Args:
- key: The key to get from the object.
- Returns:
- The item from the object.
- """
- return ObjectItemOperation(self, key).guess_type()
- def __getattr__(self, name) -> ObjectItemOperation:
- """Get an attribute of the var.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the var.
- """
- return ObjectItemOperation(self, name)
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class LiteralObjectVar(LiteralVar, ObjectVar):
- """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 | None = None,
- _var_data: VarData | None = None,
- ):
- """Initialize the object var.
- Args:
- _var_value: The value of the var.
- _var_type: The type of the var.
- _var_data: Additional hooks and imports associated with the Var.
- """
- super(LiteralObjectVar, self).__init__(
- _var_name="",
- _var_type=(
- Dict[
- unionize(*map(type, _var_value.keys())),
- unionize(*map(type, _var_value.values())),
- ]
- if _var_type is None
- else _var_type
- ),
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(
- self,
- "_var_value",
- _var_value,
- )
- object.__delattr__(self, "_var_name")
- def _key_type(self) -> Type:
- """Get the type of the keys of the object.
- Returns:
- The type of the keys of the object.
- """
- args_list = typing.get_args(self._var_type)
- return args_list[0] if args_list else Any
- def _value_type(self) -> Type:
- """Get the type of the values of the object.
- Returns:
- The type of the values of the object.
- """
- args_list = typing.get_args(self._var_type)
- return args_list[1] if args_list else Any
- 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 _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(
- *[
- 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,
- )
- 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 json(self) -> str:
- """Get the JSON representation of the object.
- Returns:
- The JSON representation of the object.
- """
- return (
- "{"
- + ", ".join(
- [
- f"{LiteralVar.create(key).json()}:{LiteralVar.create(value).json()}"
- for key, value in self._var_value.items()
- ]
- )
- + "}"
- )
- def __hash__(self) -> int:
- """Get the hash of the var.
- Returns:
- The hash of the var.
- """
- return hash((self.__class__.__name__, self._var_name))
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class ObjectToArrayOperation(ArrayVar):
- """Base class for object to array operations."""
- value: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
- def __init__(
- self,
- _var_value: ObjectVar,
- _var_type: Type = list,
- _var_data: VarData | None = None,
- ):
- """Initialize the object to array operation.
- Args:
- _var_value: The value of the operation.
- _var_data: Additional hooks and imports associated with the operation.
- """
- super(ObjectToArrayOperation, self).__init__(
- _var_name="",
- _var_type=_var_type,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "value", _var_value)
- object.__delattr__(self, "_var_name")
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the operation.
- Raises:
- NotImplementedError: Must implement _cached_var_name.
- """
- raise NotImplementedError(
- "ObjectToArrayOperation must implement _cached_var_name"
- )
- def __getattr__(self, name):
- """Get an attribute of the operation.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the operation.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the operation.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- self.value._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
- class ObjectKeysOperation(ObjectToArrayOperation):
- """Operation to get the keys of an object."""
- def __init__(
- self,
- value: ObjectVar,
- _var_data: VarData | None = None,
- ):
- """Initialize the object keys operation.
- Args:
- value: The value of the operation.
- _var_data: Additional hooks and imports associated with the operation.
- """
- super(ObjectKeysOperation, self).__init__(
- value, List[value._key_type()], _var_data
- )
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the operation.
- Returns:
- The name of the operation.
- """
- return f"Object.keys({self.value._var_name})"
- class ObjectValuesOperation(ObjectToArrayOperation):
- """Operation to get the values of an object."""
- def __init__(
- self,
- value: ObjectVar,
- _var_data: VarData | None = None,
- ):
- """Initialize the object values operation.
- Args:
- value: The value of the operation.
- _var_data: Additional hooks and imports associated with the operation.
- """
- super(ObjectValuesOperation, self).__init__(
- value, List[value._value_type()], _var_data
- )
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the operation.
- Returns:
- The name of the operation.
- """
- return f"Object.values({self.value._var_name})"
- class ObjectEntriesOperation(ObjectToArrayOperation):
- """Operation to get the entries of an object."""
- def __init__(
- self,
- value: ObjectVar,
- _var_data: VarData | None = None,
- ):
- """Initialize the object entries operation.
- Args:
- value: The value of the operation.
- _var_data: Additional hooks and imports associated with the operation.
- """
- super(ObjectEntriesOperation, self).__init__(
- value, List[Tuple[value._key_type(), value._value_type()]], _var_data
- )
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the operation.
- Returns:
- The name of the operation.
- """
- return f"Object.entries({self.value._var_name})"
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class ObjectMergeOperation(ObjectVar):
- """Operation to merge two objects."""
- left: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
- right: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
- def __init__(
- self,
- left: ObjectVar,
- right: ObjectVar,
- _var_data: VarData | None = None,
- ):
- """Initialize the object merge operation.
- Args:
- left: The left object to merge.
- right: The right object to merge.
- _var_data: Additional hooks and imports associated with the operation.
- """
- super(ObjectMergeOperation, self).__init__(
- _var_name="",
- _var_type=left._var_type,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "left", left)
- object.__setattr__(self, "right", right)
- object.__delattr__(self, "_var_name")
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the operation.
- Returns:
- The name of the operation.
- """
- return f"Object.assign({self.left._var_name}, {self.right._var_name})"
- def __getattr__(self, name):
- """Get an attribute of the operation.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the operation.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the operation.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- self.left._get_all_var_data(),
- self.right._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
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class ObjectItemOperation(ImmutableVar):
- """Operation to get an item from an object."""
- value: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
- key: Var | Any = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
- def __init__(
- self,
- value: ObjectVar,
- key: Var | Any,
- _var_data: VarData | None = None,
- ):
- """Initialize the object item operation.
- Args:
- value: The value of the operation.
- key: The key to get from the object.
- _var_data: Additional hooks and imports associated with the operation.
- """
- super(ObjectItemOperation, self).__init__(
- _var_name="",
- _var_type=value._value_type(),
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "value", value)
- object.__setattr__(
- self, "key", key if isinstance(key, Var) else LiteralVar.create(key)
- )
- object.__delattr__(self, "_var_name")
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the operation.
- Returns:
- The name of the operation.
- """
- return f"{str(self.value)}[{str(self.key)}]"
- def __getattr__(self, name):
- """Get an attribute of the operation.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the operation.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the operation.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- self.value._get_all_var_data(),
- self.key._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
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- **{"slots": True} if sys.version_info >= (3, 10) else {},
- )
- class ToObjectOperation(ObjectVar):
- """Operation to convert a var to an object."""
- _original_var: Var = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
- def __init__(
- self,
- _original_var: Var,
- _var_type: Type = dict,
- _var_data: VarData | None = None,
- ):
- """Initialize the to object operation.
- Args:
- _original_var: The original var to convert.
- _var_type: The type of the var.
- _var_data: Additional hooks and imports associated with the operation.
- """
- super(ToObjectOperation, self).__init__(
- _var_name="",
- _var_type=_var_type,
- _var_data=ImmutableVarData.merge(_var_data),
- )
- object.__setattr__(self, "_original_var", _original_var)
- object.__delattr__(self, "_var_name")
- @cached_property
- def _cached_var_name(self) -> str:
- """The name of the operation.
- Returns:
- The name of the operation.
- """
- return str(self._original_var)
- def __getattr__(self, name):
- """Get an attribute of the operation.
- Args:
- name: The name of the attribute.
- Returns:
- The attribute of the operation.
- """
- if name == "_var_name":
- return self._cached_var_name
- return super(type(self), self).__getattr__(name)
- @cached_property
- def _cached_get_all_var_data(self) -> ImmutableVarData | None:
- """Get all VarData associated with the operation.
- Returns:
- The VarData of the components and all of its children.
- """
- return ImmutableVarData.merge(
- self._original_var._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
|