Question: Given the following hierarchy of python dataclasses: @dataclass class A: a: str aa: str @dataclass class B(A): b: str @dataclass class C(A): c: str @dataclass class D(B, C): d: str  Is there any general method that allows you to insert an attribute with a default value in this inheritance hierarchy? For instance, the following produces a Non-default argument(s) follows default argument(s) defined in 'B' error for class D. @dataclass class A: a: str aa: str @dataclass class B(A): b: str = 'b' # <-- default value @dataclass class C(A): c: str @dataclass class D(B, C): d: str  I suppose one solution could be to give all attributes in the hierarchy a default value of None, and add a __post_init__() validation which raises some exception if any attributes are None, but this doesn't seem right and you would need it in every dataclass in the hierarchy. Class inheritance in Python 3.7 dataclasses proposes a solution where you create two separate branches of the inheritance hierarchy; one for default values and one without. The drawback here is that the hierarchy quickly becomes mangled with a lot of classes, but if there are no better options, I suppose this is as good as it gets. Edit I've come up with a meta_dataclass which does some hackery to at least solve my problem. I'm sure it breaks all kinds of rules, but perhaps someone can improve upon it. It allows a hierarchy of meta_dataclasses where any attribute in the hierarchy can have a default value. It is motivated by the solution presented in Class inheritance in Python 3.7 dataclasses. It effectively creates two inheritance branches, one with default values and one without, but the creation of the extra classes required to achieve this is encapsulated in the mete_dataclass decorator. A current drawback is that a meta_dataclass can only inherit from other meta_dataclasses. Full code: from dataclasses import make_dataclass, MISSING, field class Dataclass: pass class Declarations: pass class Definitions: pass def meta_dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False): def wrap(cls): declaration_bases = [] definition_bases = [] for base in cls.__bases__: if issubclass(base, Dataclass): declaration_bases += [c for c in base.__bases__ if issubclass(c, Declarations)] definition_bases += [c for c in base.__bases__ if issubclass(c, Definitions)] elif len(cls.__bases__) == 1 and base != object: raise ValueError(f'meta_dataclasses can only inherit from other meta_dataclasses. ' f'{cls} inherits from {base}') declaration_bases.append(Declarations) definition_bases.append(Definitions) fields = [] if hasattr(cls, '__annotations__'): for field_name, field_type in cls.__annotations__.items(): f = field(default=cls.__dict__[field_name]) if field_name in cls.__dict__ else field() fields.append((field_name, field_type, f)) declarations = make_dataclass(cls_name=f'{cls.__name__}_Declarations', bases=tuple(declaration_bases), fields=[f for f in fields if isinstance(f[2].default, type(MISSING))], init=init, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen) definitions = make_dataclass(cls_name=f'{cls.__name__}_Definitions', bases=tuple(definition_bases), fields=[f for f in fields if not isinstance(f[2].default, type(MISSING))], init=init, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen) cls_wrapper = make_dataclass(cls_name=cls.__name__, fields=[], bases=(Dataclass, definitions, declarations), namespace=cls.__dict__, init=init, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen) return cls_wrapper if cls is None: return wrap else: return wrap(cls)  Example: @meta_dataclass class A: a: str aa: str @meta_dataclass class B(A): b: str = 'b' @meta_dataclass class C(A): c: str @meta_dataclass class D(B, C): d: str >>> help(D) Help on class D in module types: class D(__main__.Dataclass, D_Definitions, D_Declarations) | D(a: str, aa: str, c: str, d: str, b: str = 'b') -> None | | D(a: str, aa: str, c: str, d: str, b: str = 'b') | | Method resolution order: | D | __main__.Dataclass | D_Definitions | B_Definitions | C_Definitions | A_Definitions | __main__.Definitions | D_Declarations | B_Declarations | C_Declarations | A_Declarations | __main__.Declarations | builtins.object  Illustration: The below image illustrates what the @meta_dataclass decorator does to a single class. 

Answer: This is a well-known issue for data classes, there are several workarounds but this is solved very elegantly in Python 3.10, here is the PR that solved the issue 43532. It would work the following way: from dataclasses import dataclass @dataclass(kw_only=True) class Base: type: str counter: int = 0 @dataclass(kw_only=True) class Foo(Base): id: int  This is deeply explained at: https://medium.com/@aniscampos/python-dataclass-inheritance-finally-686eaf60fbb5  For the original question, C and D are the minimum required classes to have the kw_only flag set to True: @dataclass class A: a: str aa: str @dataclass class B(A): b: str = 'b' # <-- default value @dataclass(kw_only=True) class C(A): c: str @dataclass(kw_only=True) class D(B, C): d: str  Although all of them could have the flag set to True for this matter.