Skip to content

Nontransitive subtyping involving protocols and object #720

@JelleZijlstra

Description

@JelleZijlstra

Summary

ty currently fails the last assert in this file:

from ty_extensions import static_assert, is_subtype_of
from typing import Protocol

class P(Protocol):
    def __str__(self) -> str: ...

class P2(Protocol):
    x: int

static_assert(is_subtype_of(object, P))
static_assert(is_subtype_of(P2, object))
static_assert(is_subtype_of(P2, P))

https://play.ty.dev/23be40f7-3ebf-4785-991b-29c7508b5e22

That is, it accepts that P2 <: object and object <: P, but not that P2 <: P.

ty has a property test asserting that subtyping is transitive, but it apparently didn't catch this case.

Transitivity of subtyping is important for making union simplification deterministic, but it seems that is not an issue in practice here, because P is also a subtype of object (in the other direction) and ty prefers simplifying to object.

I think this is more of a curiosity than a real bug that can break soundness, but reporting it anyway in case it's more serious than I thought.

Version

No response

Metadata

Metadata

Assignees

Labels

ProtocolsbugSomething isn't workingtype propertiessubtyping, assignability, equivalence, and more

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions