make object var handle all mapping instead of just dict
This commit is contained in:
parent
5d877d54d0
commit
c3b8e7a5e1
@ -829,6 +829,22 @@ StateBases = get_base_class(StateVar)
|
|||||||
StateIterBases = get_base_class(StateIterVar)
|
StateIterBases = get_base_class(StateIterVar)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_issubclass(cls: Type, cls_check: Type | Tuple[Type, ...]):
|
||||||
|
"""Check if a class is a subclass of another class. Returns False if internal error occurs.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cls: The class to check.
|
||||||
|
cls_check: The class to check against.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Whether the class is a subclass of the other class.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return issubclass(cls, cls_check)
|
||||||
|
except TypeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> bool:
|
def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> bool:
|
||||||
"""Check if a type hint is a subclass of another type hint.
|
"""Check if a type hint is a subclass of another type hint.
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ from reflex.utils.types import (
|
|||||||
_isinstance,
|
_isinstance,
|
||||||
get_origin,
|
get_origin,
|
||||||
has_args,
|
has_args,
|
||||||
|
safe_issubclass,
|
||||||
unionize,
|
unionize,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -686,7 +687,9 @@ class Var(Generic[VAR_TYPE]):
|
|||||||
|
|
||||||
# If the first argument is a python type, we map it to the corresponding Var type.
|
# If the first argument is a python type, we map it to the corresponding Var type.
|
||||||
for var_subclass in _var_subclasses[::-1]:
|
for var_subclass in _var_subclasses[::-1]:
|
||||||
if fixed_output_type in var_subclass.python_types:
|
if fixed_output_type in var_subclass.python_types or safe_issubclass(
|
||||||
|
fixed_output_type, var_subclass.python_types
|
||||||
|
):
|
||||||
return self.to(var_subclass.var_subclass, output)
|
return self.to(var_subclass.var_subclass, output)
|
||||||
|
|
||||||
if fixed_output_type is None:
|
if fixed_output_type is None:
|
||||||
|
@ -8,8 +8,8 @@ import typing
|
|||||||
from inspect import isclass
|
from inspect import isclass
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
Dict,
|
|
||||||
List,
|
List,
|
||||||
|
Mapping,
|
||||||
NoReturn,
|
NoReturn,
|
||||||
Tuple,
|
Tuple,
|
||||||
Type,
|
Type,
|
||||||
@ -36,7 +36,7 @@ from .base import (
|
|||||||
from .number import BooleanVar, NumberVar, raise_unsupported_operand_types
|
from .number import BooleanVar, NumberVar, raise_unsupported_operand_types
|
||||||
from .sequence import ArrayVar, StringVar
|
from .sequence import ArrayVar, StringVar
|
||||||
|
|
||||||
OBJECT_TYPE = TypeVar("OBJECT_TYPE")
|
OBJECT_TYPE = TypeVar("OBJECT_TYPE", covariant=True)
|
||||||
|
|
||||||
KEY_TYPE = TypeVar("KEY_TYPE")
|
KEY_TYPE = TypeVar("KEY_TYPE")
|
||||||
VALUE_TYPE = TypeVar("VALUE_TYPE")
|
VALUE_TYPE = TypeVar("VALUE_TYPE")
|
||||||
@ -46,7 +46,7 @@ ARRAY_INNER_TYPE = TypeVar("ARRAY_INNER_TYPE")
|
|||||||
OTHER_KEY_TYPE = TypeVar("OTHER_KEY_TYPE")
|
OTHER_KEY_TYPE = TypeVar("OTHER_KEY_TYPE")
|
||||||
|
|
||||||
|
|
||||||
class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
|
||||||
"""Base class for immutable object vars."""
|
"""Base class for immutable object vars."""
|
||||||
|
|
||||||
def _key_type(self) -> Type:
|
def _key_type(self) -> Type:
|
||||||
@ -59,7 +59,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
|||||||
|
|
||||||
@overload
|
@overload
|
||||||
def _value_type(
|
def _value_type(
|
||||||
self: ObjectVar[Dict[Any, VALUE_TYPE]],
|
self: ObjectVar[Mapping[Any, VALUE_TYPE]],
|
||||||
) -> Type[VALUE_TYPE]: ...
|
) -> Type[VALUE_TYPE]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -87,7 +87,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
|||||||
|
|
||||||
@overload
|
@overload
|
||||||
def values(
|
def values(
|
||||||
self: ObjectVar[Dict[Any, VALUE_TYPE]],
|
self: ObjectVar[Mapping[Any, VALUE_TYPE]],
|
||||||
) -> ArrayVar[List[VALUE_TYPE]]: ...
|
) -> ArrayVar[List[VALUE_TYPE]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -103,7 +103,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
|||||||
|
|
||||||
@overload
|
@overload
|
||||||
def entries(
|
def entries(
|
||||||
self: ObjectVar[Dict[Any, VALUE_TYPE]],
|
self: ObjectVar[Mapping[Any, VALUE_TYPE]],
|
||||||
) -> ArrayVar[List[Tuple[str, VALUE_TYPE]]]: ...
|
) -> ArrayVar[List[Tuple[str, VALUE_TYPE]]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -133,49 +133,55 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
|||||||
# NoReturn is used here to catch when key value is Any
|
# NoReturn is used here to catch when key value is Any
|
||||||
@overload
|
@overload
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self: ObjectVar[Dict[Any, NoReturn]],
|
self: ObjectVar[Mapping[Any, NoReturn]],
|
||||||
key: Var | Any,
|
key: Var | Any,
|
||||||
) -> Var: ...
|
) -> Var: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __getitem__(
|
||||||
|
self: (ObjectVar[Mapping[Any, bool]]),
|
||||||
|
key: Var | Any,
|
||||||
|
) -> BooleanVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self: (
|
self: (
|
||||||
ObjectVar[Dict[Any, int]]
|
ObjectVar[Mapping[Any, int]]
|
||||||
| ObjectVar[Dict[Any, float]]
|
| ObjectVar[Mapping[Any, float]]
|
||||||
| ObjectVar[Dict[Any, int | float]]
|
| ObjectVar[Mapping[Any, int | float]]
|
||||||
),
|
),
|
||||||
key: Var | Any,
|
key: Var | Any,
|
||||||
) -> NumberVar: ...
|
) -> NumberVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self: ObjectVar[Dict[Any, str]],
|
self: ObjectVar[Mapping[Any, str]],
|
||||||
key: Var | Any,
|
key: Var | Any,
|
||||||
) -> StringVar: ...
|
) -> StringVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self: ObjectVar[Dict[Any, list[ARRAY_INNER_TYPE]]],
|
self: ObjectVar[Mapping[Any, list[ARRAY_INNER_TYPE]]],
|
||||||
key: Var | Any,
|
key: Var | Any,
|
||||||
) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
|
) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self: ObjectVar[Dict[Any, set[ARRAY_INNER_TYPE]]],
|
self: ObjectVar[Mapping[Any, set[ARRAY_INNER_TYPE]]],
|
||||||
key: Var | Any,
|
key: Var | Any,
|
||||||
) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
|
) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self: ObjectVar[Dict[Any, tuple[ARRAY_INNER_TYPE, ...]]],
|
self: ObjectVar[Mapping[Any, tuple[ARRAY_INNER_TYPE, ...]]],
|
||||||
key: Var | Any,
|
key: Var | Any,
|
||||||
) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
|
) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self: ObjectVar[Dict[Any, dict[OTHER_KEY_TYPE, VALUE_TYPE]]],
|
self: ObjectVar[Mapping[Any, Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]],
|
||||||
key: Var | Any,
|
key: Var | Any,
|
||||||
) -> ObjectVar[dict[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
|
) -> ObjectVar[Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
|
||||||
|
|
||||||
def __getitem__(self, key: Var | Any) -> Var:
|
def __getitem__(self, key: Var | Any) -> Var:
|
||||||
"""Get an item from the object.
|
"""Get an item from the object.
|
||||||
@ -195,49 +201,49 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
|||||||
# NoReturn is used here to catch when key value is Any
|
# NoReturn is used here to catch when key value is Any
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
self: ObjectVar[Dict[Any, NoReturn]],
|
self: ObjectVar[Mapping[Any, NoReturn]],
|
||||||
name: str,
|
name: str,
|
||||||
) -> Var: ...
|
) -> Var: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
self: (
|
self: (
|
||||||
ObjectVar[Dict[Any, int]]
|
ObjectVar[Mapping[Any, int]]
|
||||||
| ObjectVar[Dict[Any, float]]
|
| ObjectVar[Mapping[Any, float]]
|
||||||
| ObjectVar[Dict[Any, int | float]]
|
| ObjectVar[Mapping[Any, int | float]]
|
||||||
),
|
),
|
||||||
name: str,
|
name: str,
|
||||||
) -> NumberVar: ...
|
) -> NumberVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
self: ObjectVar[Dict[Any, str]],
|
self: ObjectVar[Mapping[Any, str]],
|
||||||
name: str,
|
name: str,
|
||||||
) -> StringVar: ...
|
) -> StringVar: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
self: ObjectVar[Dict[Any, list[ARRAY_INNER_TYPE]]],
|
self: ObjectVar[Mapping[Any, list[ARRAY_INNER_TYPE]]],
|
||||||
name: str,
|
name: str,
|
||||||
) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
|
) -> ArrayVar[list[ARRAY_INNER_TYPE]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
self: ObjectVar[Dict[Any, set[ARRAY_INNER_TYPE]]],
|
self: ObjectVar[Mapping[Any, set[ARRAY_INNER_TYPE]]],
|
||||||
name: str,
|
name: str,
|
||||||
) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
|
) -> ArrayVar[set[ARRAY_INNER_TYPE]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
self: ObjectVar[Dict[Any, tuple[ARRAY_INNER_TYPE, ...]]],
|
self: ObjectVar[Mapping[Any, tuple[ARRAY_INNER_TYPE, ...]]],
|
||||||
name: str,
|
name: str,
|
||||||
) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
|
) -> ArrayVar[tuple[ARRAY_INNER_TYPE, ...]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
self: ObjectVar[Dict[Any, dict[OTHER_KEY_TYPE, VALUE_TYPE]]],
|
self: ObjectVar[Mapping[Any, Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]],
|
||||||
name: str,
|
name: str,
|
||||||
) -> ObjectVar[dict[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
|
) -> ObjectVar[Mapping[OTHER_KEY_TYPE, VALUE_TYPE]]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __getattr__(
|
def __getattr__(
|
||||||
@ -299,7 +305,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
|
|||||||
class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
|
||||||
"""Base class for immutable literal object vars."""
|
"""Base class for immutable literal object vars."""
|
||||||
|
|
||||||
_var_value: Dict[Union[Var, Any], Union[Var, Any]] = dataclasses.field(
|
_var_value: Mapping[Union[Var, Any], Union[Var, Any]] = dataclasses.field(
|
||||||
default_factory=dict
|
default_factory=dict
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -466,7 +472,7 @@ def object_merge_operation(lhs: ObjectVar, rhs: ObjectVar):
|
|||||||
"""
|
"""
|
||||||
return var_operation_return(
|
return var_operation_return(
|
||||||
js_expression=f"({{...{lhs}, ...{rhs}}})",
|
js_expression=f"({{...{lhs}, ...{rhs}}})",
|
||||||
var_type=Dict[
|
var_type=Mapping[
|
||||||
Union[lhs._key_type(), rhs._key_type()],
|
Union[lhs._key_type(), rhs._key_type()],
|
||||||
Union[lhs._value_type(), rhs._value_type()],
|
Union[lhs._value_type(), rhs._value_type()],
|
||||||
],
|
],
|
||||||
|
@ -987,7 +987,7 @@ class ArrayVar(Var[ARRAY_VAR_TYPE], python_types=(list, tuple, set)):
|
|||||||
raise_unsupported_operand_types("[]", (type(self), type(i)))
|
raise_unsupported_operand_types("[]", (type(self), type(i)))
|
||||||
return array_item_operation(self, i)
|
return array_item_operation(self, i)
|
||||||
|
|
||||||
def length(self) -> NumberVar:
|
def length(self) -> NumberVar[int]:
|
||||||
"""Get the length of the array.
|
"""Get the length of the array.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
Loading…
Reference in New Issue
Block a user