Skip to content

Access abstract class property from class method #8532

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
olirice opened this issue Mar 13, 2020 · 14 comments
Closed

Access abstract class property from class method #8532

olirice opened this issue Mar 13, 2020 · 14 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code good-first-issue priority-2-low

Comments

@olirice
Copy link

olirice commented Mar 13, 2020

When accessing a class property from a class method mypy does not respect the property decorator.

Steps to reproduce:

class Example:

    @property
    @classmethod
    def name(cls) -> str:
        return "my_name"

    def name_length_from_method(self) -> int:
        return len(self.name) # succeeds

    @classmethod
    def name_length_from_class_method(cls) -> int:
        return len(cls.name)  # error: Argument 1 to "len" has incompatible type "Callable[[], str]"
  • Python Version: 3.7.2
  • Mypy Version: 0.770
  • The issue persisted when installed from master 20f7f2d
@msullivan msullivan added bug mypy got something wrong false-positive mypy gave an error on correct code good-first-issue priority-2-low labels Mar 13, 2020
@ErwanDL
Copy link

ErwanDL commented Mar 14, 2020

I would like to try and tackle this issue since it is labelled as a good first issue. @msullivan do you have an idea of where I should start looking ?

@msullivan
Copy link
Collaborator

Probably in checkmember.py

@Sanchit-Trivedi
Copy link

Sanchit-Trivedi commented Mar 17, 2020

Hi @msullivan @olirice . I am a newbie to open source. Please excuse if you perceive this as a dumb question. Saw this issue as it was marked as a good first issue. I ran the given code in python 3.6.9. It is not even working in normal python let alone mypy. Can you please clarify whether this was supposed to be a mypy specific bug or could be in python3 itself?

@olirice olirice changed the title Access class property from class method Access abstract class property from class method Mar 17, 2020
@olirice
Copy link
Author

olirice commented Mar 17, 2020

@Sanchit-Trivedi thank you for catching that. I boiled the example down a little too far!

Here is an updated minimal reproducable example:

from abc import ABC, abstractmethod


class MyBase(ABC):

    @property
    @classmethod
    @abstractmethod
    def name(cls) -> str:
        raise NotImplementedError()

    def name_length_from_method(self) -> int:
        return len(self.name)  # succeeds

    @classmethod
    def name_length_from_class_method(cls) -> int:
        return len(
            cls.name
        )  # error: Argument 1 to "len" has incompatible type "Callable[[], str]"

The valid usage of that abstract base class could be

# Usage Example
class MyClass(MyBase):
    name = "some_name"

print(MyClass().name_length_from_method()) # prints 9
print(MyClass.name_length_from_class_method()) # prints 9

@ErwanDL
Copy link

ErwanDL commented Mar 17, 2020

@olirice are you sure about the usage of the abstract base class ? In the ABC you define name as a property + classmethod, but in your derived class you override it as a class attribute by doing name = "some_name" (so technically it runs, but I am not sure it really does what you intended it to).

After doing a bit of research, it actually seems that combining the @property and @classmethod decorators is not possible the way you did it (https://bugs.python.org/issue20659, https://stackoverflow.com/questions/128573/using-property-on-classmethods). You apparently have to define the property in the metaclass.

@olirice
Copy link
Author

olirice commented Mar 17, 2020

@ErwanDL you're right. There are a bunch of examples floating around that stack abstractmethod, classmethod, and property decorators, but it doesn't appear to be officially supported.

Thanks for your help and sorry this wasn't the good first issue you were looking for!

@olirice olirice closed this as completed Mar 17, 2020
@ErwanDL
Copy link

ErwanDL commented Mar 17, 2020

@olirice no problem, and don't worry there are plenty of issues on this repo for me to dive into :)

@Sanchit-Trivedi
Copy link

@olirice will have to look up other first issues to fix I guess. Can you suggest any?

@olirice
Copy link
Author

olirice commented Mar 17, 2020

@Sanchit-Trivedi thank you as well!
wrt suggesting an issue: sorry, I can't be much help there. I'm similarly new to this codebase

@rominf
Copy link

rominf commented Aug 5, 2021

In 3.9 it's supported: https://docs.python.org/3.9/library/functions.html#classmethod

@mason3k
Copy link

mason3k commented Oct 14, 2021

I believe this is still an issue; as @rominf mentioned, this is officially supported as of 3.9 and I am still receiving spurious errors suggesting that the property is of type Callable[...]

@skymandr
Copy link

skymandr commented Nov 26, 2021

Can confirm this is still an issue in Python 3.9 and mypy 0.910

@tilsche
Copy link

tilsche commented Dec 6, 2021

I have the same issue with mypy 0.910 and Python 3.9.7. It would be great if this could be reopened (and fixed of course).

@hauntsaninja
Copy link
Collaborator

Feel free to follow #11619 , note that CPython might rollback some of the related changes in 3.9

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 good-first-issue priority-2-low
Projects
None yet
Development

No branches or pull requests

9 participants