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

Signature of "__call__" incompatible with supertype "type" #6721

Closed
kprzybyla opened this issue Apr 25, 2019 · 3 comments
Closed

Signature of "__call__" incompatible with supertype "type" #6721

kprzybyla opened this issue Apr 25, 2019 · 3 comments

Comments

@kprzybyla
Copy link
Contributor

Hi,

I found a potential bug where mypy raises an error where it should not. It is present only when user inherits after type. Inheritance after object seems to work fine. Please see below code example.

class Meta(type):

    def __call__(cls, value: int, *args, **kwargs): ...


class Class:

    def __call__(self, value: int, *args, **kwargs): ...

Running mypy with command mypy example.py results in following output:

example.py:3: error: Signature of "__call__" incompatible with supertype "type"

I would expect mypy to not raise any errors after type checking above code. Adding #type: ignore gets rid of an error but it seems that this is a bug in mypy. Unless I'm missing something important?

I used mypy 0.660 and Python 3.7.3.

@gvanrossum
Copy link
Member

gvanrossum commented Apr 25, 2019

It's a direct consequence of the definition of type.__call__ in typeshed:

    def __call__(self, *args: Any, **kwds: Any) -> Any: ...

The error you are seeing is due to the Liskov principle. (Google it if you're not familiar.)

If you really want this signature, just put a # type: ignore on the def line.

@ilevkivskyi
Copy link
Member

I think we can actually allow this, as we allow incompatible overrides of __init__ (which is essentially the same).

On the other hand this is pretty niche, so I am not sure.

@kprzybyla
Copy link
Contributor Author

kprzybyla commented Apr 25, 2019

@gvanrossum Thank you for the explanation, after looking at typeshed repository and checking the definition of both object and type now it makes perfect sense. I thought that __call__ signature is the same for both object and type, I saw it inside type and thought that object will have the same signature through inheritance but it does not since type inherits after object, not the other way around.

I think that I will actually go with the below code since it seems reasonable and mypy does not raise an error with this signature.

class Meta(type):

    def __call__(self, *args, value: Optional[int] = None, **kwargs): ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants