Skip to content

Dataclasses

pane dataclasses work similarly to many other libraries. They aim to have a superset of the features of the standard library dataclasses. A dataclass can be made by subclassing pane.PaneBase:

import pane
from typing import t

class MyDataclass(pane.PaneBase):
    x: int = 5  # basic field w/ default
    y: t.Optional[float] = None
    # remaining fields should be keyword only
    _: pane.KW_ONLY  
    # advanced field specification
    z: t.List[float] = pane.field(aliases=('w',), default_factory=list)
    # apply custom logic to a field
    w: str = pane.field(converter=CustomConverter())

Constructors

pane automatically makes constructors for you:

>>> import inspect; inspect.signature(MyDataclass.__init__)
<Signature (x: int = 5, y: Optional[float] = None, *, z: list[float] = []) -> None>

MyDataclass.__init__ performs conversion on arguments:

>>> MyDataclass()
MyDataclass(x=5, y=None, z=[])

>>> MyDataclass(z=[5.0, 10.0, 's'])
Traceback (most recent call last):
...
pane.errors.ConvertError: Expected sequence of floats
While parsing field '2':
  Expected a float, instead got `s` of type `str`

To bypass conversion, use Mydataclass.make_unchecked instead:

>>> MyDataclass.make_unchecked(z=[5.0, 10.0, 's'])
MyDataclass(x=5, y=None, z=[5.0, 10.0, 's'])

Like regular dataclasses, __post_init__ is called on construction, allowing extra validation logic and initializing init=False fields.

MyDataclass.from_obj, MyDataclass.from_data, MyDataclass.from_json, and MyDataclass.from_yaml perform conversion from an object:

# note the use of an alias for 'z'
>>> MyDataclass.from_data({'x': 10, 'y': 10., 'w': [10.]})
MyDataclass(x=10, y=10.0, z=[10.0])

>>> from io import StringIO
>>> MyDataclass.from_json(StringIO('{"x": 10, "y": 10.0, "w": [10.0]}'))
MyDataclass(x=10, y=10.0, z=[10.0])

(from_json and from_yaml take a file-like object or filename. from_jsons and from_yamls take a string).

Member methods

MyDataclass.into_data performs the reverse operation, converting a dataclass to a data interchange type (usually a dict):

>>> MyDataclass(x=10, y=10.0, z=[10.0]).into_data()
{'x': 10, 'y': 10.0, 'z': [10.0]}

MyDataclass.dict returns a dictionary containing the fields, using their Python names. set_only may be specified to return only explicitly set fields, and rename may be specified to return using differently-styled names:

Index of methods

Method name Method type Description
__init__ classmethod Instantiate a dataclass from data
make_unchecked classmethod Instantiate a dataclass from data
from_obj classmethod Instantiate a dataclass from a convertible object
from_data classmethod Instantiate a dataclass from interchange data
from_json classmethod Instantiate a dataclass from a JSON file
from_yaml classmethod Instantiate a dataclass from a YAML file
from_yaml_all classmethod Instantiate a list of dataclasses from a YAML stream of multiple YAML documents
from_jsons classmethod Instantiate a dataclass from a JSON string
from_yamls classmethod Instantiate a dataclass from a YAML string
write_json classmethod Write a dataclass to a JSON string or file
write_yaml classmethod Write a dataclass to a YAML string or file
into_data instance method Convert dataclass into interchange data
dict instance method Return dataclass fields as a dict (optionally, return only set fields)

Class arguments

Dataclass behavior can be customized using arguments passed to the class constructor. The following arguments are supported:

Args:

  • name (str): Name of the class, used in error messages.
  • out_format (ClassLayout): Format to serialize class in (default: struct)
  • in_format (t.Sequence[ClassLayout]): Formats class may be serialized from (default: ['struct', 'tuple'] if no keyword arguments, else ['struct'])
  • eq (bool): Whether to add __eq__ method
  • order (bool): Whether to add ordering methods (__gt__, __le__, etc.)
  • frozen (bool): Whether to freeze dataclass
  • unsafe_hash (bool): Whether to add a __hash__ method even for non-frozen dataclasses. Behaves the same as unsafe_hash in vanilla dataclasses.
  • kw_only (bool): If true, make all parameters keyword-only
  • rename (RenameStyle): How to rename parameters upon conversion to data. Cannot be specified with in_rename or out_rename
  • in_rename (RenameStyle or t.Sequence[RenameStyle]): Allow inputs renamed from these formats
  • out_rename (RenameStyle): Output renamed to this format
  • allow_extra (bool): Whether to allow (and ignore) extra parameters
  • custom (IntoConverterHandlers): Custom handlers to apply to members of this class. Can be a handler, a list of handlers, or a dict mapping types to converters.

In general, these arguments are inherited by subclasses, unless overridden.

Generic classes

Generic classes are supported natively, with proper inheritance.