ds_common_serde_py_lib._serializable_convert ============================================ .. py:module:: ds_common_serde_py_lib._serializable_convert .. autoapi-nested-parse:: **File:** ``_serializable_convert.py`` **Region:** ``ds_common_serde_py_lib`` Description ----------- Defines value conversion helpers used by ``Serializable.deserialize()``, including recursive conversion for typed iterables/mappings/unions and support for ``deserialize()``-capable classes. .. rubric:: Example .. code-block:: python from dataclasses import dataclass from ds_common_serde_py_lib import Serializable @dataclass class Child(Serializable): count: int obj = Child.deserialize({"count": "7"}) assert obj.count == 7 Attributes ---------- .. autoapisummary:: ds_common_serde_py_lib._serializable_convert._NOT_SET Functions --------- .. autoapisummary:: ds_common_serde_py_lib._serializable_convert._is_direct_dataclass_serializable ds_common_serde_py_lib._serializable_convert._convert_value ds_common_serde_py_lib._serializable_convert._maybe_deserialize_from_origin ds_common_serde_py_lib._serializable_convert._convert_to_concrete_type ds_common_serde_py_lib._serializable_convert._maybe_deserialize_from_type ds_common_serde_py_lib._serializable_convert._try_construct_from_mapping ds_common_serde_py_lib._serializable_convert._convert_datetime ds_common_serde_py_lib._serializable_convert._convert_typed_iterable ds_common_serde_py_lib._serializable_convert._convert_typed_mapping ds_common_serde_py_lib._serializable_convert._convert_union Module Contents --------------- .. py:function:: _is_direct_dataclass_serializable(cls: type) -> bool True only for classes directly decorated with @dataclass that also inherit Serializable. Implemented with a runtime import to avoid circular imports after splitting the implementation across multiple modules. :param cls: The class to check. :returns: True if the class is a direct dataclass Serializable, False otherwise. .. py:function:: _convert_value(value: Any, type_hint: Any) -> Any Convert ``value`` into the type described by ``type_hint``. This is the main conversion routine used during deserialization. It performs best-effort conversion guided by `type_hint`: - For concrete runtime types (including `Enum`), attempts constructor-based conversion. - For mappings and types that explicitly support `deserialize`, calls `deserialize` when unambiguous. - For typed containers (list/tuple/set/dict), converts contents recursively. - For unions (including Optionals), tries each member until one succeeds. Forward references are intentionally left unresolved to avoid import-time cycles. :param value: The value to convert. :param type_hint: The type to convert the value to. :returns: The converted value (may be unchanged if no applicable conversion strategy is found). .. py:data:: _NOT_SET :type: object .. py:function:: _maybe_deserialize_from_origin(*, value: Any, origin: Any) -> Any Attempt origin-based deserialization for parametrized type hints. This is used for hints where `get_origin(type_hint)` returns a type that may provide a `deserialize` method (or be a direct dataclass `Serializable`). :param value: The raw value to convert. :param origin: The origin type as returned by `typing.get_origin`. :returns: - The deserialized object when applicable. - `_NOT_SET` if this helper does not apply. .. py:function:: _convert_to_concrete_type(*, value: Any, type_hint: type) -> Any Convert `value` to a concrete runtime `type_hint`. Conversion strategy: - Return `value` if it already matches `type_hint`. - If `type_hint` is an `Enum`, construct it from `value`. - If `value` is a mapping and `type_hint` supports `deserialize`, call it. - If `value` is a mapping, try kwarg-based construction from `__init__`. - Special-case `datetime` from ISO strings. - Fall back to `type_hint(value)` construction. :param value: The raw value to convert. :param type_hint: The concrete runtime type to convert to. :returns: The converted value. :raises ValueError: When converting to `datetime` and the value is not convertible. :raises Exception: Any exception raised by enum construction, `deserialize`, or constructors. .. py:function:: _maybe_deserialize_from_type(*, value: Any, type_hint: type) -> Any Attempt deserialization using `type_hint.deserialize` when unambiguous. :param value: The raw value (must be a mapping). :param type_hint: The target class. :returns: - The deserialized object when applicable. - `_NOT_SET` if this helper does not apply. .. py:function:: _try_construct_from_mapping(*, value: collections.abc.Mapping[str, Any], type_hint: type) -> Any Try instantiating `type_hint(**kwargs)` from a mapping. Uses `inspect.signature(type_hint.__init__)` to select keyword args and `typing.get_type_hints(type_hint.__init__)` to recursively convert values. If the signature cannot be inspected, falls back to passing the mapping as kwargs. :param value: Mapping of constructor arguments. :param type_hint: Target class to instantiate. :returns: - An instance of `type_hint` on success. - `_NOT_SET` if construction fails with `TypeError`. .. py:function:: _convert_datetime(*, value: Any) -> datetime.datetime Convert a value to `datetime`. :param value: The input value. :returns: A `datetime` parsed from an ISO-8601 string. :raises ValueError: If `value` is not a string convertible via `datetime.fromisoformat`. .. py:function:: _convert_typed_iterable(*, value: Any, origin: Any, args: tuple[Any, Ellipsis]) -> Any Convert a typed iterable (`list[T]`, `tuple[T]`, `set[T]`, `Iterable[T]`). :param value: The raw iterable value. :param origin: The typing origin. :param args: The typing args. :returns: - The converted container when applicable. - `_NOT_SET` if this helper does not apply. .. py:function:: _convert_typed_mapping(*, value: Any, origin: Any, args: tuple[Any, Ellipsis]) -> Any Convert a typed mapping (`dict[K, V]` / `Mapping[K, V]`). :param value: The raw mapping value. :param origin: The typing origin. :param args: The typing args. :returns: - The converted mapping when applicable. - `_NOT_SET` if this helper does not apply. .. py:function:: _convert_union(*, value: Any, origin: Any, args: tuple[Any, Ellipsis]) -> Any Convert a union (`typing.Union[...]` or PEP 604 `X | Y`). Attempts conversion against each member type in order, returning the first successful conversion. :param value: The raw value to convert. :param origin: The typing origin for the union. :param args: The union member types. :returns: - Converted value when a member conversion succeeds. - `None` when union includes NoneType and `value` is None. - `_NOT_SET` if this helper does not apply. :raises Exception: Re-raises the last conversion error when all non-None members fail.