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

mypy failed to narrow down union types including Self with isinstance #14912

Closed
mon-jai opened this issue Mar 16, 2023 · 2 comments · Fixed by #14923
Closed

mypy failed to narrow down union types including Self with isinstance #14912

mon-jai opened this issue Mar 16, 2023 · 2 comments · Fixed by #14923
Labels
bug mypy got something wrong topic-self-types Types for self topic-type-variables

Comments

@mon-jai
Copy link

mon-jai commented Mar 16, 2023

Bug Report

mypy failed to narrow down union types including Self with isinstance.

To Reproduce

Consider the following code:

from dataclasses import dataclass
from typing import Self, reveal_type


@dataclass
class Foo:
    i: int

    def bar(self, other: Self | int) -> int:
        if isinstance(other, Foo):
            return self.i * other.i
        else:
            reveal_type(other)  # "int" expected, gets "Self | int"
            return self.i * other # Unsupported operand types for * ("int" and "Self")  [operator]mypy(error)

Expected Behavior

Other should be infered as an int and mypy reports no error.

Actual Behavior

mypy failed to narrow type of other

Revealed type is "Union[Self`0, builtins.int]"mypy(note)

Also, mypy reports the following error.

Unsupported operand types for * ("int" and "Self")  [operator]mypy(error)

Your Environment

  • Mypy version used: 1.1.1
  • Mypy command-line flags: --follow-imports=silent --ignore-missing-imports --show-column-numbers --no-pretty (VSCode defaults)
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.11.1
@mon-jai mon-jai added the bug mypy got something wrong label Mar 16, 2023
@mon-jai
Copy link
Author

mon-jai commented Mar 17, 2023

isinstance(other, self.__class__) doesn't work too.

@tyralla
Copy link
Collaborator

tyralla commented Mar 18, 2023

Simpler repro:

[case testNarrowSelfType]
from typing import Self, Union
class A: ...
class B:
    def f(self, v: Union[Self, A]) -> A:
        if isinstance(v, B):
            return A()
        else:
            return v  # false error: Incompatible return value type (got "Union[Self, A]", expected "A")
[builtins fixtures/isinstancelist.pyi]

hauntsaninja pushed a commit that referenced this issue Mar 25, 2023
Fix narrowing union types that include Self with isinstance (Fixes #14912).

The special case of bound type variables was not handled in function `covers_at_runtime` of module `subtypes`.  So I added it and defined the test case `testNarrowSelfType`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-self-types Types for self topic-type-variables
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants