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

Cryptic error message for two generic callables with different variable binding #17551

Open
lemon24 opened this issue Jul 21, 2024 · 2 comments
Labels

Comments

@lemon24
Copy link

lemon24 commented Jul 21, 2024

Bug Report

If a @contextmanager yields a generic type alias, mypy 1.11 errors with Argument 1 to "contextmanager" has incompatible type "$TYPE"; expected "$TYPE" [arg-type], where the inferred and expected types are identical.

This does not happen if the generic type is inlined (no type alias), or if the type alias is not generic; see playground link below for examples.

This started happening in 1.11 (didn't happen in 1.10). This may be related to #8696, but I opened a new issue because it looks like a regression.

Real code that tripped this: link.

To Reproduce

Short version (more examples in playground links below):

GenericFn = Callable[[_T], _T]

@contextmanager
def make_generic() -> Iterator[GenericFn[_T]]:
    def rv(obj: _T) -> _T:
        return obj
    yield rv

Playground:

Expected Behavior

Either fail with a useful error message (the inferred and expected types being exactly the same is confusing; I am not sure what would fix the error), or don't fail (like 1.10).

Actual Behavior

error: Argument 1 to "contextmanager" has incompatible type "Callable[[], Iterator[Callable[[_T], _T]]]"; expected "Callable[[], Iterator[Callable[[_T], _T]]]"  [arg-type]

Your Environment

  • Mypy version used: 1.11.0
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files): n/a
  • Python version used: 3.12
@lemon24 lemon24 added the bug mypy got something wrong label Jul 21, 2024
@JukkaL
Copy link
Collaborator

JukkaL commented Oct 8, 2024

The behavior changed in #17348.

@ilevkivskyi Do you have an idea of what is going on?

@ilevkivskyi
Copy link
Member

This now "correctly" exposes an old bug #3924. When I print the actual and expected types, they are def [T] () -> Iterator[def (T) -> T] and def () -> Iterator[def [T] (T) -> T] so the error is technically correct, as the former is indeed not a subtype of the latter. The problem is that with current type printing logic, both callables have same user-facing representation.

Actually, I think we should finally fix #3924, although it has only few upvotes, it affects much more people, there are a lot of duplicates since it is hard to track these kind of errors to the original issue. I am also leaving this one open for bad error message.

@ilevkivskyi ilevkivskyi changed the title "incompatible type" for contextmanager yielding a generic type alias (mypy 1.11) Cryptic error message for two generic callables with different variable binding Oct 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants