Search code examples
pythonpython-attrs

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

  • 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)