rwskit.dataclasses_ =================== .. py:module:: rwskit.dataclasses_ Attributes ---------- .. autoapisummary:: rwskit.dataclasses_.log rwskit.dataclasses_.D Classes ------- .. autoapisummary:: rwskit.dataclasses_.DataclassRegistry rwskit.dataclasses_.FrozenDataclassMeta rwskit.dataclasses_.EnforceFrozenDataclassMeta Functions --------- .. autoapisummary:: rwskit.dataclasses_.immutable_dataclass rwskit.dataclasses_.is_frozen rwskit.dataclasses_.has_default_value rwskit.dataclasses_.is_optional rwskit.dataclasses_.is_required rwskit.dataclasses_.resolve_type_hints rwskit.dataclasses_.construct_dataclass Module Contents --------------- .. py:data:: log .. py:data:: D A type intended to represent a dataclass. .. py:function:: immutable_dataclass(cls: Type[D]) A decorator to convert a class to a frozen keyword only pydantic dataclass. .. py:function:: is_frozen(cls: Type) -> bool Checks if a class is a frozen dataclass. This will return ``True`` if the input ``cls`` is both a dataclass (either ``dataclasses.dataclass`` or ``pydantic.dataclasses.dataclass``) and it is frozen. .. py:function:: has_default_value(field: dataclasses.Field) -> bool Checks if a ``field`` has a default value. :param field: The field to check. :type field: Field :returns: ``True`` if the field has a default value either directly or via a default factory. :rtype: bool .. py:function:: is_optional(field: dataclasses.Field) -> bool Checks if a ``field`` is optional. :param field: The field to check. :type field: Field :returns: ``True`` if the field is optional. :rtype: bool .. py:function:: is_required(field: dataclasses.Field) -> bool Checks if a ``field`` is required. A field is required if it is not optional and does not have a default value. :param field: The field to check, :type field: Field :returns: ``True`` if the field is required. :rtype: bool .. py:function:: resolve_type_hints(cls: Type[Any], type_map: Optional[dict[str, Type[Any]]] = None, max_tries: int = 50) -> dict[str, Any] Try to resolve the type hints for a dataclass. Sometimes func:`typing.get_type_hints` fails with a ``NameError`` when the type hint has not already been imported. This method will try to catch those errors and dynamically import the unresolved class. :param cls: The dataclass to resolve the type hints for. :type cls: Type[Any] :param type_map: Additional mappings from string names to type classes, which can be used in addition to ``globals()`` for resolving type hint classes. :type type_map: dict[str, Type[Any]], optional :param max_tries: The maximum number of times the method will try to resolve missing type hints. :type max_tries: int :returns: The dictionary containing the resolved type hints. :rtype: dict[str, Any] :raises icontract.ViolationError: If the input ``cls`` is not a dataclass. .. py:function:: construct_dataclass(data: Mapping[str, Any], dataclass_type: Type[D], type_map: Optional[dict[str, Any]] = None) -> D Construct a dataclass from a mapping. Try to construct a possibly nested dataclass of ``dataclass_type`` from a mapping provided by ``data``. If the dataclass cannot be constructed from the data a ``TypeError`` will be raised. :param data: The dictionary (or other mapping) to try to convert. :type data: Mapping[str, Any] :param dataclass_type: The dataclass type we will try to construct. :type dataclass_type: Type[D] :param type_map: By default this method will use ``globals()`` to try to resolve the type hints for the dataclass fields. You can specify any additional mappings with ``type_map`` which will be appended to the default. :type type_map: dict[str, Any], optional :returns: The dataclass object we have constructed. :rtype: D :raises icontract.ViolationError: If the ``dataclass_type`` is not a dataclass. :raises TypeError: If the dictionary cannot be converted to the dataclass type. .. py:class:: DataclassRegistry Initialize the registry. .. py:attribute:: registered_classes :type: set[Type[D]] .. py:method:: __iter__() -> Iterator[Type[D]] .. py:method:: __len__() -> int .. py:method:: register(*classes: Type[D]) Add a class to the registry. :param classes: The class or classes to add. :type classes: Type[D] .. py:method:: construct_registered_dataclass(data: Mapping[str, Any], type_map: Optional[dict[str, Any]] = None) -> D Try to construct one of the registered dataclasses from the given data. :param data: The data to use for constructing a dataclass. :type data: Mapping[str, Any] :param type_map: Additional types that should be made available (imported) when resolving type hints for the registered dataclasses. :type type_map: dict[str, Any], optional :returns: An instance of a registered dataclass that is compatible with the given data. :rtype: D :raises icontract.ViolationError: If ``data`` does not contain values for all required attributes of the dataclass (or any nested dataclass). :raises icontract.ViolationError: If ``data`` is not a :class:`~typing.Mapping`. :raises ValueError: If a registered dataclass cannot be constructed from the data. .. py:class:: FrozenDataclassMeta Bases: :py:obj:`type` Turn the class into a ``pydantic`` dataclass if it is not one already. .. note:: Although this will turn any class that uses it into a ``pydantic`` dataclass, it will cause most linters (including PyCharm) to issue unresolved attribute warnings for all attributes. .. py:class:: EnforceFrozenDataclassMeta Bases: :py:obj:`type` Requires that the class must be a standard or pydantic dataclass. Any class using this metaclass is not a frozen dataclass will raise a ``TypeError`` exception. .. note:: This is not particularly useful because the metaclass will be applied before any decorators, so even if a class is decorated with @dataclass it will still raise a TypeError here, because it has not been applied yet.