'Python attrs: Inheriting from class which values have default values raises error

I have a situation where attrs class inherits from another class which attributes have default value. This raises ValueError.

Here's an example:

from attrs import define


@define
class A:
    a: int = 1


@define
class B(A):
    b: int


test = B(b=1)

>>> ValueError: No mandatory attributes allowed after an attribute with a default value or factory.  Attribute in question: Attribute(name='b', ...

How do I avoid this kind of behavior?



Solution 1:[1]

You're running into a limitation of Python. The __init__ you're asking attrs to write for you looks like this:

def __init__(self, b=1, a):
    self.b = b
    self.a = a

which can't exist.

You can work around that by either declaring class B or attribute b keyword-only:

from attrs import define, field


@define
class A:
    a: int = 1


@define(kw_only=True)
class B1(A):
    b: int

@define
class B2(A):
    b: int = field(kw_only=True)


test1 = B1(b=1)
test2 = B2(b=1)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1