Skip to content

mypy thinks value is <nothing> when it isn't #15793

Closed

Description

@zevbo

Mypy believes that it is impossible for an isinstance to succeed if the known type has a generic and the subtype has specified that generic.

To Reproduce

from typing import Generic, TypeVar, cast

T = TypeVar("T")

class A(Generic[T]):
    pass

class B(A[str]):
    something: int = 0

def f(b: A[T]) -> None:
    if isinstance(b, B):
        print(b.something)

Expected Behavior

Mypy should have no problems with this code

Actual Behavior

dumb_test.py:16: error: <nothing> has no attribute "something"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.4.1. This bug reproduces at least back to 1.2.0
  • Mypy command-line flags: None. Just run with mypy FILE
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.10.0

Activity

  1. added
    bugmypy got something wrong
    on Aug 1, 2023
  2. changed the title [-]mypy thinks value is `<nothing>` when it clearly isn't[/-] [+]mypy thinks value is `<nothing>` when it isn't[/+] on Aug 1, 2023
  3. erictraut commented on Aug 14, 2023

    @erictraut

    The code sample contains a bug. The f function is using type variable T in an incorrect manner. A type variable scoped to a function should always appear in the return type annotation. In your example, the correct annotation for parameter b is T[Any]. If you make this change, the code type checks without error.

    It may be a good idea for mypy to emit an error when a type variable is used in an incorrect manner like this. There was a discussion about this in the typing forums a while back. If I remember correctly, the authors of pyright, pytype and pyre all decided to add such an error (or warning), but mypy does not emit an error in this case.

  4. jack-tutor commented on Aug 14, 2023

    @jack-tutor

    I don't think that is the issue here. Edited to return T (T[Any] doesn't make sense as far as I understand).

    from __future__ import annotations
    
    from typing import Generic, TypeVar, cast
    
    T = TypeVar("T")
    
    
    class A(Generic[T]):
        pass
    
    
    class B(A[str]):
        something: int = 0
    
    
    def f(b: A[T]) -> T:
        if isinstance(b, B):
            print(b.something)
        raise NotImplementedError()
    

    but this still fails:

    error: <nothing> has no attribute "something"  [attr-defined]
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions