Fixed a bug that results in a false positive error when Callable() is used as a class pattern and the subject type is Any or Unknown. This addresses #7794. (#7796)

This commit is contained in:
Eric Traut 2024-04-28 18:44:26 -07:00 committed by GitHub
parent 556608dffd
commit 4c1eb615af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 1 deletions

View File

@ -43,6 +43,8 @@ import {
AnyType,
ClassType,
combineTypes,
FunctionType,
FunctionTypeFlags,
isAnyOrUnknown,
isClass,
isClassInstance,
@ -816,6 +818,20 @@ function narrowTypeBasedOnClassPattern(
return evaluator.mapSubtypesExpandTypeVars(type, /* options */ undefined, (subjectSubtypeExpanded) => {
if (isAnyOrUnknown(subjectSubtypeExpanded)) {
if (isInstantiableClass(expandedSubtype) && ClassType.isBuiltIn(expandedSubtype, 'Callable')) {
// Convert to an unknown callable type.
const unknownCallable = FunctionType.createSynthesizedInstance(
'',
FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck
);
FunctionType.addDefaultParameters(
unknownCallable,
/* useUnknown */ isUnknown(subjectSubtypeExpanded)
);
unknownCallable.details.declaredReturnType = subjectSubtypeExpanded;
return unknownCallable;
}
return convertToInstance(unexpandedSubtype);
}

View File

@ -1,7 +1,7 @@
# This sample tests the case where `Callable()` is used as a class pattern.
from collections.abc import Callable
from typing import TypeVar
from typing import Any, TypeVar
T = TypeVar("T")
@ -24,3 +24,17 @@ def func3(obj: type[int] | Callable[..., str]) -> int | str | None:
case Callable():
reveal_type(obj, expected_text="type[int] | ((...) -> str)")
return obj()
def func4(obj):
match obj:
case Callable():
reveal_type(obj, expected_text="(...) -> Unknown")
return obj()
def func5(obj: Any):
match obj:
case Callable():
reveal_type(obj, expected_text="(...) -> Any")
return obj()