from dataclasses import Field, MISSING, _FIELDS, _FIELD, _FIELD_INITVAR # type: ignore from typing import Type, Any, TypeVar, List from dacite.cache import cache from dacite.types import is_optional T = TypeVar("T", bound=Any) class DefaultValueNotFoundError(Exception): pass def get_default_value_for_field(field: Field, type_: Type) -> Any: if field.default != MISSING: return field.default elif field.default_factory != MISSING: # type: ignore return field.default_factory() # type: ignore elif is_optional(type_): return None raise DefaultValueNotFoundError() @cache def get_fields(data_class: Type[T]) -> List[Field]: fields = getattr(data_class, _FIELDS) return [f for f in fields.values() if f._field_type is _FIELD or f._field_type is _FIELD_INITVAR] @cache def is_frozen(data_class: Type[T]) -> bool: return data_class.__dataclass_params__.frozen