Skip to content

Mypy mistakes instance attrs for class attrs? #15786

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
poneill opened this issue Jul 30, 2023 · 5 comments
Closed

Mypy mistakes instance attrs for class attrs? #15786

poneill opened this issue Jul 30, 2023 · 5 comments
Labels
bug mypy got something wrong

Comments

@poneill
Copy link

poneill commented Jul 30, 2023

Bug Report

Consider the following class definition:

from typing import Any


class Foo:
    @classmethod
    def bar(cls) -> Any:
        return cls.baz  # mypy correctly catches attr-defined error

Mypy (1.4.1) correctly notices that baz is not defined. However, if we amend the class definition slightly by adding baz as an instance attr like so:

class Foo2:
    def __init__(self, baz: int) -> None:
        self.baz = baz

    @classmethod
    def bar(cls) -> int:
        return cls.baz  # but mypy doesn't catch the attr-defined error here

now mypy doesn't spot the error anymore: it seems to be confused about whether baz is an instance or a class attr.

To Reproduce

Please see playground gist here.

Expected Behavior

I would expect mypy to raise an [attr-defined] error for Foo2 just as for Foo1.

Actual Behavior

main.py:7: error: "type[Foo]" has no attribute "baz"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)

[But mypy finds nothing for Foo2.]

Your Environment

  • Mypy version used: 1.4.1
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files): NA
  • Python version used: 3.11

Thanks!

@poneill poneill added the bug mypy got something wrong label Jul 30, 2023
@erictraut
Copy link

I think this is a duplicate of #240.

@AlexWaygood
Copy link
Member

I think this is a duplicate of #240.

Indeed

@AlexWaygood AlexWaygood closed this as not planned Won't fix, can't repro, duplicate, stale Jul 30, 2023
@ikonst
Copy link
Contributor

ikonst commented Jul 31, 2023

Maybe we should split reading and writing? #240 is about writing to the class instance, which @JukkaL proceeded to comment might be a tough call to make.

@erictraut
Copy link

FWIW, here is a description of how I addressed this problem in pyright.

@poneill
Copy link
Author

poneill commented Jul 31, 2023

Maybe we should split reading and writing? #240 is about writing to the class instance, which @JukkaL proceeded to comment might be a tough call to make.

I'm far from an expert on this topic, but this issue (is about reading instance attributes as class attributes) does seem distinct from #240 (about writing them). (This issue is, however, a duplicate of #240 (comment), #15307, #1097 and others).

The important difference between #240 and this issue, AIUI, is that the snippet in #240 doesn't raise an AttributeError at runtime, so mypy is simply following python's counterintuitive behavior in this case. The snippet in this issue, however, will raise AttributeError:

foo2 = Foo2(1)
foo2.baz  # AttributeError: type object 'Foo2' has no attribute 'baz'

It sounds like there are deep-seated reasons why this error is hard to catch statically, but python does indeed consider it an error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

4 participants