From 21be94ac33f445d8a681babec6c56ca3d1b67156 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 25 Sep 2025 10:21:29 +0100 Subject: [PATCH] [ty] Explicitly test assignability/subtyping between unions of nominal types and protocols with method members (#20557) --- .../resources/mdtest/protocols.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/ty_python_semantic/resources/mdtest/protocols.md b/crates/ty_python_semantic/resources/mdtest/protocols.md index e9de6e7536..94a30d6379 100644 --- a/crates/ty_python_semantic/resources/mdtest/protocols.md +++ b/crates/ty_python_semantic/resources/mdtest/protocols.md @@ -1769,6 +1769,9 @@ class P(Protocol): class NominalSubtype: def m(self, y: int) -> None: ... +class NominalSubtype2: + def m(self, *args: object) -> None: ... + class NotSubtype: def m(self, x: int) -> int: return 42 @@ -1785,18 +1788,24 @@ class DefinitelyNotSubtype: m = None static_assert(is_subtype_of(NominalSubtype, P)) +static_assert(is_subtype_of(NominalSubtype2, P)) +static_assert(is_subtype_of(NominalSubtype | NominalSubtype2, P)) static_assert(not is_assignable_to(DefinitelyNotSubtype, P)) static_assert(not is_assignable_to(NotSubtype, P)) +static_assert(not is_assignable_to(NominalSubtype | NotSubtype, P)) +static_assert(not is_assignable_to(NominalSubtype2 | DefinitelyNotSubtype, P)) # `m` has the correct signature when accessed on instances of `NominalWithClassMethod`, # but not when accessed on the class object `NominalWithClassMethod` itself # -# TODO: this should pass +# TODO: these should pass static_assert(not is_assignable_to(NominalWithClassMethod, P)) # error: [static-assert-error] +static_assert(not is_assignable_to(NominalSubtype | NominalWithClassMethod, P)) # error: [static-assert-error] # Conversely, `m` has the correct signature when accessed on the class object # `NominalWithStaticMethod`, but not when accessed on instances of `NominalWithStaticMethod` static_assert(not is_assignable_to(NominalWithStaticMethod, P)) +static_assert(not is_assignable_to(NominalSubtype | NominalWithStaticMethod, P)) ``` A callable instance attribute is not sufficient for a type to satisfy a protocol with a method @@ -2112,6 +2121,7 @@ static_assert(is_subtype_of(NClassMethodGood, PClassMethod)) # error: [static-a static_assert(is_subtype_of(NClassMethodGood, PStaticMethod)) # error: [static-assert-error] static_assert(not is_assignable_to(NClassMethodBad, PClassMethod)) # error: [static-assert-error] static_assert(not is_assignable_to(NClassMethodBad, PStaticMethod)) # error: [static-assert-error] +static_assert(not is_assignable_to(NClassMethodGood | NClassMethodBad, PClassMethod)) # error: [static-assert-error] static_assert(is_assignable_to(NStaticMethodGood, PClassMethod)) static_assert(is_assignable_to(NStaticMethodGood, PStaticMethod)) @@ -2120,6 +2130,7 @@ static_assert(is_subtype_of(NStaticMethodGood, PClassMethod)) # error: [static- static_assert(is_subtype_of(NStaticMethodGood, PStaticMethod)) # error: [static-assert-error] static_assert(not is_assignable_to(NStaticMethodBad, PClassMethod)) # error: [static-assert-error] static_assert(not is_assignable_to(NStaticMethodBad, PStaticMethod)) # error: [static-assert-error] +static_assert(not is_assignable_to(NStaticMethodGood | NStaticMethodBad, PStaticMethod)) # error: [static-assert-error] ``` ## Equivalence of protocols with method or property members