rwskit.dataclasses

Attributes

log

D

A type intended to represent a dataclass.

Classes

DataclassRegistry

Initialize the registry.

FrozenDataclassMeta

Turn the class into a pydantic dataclass if it is not one already.

EnforceFrozenDataclassMeta

Requires that the class must be a standard or pydantic dataclass.

Functions

immutable_dataclass(cls)

A decorator to convert a class to a frozen keyword only pydantic dataclass.

is_frozen(→ bool)

Checks if a class is a frozen dataclass.

has_default_value(→ bool)

Checks if a field has a default value.

is_optional(→ bool)

Checks if a field is optional.

is_required(→ bool)

Checks if a field is required.

resolve_type_hints(→ dict[str, Any])

Try to resolve the type hints for a dataclass.

construct_dataclass(→ D)

Construct a dataclass from a mapping.

Module Contents

rwskit.dataclasses_.log[source]
rwskit.dataclasses_.D[source]

A type intended to represent a dataclass.

rwskit.dataclasses_.immutable_dataclass(cls: Type[D])[source]

A decorator to convert a class to a frozen keyword only pydantic dataclass.

rwskit.dataclasses_.is_frozen(cls: Type) bool[source]

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.

rwskit.dataclasses_.has_default_value(field: dataclasses.Field) bool[source]

Checks if a field has a default value.

Parameters:

field (Field) – The field to check.

Returns:

True if the field has a default value either directly or via a default factory.

Return type:

bool

rwskit.dataclasses_.is_optional(field: dataclasses.Field) bool[source]

Checks if a field is optional.

Parameters:

field (Field) – The field to check.

Returns:

True if the field is optional.

Return type:

bool

rwskit.dataclasses_.is_required(field: dataclasses.Field) bool[source]

Checks if a field is required.

A field is required if it is not optional and does not have a default value.

Parameters:

field (Field) – The field to check,

Returns:

True if the field is required.

Return type:

bool

rwskit.dataclasses_.resolve_type_hints(cls: Type[Any], type_map: dict[str, Type[Any]] | None = None, max_tries: int = 50) dict[str, Any][source]

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.

Parameters:
  • cls (Type[Any]) – The dataclass to resolve the type hints for.

  • type_map (dict[str, Type[Any]], optional) – Additional mappings from string names to type classes, which can be used in addition to globals() for resolving type hint classes.

  • max_tries (int) – The maximum number of times the method will try to resolve missing type hints.

Returns:

The dictionary containing the resolved type hints.

Return type:

dict[str, Any]

Raises:

icontract.ViolationError – If the input cls is not a dataclass.

rwskit.dataclasses_.construct_dataclass(data: Mapping[str, Any], dataclass_type: Type[D], type_map: dict[str, Any] | None = None) D[source]

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.

Parameters:
  • data (Mapping[str, Any]) – The dictionary (or other mapping) to try to convert.

  • dataclass_type (Type[D]) – The dataclass type we will try to construct.

  • type_map (dict[str, Any], optional) – 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.

Returns:

The dataclass object we have constructed.

Return type:

D

Raises:
  • icontract.ViolationError – If the dataclass_type is not a dataclass.

  • TypeError – If the dictionary cannot be converted to the dataclass type.

class rwskit.dataclasses_.DataclassRegistry[source]

Initialize the registry.

registered_classes: set[Type[D]][source]
__iter__() Iterator[Type[D]][source]
__len__() int[source]
register(*classes: Type[D])[source]

Add a class to the registry.

Parameters:

classes (Type[D]) – The class or classes to add.

construct_registered_dataclass(data: Mapping[str, Any], type_map: dict[str, Any] | None = None) D[source]

Try to construct one of the registered dataclasses from the given data.

Parameters:
  • data (Mapping[str, Any]) – The data to use for constructing a dataclass.

  • type_map (dict[str, Any], optional) – Additional types that should be made available (imported) when resolving type hints for the registered dataclasses.

Returns:

An instance of a registered dataclass that is compatible with the given data.

Return type:

D

Raises:
  • icontract.ViolationError – If data does not contain values for all required attributes of the dataclass (or any nested dataclass).

  • icontract.ViolationError – If data is not a Mapping.

  • ValueError – If a registered dataclass cannot be constructed from the data.

class rwskit.dataclasses_.FrozenDataclassMeta[source]

Bases: 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.

class rwskit.dataclasses_.EnforceFrozenDataclassMeta[source]

Bases: 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.