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

attrs plugin fails to type check against AttrsInstance protocol with warm cache #14099

Closed
thomascellerier opened this issue Nov 15, 2022 · 2 comments · Fixed by #14551
Closed
Labels

Comments

@thomascellerier
Copy link

thomascellerier commented Nov 15, 2022

Bug Report

Program using protocol for attrs instances fails to typecheck once the mypy cache is warm.

To Reproduce

Given a virtualenv containing:

$ pip freeze
attrs==22.1.0
mypy==0.991
mypy-extensions==0.4.3
tomli==2.0.1
typing_extensions==4.4.0

a.py:

import attr
from typing import Protocol, ClassVar, Any

class AttrsInstance(Protocol):
    """
    A protocol to be able to statically accept an attrs class.
    attr itself defines AttrsInstance but only at type checking time.
    """

    __attrs_attrs__: ClassVar[Any]


@attr.s
class Foo:
    bar: str = attr.ib()

b.py:

from a import AttrsInstance, Foo
from typing import Type

thing: Type[AttrsInstance] = Foo 
print(thing)

First try with cold cache:

$ rm -rf .mypy_cache/  # Make sure the cache is cold
$ mypy a.py b.py
Success: no issues found in 2 source files

Now edit b.py adding one line at the end for example:

from a import AttrsInstance, Foo
from typing import Type

thing: Type[AttrsInstance] = Foo 
print(thing)

foo = False

And re-run mypy, getting error unrelated to the change!

$ mypy a.py b.py
b.py:4: error: Incompatible types in assignment (expression has type "Type[Foo]", variable has type "Type[AttrsInstance]")  [assignment]
Found 1 error in 1 file (checked 2 source files)

Deleting the cache makes it work again:

$ rm -r .mypy_cache/
$ mypy a.py b.py

Note that we also get an error if using AttrsInstance directly instead of Type[AttrsInstance]:

Using this b.py:

from a import AttrsInstance, Foo
from typing import Type

thing: AttrsInstance = Foo("bar")
print(thing)

Results in this after a similar edit to b.py:

(virtualenv) thomas@thomas-xps13:~/Projects/test$ mypy a.py b.py
b.py:4: error: Incompatible types in assignment (expression has type "Foo", variable has type "AttrsInstance")  [assignment]
b.py:4: note: Protocol member AttrsInstance.__attrs_attrs__ expected class variable, got instance variable
b.py:4: note: Protocol member AttrsInstance.__attrs_attrs__ expected settable variable, got read-only attribute
Found 1 error in 1 file (checked 2 source files)

Expected Behavior

Program should still typecheck correctly with warm cache.

Actual Behavior

Program fails to typecheck. Deleting the cache and re-running works as a (slow) workaround.

Your Environment

  • Mypy version used: 0.991
  • Mypy command-line flags: mypy a.py b.py
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.10.6 (ubuntu 22.04, package version 3.10.6-1~22.04.1)
@thomascellerier thomascellerier added the bug mypy got something wrong label Nov 15, 2022
hauntsaninja pushed a commit that referenced this issue Jan 30, 2023
Use correct fullname for `__attrs_attrs__` ClassVar to fix issue with
warm cache.
Closes #14099
cdce8p added a commit to cdce8p/mypy that referenced this issue Jan 30, 2023
…14551)

Use correct fullname for `__attrs_attrs__` ClassVar to fix issue with
warm cache.
Closes python#14099

(cherry picked from commit 8e9f89a)
@thomascellerier
Copy link
Author

Thanks for the fix! I didn't take the time to dig into it myself.

@hauntsaninja
Copy link
Collaborator

Thanks for the great repro!

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

Successfully merging a pull request may close this issue.

3 participants