Question: I'm using Python dataclasses with inheritance and I would like to make an inherited abstract property into a required constructor argument. Using an inherited abstract property as a optional constructor argument works as expected, but I've been having real trouble making the argument required. Below is a minimal working example, test_1() fails with TypeError: Can't instantiate abstract class Child1 with abstract methods inherited_attribute, test_2() fails with AttributeError: can't set attribute, and test_3() works as promised. Does anyone know a way I can achieve this behavior while still using dataclasses? import abc import dataclasses @dataclasses.dataclass class Parent(abc.ABC): @property @abc.abstractmethod def inherited_attribute(self) -> int: pass @dataclasses.dataclass class Child1(Parent): inherited_attribute: int @dataclasses.dataclass class Child2(Parent): inherited_attribute: int = dataclasses.field() @dataclasses.dataclass class Child3(Parent): inherited_attribute: int = None def test_1(): Child1(42) def test_2(): Child2(42) def test_3(): Child3(42) 

Answer: So, the thing is, you declared an abstract property. Not an abstract constructor argument, or an abstract instance dict entry - abc has no way to specify such things. Abstract properties are really supposed to be overridden by concrete properties, but the abc machinery will consider it overridden if there is a non-abstract entry in the subclass's class dict.  Your Child1 doesn't create a class dict entry for inherited_attribute - the annotation only creates an entry in the annotation dict. Child2 does create an entry in the class dict, but then the dataclass machinery removes it, because it's a field with no default value. This changes the abstractness status of Child2, which is undefined behavior below Python 3.10, but Python 3.10 added abc.update_abstractmethods to support that, and dataclasses uses that function on Python 3.10. Child3 creates an entry in the class dict, and since the dataclass machinery sees this entry as a default value, it leaves the entry there, so the abstract property is considered overridden.   So you've got a few courses of action here. The first is to remove the abstract property. You don't want to force your subclasses to have a property - you want your subclasses to have an accessible inherited_attribute instance attribute, and it's totally fine if this attribute is implemented as an instance dict entry. abc doesn't support that, and using an abstract property is wrong, so just document the requirement instead of trying to use abc to enforce it. With the abstract property removed, Parent isn't actually abstract any more, and in fact doesn't really do anything, so at that point, you can just take Parent out entirely.  Option 2, if you really want to stick with the abstract property, would be to give your subclasses a concrete property, properly overriding the abstract property: @dataclasses.dataclass class Child(Parent): _hidden_field: int @property def inherited_attribute(self): return self._hidden_field  This would require you to give the field a different name from the attribute name you wanted, with consequences for the constructor argument names, the repr output, and anything else that cares about field names.  The third option is to get something else into the class dict to shadow the inherited_attribute name, in a way that doesn't get treated as a default value. Python 3.10 added slots support in dataclasses, so you could do @dataclasses.dataclass(slots=True) class Child(Parent): inherited_attribute: int  and the generated slot descriptor would shadow the abstract property, without being treated as a default value. However, this would not give the usual memory savings of slots, because your classes inherit from Parent, which doesn't use slots.  Overall, I would recommend option 1. Abstract properties don't mean what you want, so just don't use them.