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

Class inheriting from property doesn't typecheck properly when used as a decorator #6158

Open
matthchr opened this issue Jan 8, 2019 · 3 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-descriptors Properties, class vs. instance attributes

Comments

@matthchr
Copy link

matthchr commented Jan 8, 2019

I have a custom class inheriting from property. When I go to use this as a decorator though mypy seems to miss that it's a property at all. This is with Python 3.6.3 and mypy 0.650.

Example:

class CustomProperty(property):
    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        super().__init__(fget, fset, fdel, doc)

class A:
    def __init__(self) -> None:
        self._val = 1

    @CustomProperty
    def val(self) -> int:
        return self._val

    @val.setter
    def val(self, v: int) -> None:
        self._val = v


def test_a() -> None:
    print(A.val)

Running mypy on this gives the following output:
mypy minimal2.py

minimal.py:14: error: Name 'val' already defined on line 10
minimal.py:14: error: Name 'val' is not defined
minimal.py:20: error: "Type[A]" has no attribute "val"

Contrast this with the same code with the builtin property which typechecks fine:

class B:
    def __init__(self) -> None:
        self._val = 1

    @property
    def val(self) -> int:
        return self._val

    @val.setter
    def val(self, v: int) -> None:
        self._val = v

def test_b() -> None:
    print(B.val)

It's possible that this is related to #1529 where @ilevkivskyi suggested that:

The original example now passes mypy, not sure however how useful the subclass can be (property is heavily special-cased in mypy), but at least the original bug is fixed, so closing this.

Is subclassing property frowned upon (or just not supported in mypy?).

@msullivan
Copy link
Collaborator

Unfortunately mypy doesn't support subclassing property right now.

In simple use-cases, you can get away with something like

if TYPE_CHECKING:
    CustomProperty = property
else:
    # real CustomProperty definition

but this won't work if you need a custom constructor

@ilevkivskyi
Copy link
Member

In some sense this is a "duplicate" of #220, but the latter is too broad, so I propose to keep this open instead of accumulating example of unsupported patterns in that issue.

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal false-positive mypy gave an error on correct code labels Jan 9, 2019
@AlexWaygood AlexWaygood added the topic-descriptors Properties, class vs. instance attributes label Mar 26, 2022
@johhnry
Copy link

johhnry commented Feb 5, 2024

Hi! Are there any update on this? I am using MyPy 1.8.0 and this doesn't work:

class custom(property):
    pass

class A:
    @custom
    def p(self):
        return 0
        
    @custom.setter
    def p(self, v: int) -> None:
        return
main.py:9: error: Name "p" already defined on line 5  [no-redef]
Found 1 error in 1 file (checked 1 source file)

The fix from @msullivan works thought but it's not clean...

Thanks!

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 topic-descriptors Properties, class vs. instance attributes
Projects
None yet
Development

No branches or pull requests

5 participants