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

False-positive error on overriding attribute of base class with rtype-annotated property #9134

Open
sizmailov opened this issue Jul 12, 2020 · 3 comments

Comments

@sizmailov
Copy link
Contributor

(bug report)

Annotation of property of derived class with -> Any makes mypy complain about incompatibility with base class. The exact rtype doesn't matter, the error is still the same. The MRE is a simplified version of stubgen output.

MRE:

from typing import Any

class A:
    doc = ""

class B(A):
    # remove "-> Any" to make mypy happy
    @property
    def doc(self) -> Any:
        return ""

Expected: no errors reported

Actual:

foo.py:11: error: Signature of "doc" incompatible with supertype "A"
Found 1 error in 1 file (checked 1 source file)

command line command: mypy foo.py

version info:
mypy: 0.790+dev.ffdbeb3d47ccb2d9691b36993be0a18e0718d997
python: 3.7.3

P.S.: The error message of Signature of "doc" incompatible with supertype "A" should be more descriptive. It's good enough for simple cases, but rather cryptic for more involved examples. (I realize it might be not so trivial to propagate the root source of incompatibility and represent it nicely)

@JukkaL
Copy link
Collaborator

JukkaL commented Sep 11, 2020

The error message is kind of reasonable, since doc is mutable in A but not in B. If you don't have an annotation, mypy treats the code as untyped and omits various checks.

The error message of Signature of "doc" incompatible with supertype "A" should be more descriptive

I think that mypy sometimes produces a better message, but not in this case. Would you like to create a separate issue about the better error message?

@sizmailov
Copy link
Contributor Author

The error message is kind of reasonable, since doc is mutable in A but not in B.

If it so, the next snippet should pass the check, right?

from typing import Any


class A:
    doc = ""


class B(A):
    @property
    def doc(self) -> Any:
        return ""

    @doc.setter
    def doc(self, value: str) -> None:
        print("set")

    @doc.deleter
    def doc(self) -> None:
        print("del")

In fact mypy reports the same error:

example.py:9: error: Signature of "doc" incompatible with supertype "A"
example.py:10: error: Signature of "doc" incompatible with supertype "A"
Found 2 errors in 1 file (checked 1 source file)

At the moment I'm not sure what makes mypy complain about this snippet to file another issue.

@sizmailov
Copy link
Contributor Author

Apparently @property decorator is treated as black box and effectively () -> Any gets compared to str.

Another form of overriding value-attribute with property triggers another false-positive error:

class B(A):
    doc = property(...)
# Incompatible types in assignment (expression has type "property", base class "A" defined the type as "str")

Same applies to custom descriptors as well:

class B(A):
    doc = RevealAccess(10, 'var "x"')
# Incompatible types in assignment (expression has type "RevealAccess", base class "A" defined the type as "str")

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