Search code examples
pythonmypypython-typingpython-attrs

Mypy returns Error "Unexpected keyword argument" for subclass of a decorated class with attrs package


I have two decorated classes using attrs package as follows:

@attr.s(kw_only=True)
class Entity:
    """
    base class of all entities
    """
    entity_id = attr.ib(type=str)
    # ...

@attr.s(kw_only=True)
class Customer(Entity):
    customer_name = attr.ib(type=Name)
    # ...

I get Unexpected keyword argument "entity_id" for "Customer" for code like this:

def register_customer(customer_name: str):
    return Customer(
        entity_id=unique_id_generator(),
        customer_name=Name(full_name=customer_name),
    )

So how can I make Mypy aware of the __init__ method of my parent class. I should mention that the code works perfectly and there is (at least it seems) no runtime error.


Solution

  • Your code is correct and should work. If I run the following simplified version:

    import attr
    
    @attr.s(kw_only=True)
    class Entity:
        """
        base class of all entities
        """
        entity_id = attr.ib(type=str)
        # ...
    
    @attr.s(kw_only=True)
    class Customer(Entity):
        customer_name = attr.ib(type=str)
    
    def register_customer(customer_name: str) -> Customer:
        return Customer(
            entity_id="abc",
            customer_name=customer_name,
        )   # ...
    

    through Mypy 0.910 with attrs 21.2.0 on Python 3.9.7 I get:

    Success: no issues found in 1 source file
    

    My theories:

    • Old Mypy (there's a lot of changes all times, sometimes it takes time for the attrs plugin to be updated with new features).
    • Old attrs (we try to keep up with the changes in attrs and the features provided by Mypy).
    • Python 2 (since you're using the old syntax). kw_only used to be Python 3-only and I wouldn't be surprised if mypy has some resident logic around it?