Skip to content

Intersection between Protocol and almost overlapping class is simplified incorrectly #770

@JelleZijlstra

Description

@JelleZijlstra

Summary

In the below example, ty incorrectly simplifies a Protocol out of an intersection when it almost (but not quite) is the same as a nominal class.

https://play.ty.dev/9b0ac32c-9200-4558-8269-6e3f3bea1837

from typing import Protocol
from ty_extensions import Intersection, Not

class Proto(Protocol):
    def meth(self) -> int: ...

class X:
    def meth(self) -> int | str: return 42

def f(x: Intersection[X, Proto]):
    reveal_type(x)  # X (expect X & Proto)
    reveal_type(x.meth())  # int | str (expect int)

This can also lead to incorrect type inference without explicit Intersection types (https://play.ty.dev/6185eec9-9e29-49f6-b0ef-b817844fedb5):

from typing import Protocol

class Proto(Protocol):
    def meth(self) -> int: ...

class X:
    def meth(self) -> int | str: return 42

def f(x: Proto):
    if isinstance(x, X):
        reveal_type(x)  # X
        reveal_type(x.meth())  # int | str

Version

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions