Skip to content

Mypy incorrectly says signature is incompatible with supertype when using decorator #3260

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

Closed
fniessink opened this issue Apr 26, 2017 · 13 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal

Comments

@fniessink
Copy link

When checking the code below with mypy v0.501, mypy complains that

deco.py:10: error: Signature of "a" incompatible with supertype "A"

According to @ilevkivskyi this may be related to #1441.

import functools

class A:
  @functools.lru_cache()
  def a(self) -> str: 
    return 'a'

class B(A):
  @functools.lru_cache()
  def a(self) -> str:
    return super().a() + 'b'
@ilevkivskyi ilevkivskyi added the bug mypy got something wrong label Apr 26, 2017
@ilevkivskyi
Copy link
Member

I played with this a bit and it looks like this is specific to functools.lru_cache(), most probably since it is a class that defines a __call__ method with decorator-like signature. So this is different from #1441.

@JelleZijlstra
Copy link
Member

I just ran into this too with a method decorated with @contextlib.asynccontextmanager (https://docs.python.org/3.7/library/contextlib.html#contextlib.asynccontextmanager).

@JukkaL JukkaL added the false-positive mypy gave an error on correct code label May 19, 2018
@jdferreira
Copy link

I also ran with this issue today, precisely with the @lry_cache decorator on a subclass's method overriding a base method. Are there any solutions or workarounds at this point?

@stlehmann
Copy link

I' ve als got this issue with a stub-file for PyQt5:

class Qt:
    class Alignment: ...

class QWidget: ...

class QLayoutItem: ...

class QObject: ...

class QLayout(QObject, QLayoutItem):
    def addWidget(self, w: QWidget) -> None: ...

class QGridLayout(QLayout):
    def addWidget(
        self, widget: QWidget, row: int, column: int, alignment: Qt.Alignment = ...
    ) -> None: ...

Results in the following mypy error:

test.pyi:14: error: Signature of "addWidget" incompatible with supertype "QLayout"

@gvanrossum
Copy link
Member

@stlehmann Mypy is right in your case, it fails Liskov. The subclass method requires more arguments than the superclass method, so it is not a proper subtype.

@JukkaL
Copy link
Collaborator

JukkaL commented Jul 23, 2018

@stlehmann You can silence the mypy error by adding a # type: ignore comment on line 14. It won't cause mypy to ignore the signature, but it will stop complaints about the Liskov violation.

@stlehmann
Copy link

@gvanrossum Thanks for the explanation. I googled Liskov and it makes perfectly sense. However in this case I can't change the API so I will use #type: ignore to silence the error message as proposed by @JukkaL

@gvanrossum
Copy link
Member

gvanrossum commented Jul 24, 2018 via email

@ilevkivskyi
Copy link
Member

I tried both examples (lru_cache() and asynccontextmanager) they both work correctly on master.

@ikelos
Copy link

ikelos commented Feb 28, 2019

I'm not sure the lru_cache() issue is resolved as of 0.670? The example provided applied lru_cache() to both methods, but this error is still raised if lru_cache() is only used on one method. Is that expected? If not, I'm happy to open a new bug for it if that's the proper way to handle it.

I found this when I had defined an abstractmethod (which therefore didn't need the lru_cache decorator).


class A: 
  def a(self) -> str: 
    return 'a'
  
class B(A): 
  @functools.lru_cache() 
  def a(self) -> str: 
    return super().a() + 'b'

results in:

mypy-test.py:9: error: Signature of "a" incompatible with supertype "A"

@ilevkivskyi
Copy link
Member

Yes, this is a bug, but we already have an issue for this, see #5836

@ikelos
Copy link

ikelos commented Feb 28, 2019

Ok, cool. I'll follow along there, thanks! 5:)

@igor-petrik-invitae
Copy link

igor-petrik-invitae commented Jan 20, 2023

I am still encountering this issue with the following use case on MyPy version 0.991:

from functools import cache


class Base:
    @classmethod
    @cache
    def value(cls) -> str:
        # Some expensive default implementation
        return "[computed default]"


class Simple(Base):
    @classmethod
    def value(cls) -> str:
        return "Simple value that doesn't need caching"

error: Signature of "value" incompatible with supertype "Base" [override]

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

No branches or pull requests

9 participants