diff --git a/reflex/utils/serializers.py b/reflex/utils/serializers.py index 614257181..9167656f3 100644 --- a/reflex/utils/serializers.py +++ b/reflex/utils/serializers.py @@ -189,16 +189,37 @@ def get_serializer_type(type_: Type) -> Optional[Type]: return None -def has_serializer(type_: Type) -> bool: +def has_serializer(type_: Type, into_type: Type | None = None) -> bool: """Check if there is a serializer for the type. Args: type_: The type to check. + into_type: The type to serialize into. Returns: Whether there is a serializer for the type. """ - return get_serializer(type_) is not None + serializer_for_type = get_serializer(type_) + return serializer_for_type is not None and ( + into_type is None or get_serializer_type(type_) == into_type + ) + + +def can_serialize(type_: Type, into_type: Type | None = None) -> bool: + """Check if there is a serializer for the type. + + Args: + type_: The type to check. + into_type: The type to serialize into. + + Returns: + Whether there is a serializer for the type. + """ + return has_serializer(type_, into_type) or ( + isinstance(type_, type) + and dataclasses.is_dataclass(type_) + and (into_type is None or into_type is dict) + ) @serializer(to=str) @@ -214,7 +235,7 @@ def serialize_type(value: type) -> str: return value.__name__ -@serializer +@serializer(to=dict) def serialize_base(value: Base) -> dict: """Serialize a Base instance. diff --git a/reflex/utils/types.py b/reflex/utils/types.py index 0adbe6162..d58825ed5 100644 --- a/reflex/utils/types.py +++ b/reflex/utils/types.py @@ -303,30 +303,6 @@ def get_property_hint(attr: Any | None) -> GenericType | None: return hints.get("return", None) -def can_access_properties(cls: GenericType) -> bool: - """Check if the class can access properties. - - Args: - cls: The class to check. - - Returns: - Whether the class can access properties. - """ - from reflex.model import Model - - return ( - hasattr(cls, "__fields__") - or (isinstance(cls, type) and issubclass(cls, DeclarativeBase)) - or ( - isinstance(cls, type) - and not is_generic_alias(cls) - and issubclass(cls, Model) - ) - or (is_union(cls) and all(can_access_properties(arg) for arg in get_args(cls))) - or (isinstance(cls, type) and dataclasses.is_dataclass(cls)) - ) - - def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None: """Check if an attribute can be accessed on the cls and return its type. diff --git a/reflex/vars/base.py b/reflex/vars/base.py index 40eb986da..d0e71b871 100644 --- a/reflex/vars/base.py +++ b/reflex/vars/base.py @@ -67,7 +67,6 @@ from reflex.utils.types import ( GenericType, Self, _isinstance, - can_access_properties, get_origin, has_args, unionize, @@ -294,7 +293,7 @@ def can_use_in_object_var(cls: GenericType) -> bool: return ( inspect.isclass(cls) and not issubclass(cls, Var) - and (can_access_properties(cls) or serializers.has_serializer(cls)) + and serializers.can_serialize(cls, dict) )