Skip to content

Type-narrowing based on instance type #19671

Open

Description

@nenb

Bug Report

I would like to do a form of type narrowing based on the instance type. Minimal example in the script below.

mypy tells me that my script is not a valid pattern though. Is this true, or is it a bug?

To Reproduce

from typing import overload, Protocol, Self

class HasOverride(Protocol):
    override: bool

class A():
       
    @overload
    def fake_method(self: HasOverride) -> "A":
        ...
    
    @overload
    def fake_method(self) -> Self:
        ...
        
    def fake_method(self) -> Self | "A":
        if hasattr(self, 'override'):
            return A()
        return self
    
class B(A):  # fake_method should return B
    pass

class C(A):  # fake_method should return A
    override = True

Expected Behavior

mypy 1.16.0 raises the following error:

error: Overloaded function implementation cannot satisfy signature 1 due to inconsistencies in how they use type variables [misc]

pyright 1.1.403 does not raise an error.

It seems reasonable to me to allow this pattern, which is why I am opening this as a bug report.

If this is in fact desired behaviour, I would be very grateful for an explanation and, if possible, a suggested alternative pattern (I'm a bit desperate!).

Actual Behavior

Your Environment

  • Mypy version used: 1.16.0 (but have also repeated on 1.17.1)
  • Mypy command-line flags: just mypy (from a clean environment I pip installed mypy and then ran `mypy on the script above)
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.11.13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions