7

I'm trying to create a Python 3.7 dataclass composed of inherited dataclasses:

from dataclasses import dataclass

@dataclass
class A:
    title: str
    synopsis: str = "A book"

@dataclass
class B:
    id: str
    description: str = "A short book about something"
   
@dataclass()
class C(A, B):
    provider: str

c = C(title="Trainspotting")

This throws the following exception:

Traceback (most recent call last):
File "tests/test.py", line 14, in <module>
    class C(A, B):
File "lib/python3.7/dataclasses.py", line 958, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
File "lib/python3.7/dataclasses.py", line 879, in _process_class
    else 'self',
File "lib/python3.7/dataclasses.py", line 466, in _init_fn
    raise TypeError(f'non-default argument {f.name!r} '

TypeError: non-default argument 'title' follows default argument

It seems that Python's @dataclass resolution does not align all the parent's default and non-default options when it reverses through the MRO. Is there a way around this?

Edit: I now use Pydantic library, which offers much more control plus added features such as JSON serialisation and deserialisation.

Alastair McCormack
  • 26,573
  • 8
  • 77
  • 100
  • Based on https://docs.python.org/3/library/dataclasses.html#inheritance, I'd say no - the fields are all kept in insertion order, you'd have to make sure all fields have defaults if you want to use inheritance. – jonrsharpe Jan 05 '19 at 11:55

0 Answers0