Reputation: 7162
I have a simple (frozen) dataclass inheritance as follows:
from attrs import frozen
@frozen
class Interval:
left: str
right: str
@frozen
class RealInterval(Interval):
def __attrs_pre_init__(self) -> None:
super().__init__("-oo", "+oo")
x = RealInterval()
According to the documentation, it looks promising:
attrs_pre_init is automatically detected and run before attrs starts initializing. This is useful if you need to inject a call to super().init()
But when I check with mypy
I get:
$ mypy example.py
example.py:13: error: Missing positional arguments "left", "right" in call to "RealInterval"
Found 1 error in 1 file (checked 1 source file)
Note that this is not a duplicate of this:
Upvotes: 1
Views: 578
Reputation: 4166
This is not how attrs
(and for that matter: dataclasses work).
The __init__
is written for specifically the attributes you're defining for performance reasons.
The easiest solution for your use-case is overriding the attributes:
@frozen
class RealInterval(Interval):
left: str = "-oo"
right: str = "+oo"
Which gives you:
>>> RealInterval()
RealInterval(left='-oo', right='+oo')
>>> RealInterval("foo", "bar")
RealInterval(left='foo', right='bar')
The pre_init logic is when you're subclassing classes you don't own, but that need their __init__
called. That's true for some GUI kits for example.
Upvotes: 1
Reputation: 822
This should work even without attrs
module
from dataclasses import dataclass
@dataclass(frozen=True)
class Interval:
left: str
right: str
@dataclass(frozen=True)
class RealInterval(Interval):
def __init__(self) -> None:
super().__init__("-oo", "+oo")
x = RealInterval()
__init__
of the subclass runs before __init__
of the superclass.
This can be done with attrs
with replacing @dataclass(frozen=True)
with @frozen
.
Notice that this overrides the default __init__
method of the subclass.
Upvotes: 0