Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

super().__init__(....) in mixins fails with Too many arguments for "__init__" of "object" #5887

Closed
kurtgn opened this issue Nov 12, 2018 · 12 comments
Labels
false-positive mypy gave an error on correct code feature priority-1-normal

Comments

@kurtgn
Copy link

kurtgn commented Nov 12, 2018

When I create a mixin class that extends the logic of __init__, the regular thing to do is:

class ExtraValuemixin:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # some extra initialization
        

However this looks wrong to mypy, as it says:

Too many arguments for "__init__" of "object"

I get it, there's no *args or **kwargs in the object's constructor signature; but this is a mixin, and it relies on its childen's constructors. Ho do I make mypy understand this?

Full example:

class ExtraValuemixin:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # some extra initialization
        self._extra_value = 1

    def retrieve_extra_value(self):
        return self._extra_value


class ParentObj:

    def __init__(self, value):
        self.value = value


class ChildObj(ExtraValuemixin, ParentObj):
    pass


obj = ChildObj(value=5)

print(obj.retrieve_extra_value())
@mathfac
Copy link

mathfac commented Dec 22, 2018

Faced with the same issue.

@JukkaL JukkaL added feature priority-1-normal false-positive mypy gave an error on correct code labels Jan 2, 2019
@JukkaL
Copy link
Collaborator

JukkaL commented Jan 2, 2019

Mypy shouldn't complain about this idiom, but I'm not sure what exact rules should be. Maybe calls to super().__init__ should be special cased.

@gvanrossum
Copy link
Member

There are lots of problems with mixins. Maybe we should have a way to flag them?

@ilevkivskyi
Copy link
Member

@gvanrossum

There are lots of problems with mixins. Maybe we should have a way to flag them?

There is a proposal python/typing#246 (partially based on python/typing#241)

@gvanrossum
Copy link
Member

Hmm... Maybe it’s time to work on both of these.

@ilevkivskyi
Copy link
Member

Hmm... Maybe it’s time to work on both of these.

It would be great to do it this year, I am not sure however we will have time to do this soon. Since it may be a relatively time-consuming change (taking into account necessary design discussions).

@NeilGirdhar
Copy link
Contributor

NeilGirdhar commented Jun 24, 2019

This doesn't look like it's just a problem with mixins. This looks like a special case of: #4001 and looks related to #4997

@ZdenekM
Copy link

ZdenekM commented Aug 20, 2021

It would be great if I could somehow specify, with what classes the mixin is going to be mixed up. Then, mypy might be able to judge calls to parent methods (including __init__) properly.

@kaushikcfd
Copy link

kaushikcfd commented Dec 17, 2021

On mypy==0.920, the provided MFE doesn't fail for me. We should probably close this issue?

jpmckinney added a commit to open-contracting/yapw that referenced this issue Dec 20, 2021
@LefterisJP
Copy link
Contributor

Going from mypy==0.910 to mypy=0.930 this seems to be fixed. Got bunch of type:ignore commments not needed. So I would say this issue is fixed 😄

HacKanCuBa added a commit to HacKanCuBa/blake2signer that referenced this issue Dec 28, 2021
@erictraut
Copy link

Yes, I can confirm this appears to be fixed in the latest release.

@marcinocto
Copy link

marcinocto commented Feb 9, 2022

I'm still getting error: Too many arguments for "__init__" of "object" in a scenario where one of the arguments is verbose with mypy==0.931

class ExtraValuemixin:
    def __init__(self, value, *args, **kwargs):
        super().__init__(value, *args, **kwargs)

    def retrieve_extra_value(self):
        return self._extra_value


class ParentObj:
    def __init__(self, value):
        self.value = value


class ChildObj(ExtraValuemixin, ParentObj):
    pass


obj = ChildObj(value=5)

print(obj.retrieve_extra_value())

My usecase is adding mixins to classes extending Exception so I know that the message is always there - with simplified code

class CustomExceptionMixin:
    message = ""

    def __init__(
        self, message: str, *args, **kwargs
    ) -> None:
        self.message = message
        super().__init__(message, **kwargs)  # type: ignore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
false-positive mypy gave an error on correct code feature priority-1-normal
Projects
None yet
Development

No branches or pull requests