unitxt.dataclass module¶
- class unitxt.dataclass.AbstractField(default: Any = <class 'unitxt.dataclass.Undefined'>, name: str = None, type: None = None, init: bool = True, also_positional: bool = True, default_factory: Any = None, final: bool = False, abstract: bool = False, required: bool = False, internal: bool = False, origin_cls: None = None, metadata: Dict[str, str] = <factory>)[source]¶
Bases:
Field
- class unitxt.dataclass.Dataclass[source]¶
Bases:
objectBase class for data-like classes that provides additional functionality and control.
Base class for data-like classes that provides additional functionality and control over Python’s built-in @dataclasses.dataclass decorator. Other classes can inherit from this class to get the benefits of this implementation. As a base class, it ensures that all subclasses will automatically be data classes.
The usage and field definitions are similar to Python’s built-in @dataclasses.dataclass decorator. However, this implementation provides additional classes for defining “final”, “required”, and “abstract” fields.
Key enhancements of this custom implementation:
Automatic Data Class Creation: All subclasses automatically become data classes, without needing to use the @dataclasses.dataclass decorator.
Field Immutability: Supports creation of “final” fields (using FinalField class) that cannot be overridden by subclasses. This functionality is not natively supported in Python or in the built-in dataclasses module.
Required Fields: Supports creation of “required” fields (using RequiredField class) that must be provided when creating an instance of the class, adding a level of validation not present in the built-in dataclasses module.
Abstract Fields: Supports creation of “abstract” fields (using AbstractField class) that must be overridden by any non-abstract subclass. This is similar to abstract methods in an abc.ABC class, but applied to fields.
Type Checking: Performs type checking to ensure that if a field is redefined in a subclass, the type of the field remains consistent, adding static type checking not natively supported in Python.
Error Definitions: Defines specific error types (FinalFieldError, RequiredFieldError, AbstractFieldError, TypeMismatchError) for providing detailed error information during debugging.
MetaClass Usage: Uses a metaclass (DataclassMeta) for customization of class creation, allowing checks and alterations to be made at the time of class creation, providing more control.
- Example:
class Parent(Dataclass): final_field: int = FinalField(1) # this field cannot be overridden required_field: str = RequiredField() also_required_field: float abstract_field: int = AbstractField() class Child(Parent): abstract_field = 3 # now once overridden, this is no longer abstract required_field = Field(name="required_field", default="provided", type=str) class Mixin(Dataclass): mixin_field = Field(name="mixin_field", default="mixin", type=str) class GrandChild(Child, Mixin): pass grand_child = GrandChild() logger.info(grand_child.to_dict()) ...
- to_dict(classes: List | None = None, keep_empty: bool = True)[source]¶
Convert to dict.
- Parameters:
classes (List, optional) – List of parent classes which attributes should be returned. If set to None, then all class’ attributes are returned.
keep_empty (bool) – If True, then parameters are returned regardless if their values are None or not.
- class unitxt.dataclass.DataclassMeta(name, bases, namespace, **kwargs)[source]¶
Bases:
ABCMetaMetaclass for Dataclass.
Checks for final fields when a subclass is created.
- class unitxt.dataclass.Field(default: ~typing.Any = <class 'unitxt.dataclass.Undefined'>, name: str | None = None, type: None = None, init: bool = True, also_positional: bool = True, default_factory: ~typing.Any | None = None, final: bool = False, abstract: bool = False, required: bool = False, internal: bool = False, origin_cls: None = None, metadata: ~typing.Dict[str, str] = <factory>)[source]¶
Bases:
objectAn alternative to dataclasses.dataclass decorator for a more flexible field definition.
- Parameters:
default (Any, optional) – Default value for the field. Defaults to None.
name (str, optional) – Name of the field. Defaults to None.
type (type, optional) – Type of the field. Defaults to None.
default_factory (Any, optional) – A function that returns the default value. Defaults to None.
final (bool, optional) – A boolean indicating if the field is final (cannot be overridden). Defaults to False.
abstract (bool, optional) – A boolean indicating if the field is abstract (must be implemented by subclasses). Defaults to False.
required (bool, optional) – A boolean indicating if the field is required. Defaults to False.
origin_cls (type, optional) – The original class that defined the field. Defaults to None.
- class unitxt.dataclass.FinalField(default: Any = <class 'unitxt.dataclass.Undefined'>, name: str = None, type: None = None, init: bool = True, also_positional: bool = True, default_factory: Any = None, final: bool = False, abstract: bool = False, required: bool = False, internal: bool = False, origin_cls: None = None, metadata: Dict[str, str] = <factory>)[source]¶
Bases:
Field
- class unitxt.dataclass.InternalField(default: Any = <class 'unitxt.dataclass.Undefined'>, name: str = None, type: None = None, init: bool = True, also_positional: bool = True, default_factory: Any = None, final: bool = False, abstract: bool = False, required: bool = False, internal: bool = False, origin_cls: None = None, metadata: Dict[str, str] = <factory>)[source]¶
Bases:
Field
- class unitxt.dataclass.NonPositionalField(default: Any = <class 'unitxt.dataclass.Undefined'>, name: str = None, type: None = None, init: bool = True, also_positional: bool = True, default_factory: Any = None, final: bool = False, abstract: bool = False, required: bool = False, internal: bool = False, origin_cls: None = None, metadata: Dict[str, str] = <factory>)[source]¶
Bases:
Field
- class unitxt.dataclass.OptionalField(default: Any = <class 'unitxt.dataclass.Undefined'>, name: str = None, type: None = None, init: bool = True, also_positional: bool = True, default_factory: Any = None, final: bool = False, abstract: bool = False, required: bool = False, internal: bool = False, origin_cls: None = None, metadata: Dict[str, str] = <factory>)[source]¶
Bases:
Field
- class unitxt.dataclass.RequiredField(default: Any = <class 'unitxt.dataclass.Undefined'>, name: str = None, type: None = None, init: bool = True, also_positional: bool = True, default_factory: Any = None, final: bool = False, abstract: bool = False, required: bool = False, internal: bool = False, origin_cls: None = None, metadata: Dict[str, str] = <factory>)[source]¶
Bases:
Field
- unitxt.dataclass.get_fields(cls, attrs)[source]¶
Get the fields for a class based on its attributes.
- Parameters:
cls (type) – The class to get the fields for.
attrs (dict) – The attributes of the class.
- Returns:
A dictionary mapping field names to Field instances.
- Return type:
dict
- unitxt.dataclass.is_dataclass(obj)[source]¶
Returns True if obj is a dataclass or an instance of a dataclass.
- unitxt.dataclass.is_possible_field(field_name, field_value)[source]¶
Check if a name-value pair can potentially represent a field.
- Parameters:
field_name (str) – The name of the field.
field_value – The value of the field.
- Returns:
True if the name-value pair can represent a field, False otherwise.
- Return type:
bool
- unitxt.dataclass.to_dict(obj, func=<function deepcopy>, _visited=None)[source]¶
Recursively converts an object into a dictionary representation while avoiding infinite recursion due to circular references.
- Parameters:
obj – Any Python object to be converted into a dictionary-like structure.
func (Callable, optional) – A function applied to non-iterable objects. Defaults to copy.deepcopy.
_visited (set, optional) – A set of object IDs used to track visited objects and prevent infinite recursion.
- Returns:
A dictionary representation of the input object, with supported collections and dataclasses recursively processed.
- Return type:
dict
Notes
Supports dataclasses, named tuples, lists, tuples, and dictionaries.
Circular references are detected using object IDs and replaced by func(obj).
Named tuples retain their original type instead of being converted to dictionaries.