OrenIshShalom
OrenIshShalom

Reputation: 7162

Passing parameters to frozen super dataclass

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

Answers (2)

hynek
hynek

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

user107511
user107511

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

Related Questions