From 79f8473e51dee76d3ffd193ceb36923edf02f295 Mon Sep 17 00:00:00 2001 From: David Peter Date: Tue, 29 Apr 2025 15:04:22 +0200 Subject: [PATCH] [red-knot] Assignability of class literals to Callables (#17704) ## Summary Subtyping was already modeled, but assignability also needs an explicit branch. Removes 921 ecosystem false positives. ## Test Plan New Markdown tests. --- .../mdtest/type_properties/is_assignable_to.md | 12 ++++++++++++ crates/red_knot_python_semantic/src/types.rs | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/crates/red_knot_python_semantic/resources/mdtest/type_properties/is_assignable_to.md b/crates/red_knot_python_semantic/resources/mdtest/type_properties/is_assignable_to.md index f8b8adf5f8..68c7e8ce1a 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/type_properties/is_assignable_to.md +++ b/crates/red_knot_python_semantic/resources/mdtest/type_properties/is_assignable_to.md @@ -529,6 +529,18 @@ c: Callable[[Any], str] = A().f c: Callable[[Any], str] = A().g ``` +### Class literal types + +```py +from typing import Any, Callable + +c: Callable[[str], Any] = str +c: Callable[[str], Any] = int + +# error: [invalid-assignment] +c: Callable[[str], Any] = object +``` + ### Overloads `overloaded.pyi`: diff --git a/crates/red_knot_python_semantic/src/types.rs b/crates/red_knot_python_semantic/src/types.rs index adc6ac478e..335e4d8e1c 100644 --- a/crates/red_knot_python_semantic/src/types.rs +++ b/crates/red_knot_python_semantic/src/types.rs @@ -1503,6 +1503,13 @@ impl<'db> Type<'db> { } } + (Type::ClassLiteral(class_literal), Type::Callable(_)) => { + if let Some(callable) = class_literal.into_callable(db) { + return callable.is_assignable_to(db, target); + } + false + } + (Type::FunctionLiteral(self_function_literal), Type::Callable(_)) => { self_function_literal .into_callable_type(db)