summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/litestar/dto/data_structures.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.11/site-packages/litestar/dto/data_structures.py')
-rw-r--r--venv/lib/python3.11/site-packages/litestar/dto/data_structures.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/venv/lib/python3.11/site-packages/litestar/dto/data_structures.py b/venv/lib/python3.11/site-packages/litestar/dto/data_structures.py
new file mode 100644
index 0000000..a5c3386
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/litestar/dto/data_structures.py
@@ -0,0 +1,116 @@
+from __future__ import annotations
+
+from dataclasses import dataclass
+from typing import TYPE_CHECKING, Generic, TypeVar
+
+from litestar.typing import FieldDefinition
+
+if TYPE_CHECKING:
+ from typing import Any, Callable
+
+ from litestar.dto import DTOField
+ from litestar.dto._backend import DTOBackend
+
+T = TypeVar("T")
+
+
+class DTOData(Generic[T]):
+ """DTO validated data and utility methods."""
+
+ __slots__ = ("_backend", "_data_as_builtins")
+
+ def __init__(self, backend: DTOBackend, data_as_builtins: Any) -> None:
+ self._backend = backend
+ self._data_as_builtins = data_as_builtins
+
+ def create_instance(self, **kwargs: Any) -> T:
+ """Create an instance of the DTO validated data.
+
+ Args:
+ **kwargs: Additional data to create the instance with. Takes precedence over DTO validated data.
+ """
+ data = dict(self._data_as_builtins)
+ for k, v in kwargs.items():
+ _set_nested_dict_value(data, k.split("__"), v)
+ return self._backend.transfer_data_from_builtins(data) # type: ignore[no-any-return]
+
+ def update_instance(self, instance: T, **kwargs: Any) -> T:
+ """Update an instance with the DTO validated data.
+
+ Args:
+ instance: The instance to update.
+ **kwargs: Additional data to update the instance with. Takes precedence over DTO validated data.
+ """
+ data = {**self._data_as_builtins, **kwargs}
+ for k, v in data.items():
+ setattr(instance, k, v)
+ return instance
+
+ def as_builtins(self) -> Any:
+ """Return the DTO validated data as builtins."""
+ return self._data_as_builtins
+
+
+def _set_nested_dict_value(d: dict[str, Any], keys: list[str], value: Any) -> None:
+ if len(keys) == 1:
+ d[keys[0]] = value
+ else:
+ key = keys[0]
+ d.setdefault(key, {})
+ _set_nested_dict_value(d[key], keys[1:], value)
+
+
+@dataclass(frozen=True)
+class DTOFieldDefinition(FieldDefinition):
+ """A model field representation for purposes of generating a DTO backend model type."""
+
+ __slots__ = (
+ "default_factory",
+ "dto_field",
+ "model_name",
+ )
+
+ model_name: str
+ """The name of the model for which the field is generated."""
+ default_factory: Callable[[], Any] | None
+ """Default factory of the field."""
+ dto_field: DTOField
+ """DTO field configuration."""
+
+ @classmethod
+ def from_field_definition(
+ cls,
+ field_definition: FieldDefinition,
+ model_name: str,
+ default_factory: Callable[[], Any] | None,
+ dto_field: DTOField,
+ ) -> DTOFieldDefinition:
+ """Create a :class:`FieldDefinition` from a :class:`FieldDefinition`.
+
+ Args:
+ field_definition: A :class:`FieldDefinition` to create a :class:`FieldDefinition` from.
+ model_name: The name of the model.
+ default_factory: Default factory function, if any.
+ dto_field: DTOField instance.
+
+ Returns:
+ A :class:`FieldDefinition` instance.
+ """
+ return DTOFieldDefinition(
+ annotation=field_definition.annotation,
+ args=field_definition.args,
+ default=field_definition.default,
+ default_factory=default_factory,
+ dto_field=dto_field,
+ extra=field_definition.extra,
+ inner_types=field_definition.inner_types,
+ instantiable_origin=field_definition.instantiable_origin,
+ kwarg_definition=field_definition.kwarg_definition,
+ metadata=field_definition.metadata,
+ model_name=model_name,
+ name=field_definition.name,
+ origin=field_definition.origin,
+ raw=field_definition.raw,
+ safe_generic_origin=field_definition.safe_generic_origin,
+ type_wrappers=field_definition.type_wrappers,
+ )