From b6954063c19f397cf70e622befe11816fc6f13bd Mon Sep 17 00:00:00 2001 From: David Peter Date: Mon, 13 Oct 2025 13:15:36 +0200 Subject: [PATCH] [ty] Do not function-like property for `Callable` type relations --- .../mdtest/dataclasses/dataclasses.md | 20 +++++++++++++++---- crates/ty_python_semantic/src/types.rs | 9 ++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md b/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md index bb2092aa5c..7eb2ff9d67 100644 --- a/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md +++ b/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md @@ -1204,9 +1204,9 @@ python-version = "3.12" from dataclasses import dataclass from typing import Callable from types import FunctionType -from ty_extensions import CallableTypeOf, TypeOf, static_assert, is_subtype_of, is_assignable_to +from ty_extensions import CallableTypeOf, TypeOf, static_assert, is_subtype_of, is_assignable_to, is_equivalent_to -@dataclass +@dataclass(order=True) class C: x: int @@ -1233,8 +1233,20 @@ static_assert(not is_assignable_to(EquivalentPureCallableType, DunderInitType)) static_assert(is_subtype_of(DunderInitType, EquivalentFunctionLikeCallableType)) static_assert(is_assignable_to(DunderInitType, EquivalentFunctionLikeCallableType)) -static_assert(not is_subtype_of(EquivalentFunctionLikeCallableType, DunderInitType)) -static_assert(not is_assignable_to(EquivalentFunctionLikeCallableType, DunderInitType)) +static_assert(is_subtype_of(EquivalentFunctionLikeCallableType, DunderInitType)) +static_assert(is_assignable_to(EquivalentFunctionLikeCallableType, DunderInitType)) + +static_assert(is_equivalent_to(EquivalentFunctionLikeCallableType, DunderInitType)) static_assert(is_subtype_of(DunderInitType, FunctionType)) ``` + +It should be possible to mock out synthesized methods: + +```py +from unittest.mock import Mock + +def test_c(): + c = C(1) + c.__lt__ = Mock() +``` diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index 5dd17d692d..cfd68b1a12 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -9945,9 +9945,6 @@ impl<'db> CallableType<'db> { relation_visitor: &HasRelationToVisitor<'db>, disjointness_visitor: &IsDisjointVisitor<'db>, ) -> ConstraintSet<'db> { - if other.is_function_like(db) && !self.is_function_like(db) { - return ConstraintSet::from(false); - } self.signatures(db).has_relation_to_impl( db, other.signatures(db), @@ -9970,10 +9967,8 @@ impl<'db> CallableType<'db> { return ConstraintSet::from(true); } - ConstraintSet::from(self.is_function_like(db) == other.is_function_like(db)).and(db, || { - self.signatures(db) - .is_equivalent_to_impl(db, other.signatures(db), visitor) - }) + self.signatures(db) + .is_equivalent_to_impl(db, other.signatures(db), visitor) } }