mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Fixed bug in pattern matching for Callable()
in the negative (fall-through) case. This addresses #8160. (#8163)
This commit is contained in:
parent
0f654e077b
commit
ef025a1ac2
@ -31,7 +31,6 @@ import {
|
|||||||
import { CodeFlowReferenceExpressionNode } from './codeFlowTypes';
|
import { CodeFlowReferenceExpressionNode } from './codeFlowTypes';
|
||||||
import { populateTypeVarContextBasedOnExpectedType } from './constraintSolver';
|
import { populateTypeVarContextBasedOnExpectedType } from './constraintSolver';
|
||||||
import { getTypeVarScopesForNode, isMatchingExpression } from './parseTreeUtils';
|
import { getTypeVarScopesForNode, isMatchingExpression } from './parseTreeUtils';
|
||||||
import { getTypedDictMembersForClass } from './typedDicts';
|
|
||||||
import { EvaluatorFlags, TypeEvaluator, TypeResult } from './typeEvaluatorTypes';
|
import { EvaluatorFlags, TypeEvaluator, TypeResult } from './typeEvaluatorTypes';
|
||||||
import {
|
import {
|
||||||
enumerateLiteralsForType,
|
enumerateLiteralsForType,
|
||||||
@ -39,27 +38,6 @@ import {
|
|||||||
narrowTypeForDiscriminatedLiteralFieldComparison,
|
narrowTypeForDiscriminatedLiteralFieldComparison,
|
||||||
narrowTypeForDiscriminatedTupleComparison,
|
narrowTypeForDiscriminatedTupleComparison,
|
||||||
} from './typeGuards';
|
} from './typeGuards';
|
||||||
import {
|
|
||||||
AnyType,
|
|
||||||
ClassType,
|
|
||||||
combineTypes,
|
|
||||||
FunctionType,
|
|
||||||
FunctionTypeFlags,
|
|
||||||
isAnyOrUnknown,
|
|
||||||
isClass,
|
|
||||||
isClassInstance,
|
|
||||||
isInstantiableClass,
|
|
||||||
isNever,
|
|
||||||
isSameWithoutLiteralValue,
|
|
||||||
isTypeSame,
|
|
||||||
isUnknown,
|
|
||||||
isUnpackedVariadicTypeVar,
|
|
||||||
NeverType,
|
|
||||||
Type,
|
|
||||||
TypeBase,
|
|
||||||
TypedDictEntry,
|
|
||||||
UnknownType,
|
|
||||||
} from './types';
|
|
||||||
import {
|
import {
|
||||||
addConditionToType,
|
addConditionToType,
|
||||||
applySolvedTypeVars,
|
applySolvedTypeVars,
|
||||||
@ -85,6 +63,28 @@ import {
|
|||||||
transformPossibleRecursiveTypeAlias,
|
transformPossibleRecursiveTypeAlias,
|
||||||
} from './typeUtils';
|
} from './typeUtils';
|
||||||
import { TypeVarContext } from './typeVarContext';
|
import { TypeVarContext } from './typeVarContext';
|
||||||
|
import { getTypedDictMembersForClass } from './typedDicts';
|
||||||
|
import {
|
||||||
|
AnyType,
|
||||||
|
ClassType,
|
||||||
|
FunctionType,
|
||||||
|
FunctionTypeFlags,
|
||||||
|
NeverType,
|
||||||
|
Type,
|
||||||
|
TypeBase,
|
||||||
|
TypedDictEntry,
|
||||||
|
UnknownType,
|
||||||
|
combineTypes,
|
||||||
|
isAnyOrUnknown,
|
||||||
|
isClass,
|
||||||
|
isClassInstance,
|
||||||
|
isInstantiableClass,
|
||||||
|
isNever,
|
||||||
|
isSameWithoutLiteralValue,
|
||||||
|
isTypeSame,
|
||||||
|
isUnknown,
|
||||||
|
isUnpackedVariadicTypeVar,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
// PEP 634 indicates that several built-in classes are handled differently
|
// PEP 634 indicates that several built-in classes are handled differently
|
||||||
// when used with class pattern matching.
|
// when used with class pattern matching.
|
||||||
@ -720,10 +720,22 @@ function narrowTypeBasedOnClassPattern(
|
|||||||
return subjectSubtypeExpanded;
|
return subjectSubtypeExpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle Callable specially.
|
||||||
|
if (
|
||||||
|
!isAnyOrUnknown(subjectSubtypeExpanded) &&
|
||||||
|
isInstantiableClass(classType) &&
|
||||||
|
ClassType.isBuiltIn(classType, 'Callable')
|
||||||
|
) {
|
||||||
|
if (evaluator.assignType(getUnknownTypeForCallable(), subjectSubtypeExpanded)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!isNoneInstance(subjectSubtypeExpanded) && !isClassInstance(subjectSubtypeExpanded)) {
|
if (!isNoneInstance(subjectSubtypeExpanded) && !isClassInstance(subjectSubtypeExpanded)) {
|
||||||
return subjectSubtypeUnexpanded;
|
return subjectSubtypeUnexpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle NoneType specially.
|
||||||
if (
|
if (
|
||||||
isNoneInstance(subjectSubtypeExpanded) &&
|
isNoneInstance(subjectSubtypeExpanded) &&
|
||||||
isInstantiableClass(classType) &&
|
isInstantiableClass(classType) &&
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# This sample tests the case where `Callable()` is used as a class pattern.
|
# This sample tests the case where `Callable()` is used as a class pattern.
|
||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from typing import Any, TypeVar
|
from typing import Any, Protocol, TypeVar
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
@ -38,3 +38,28 @@ def func5(obj: Any):
|
|||||||
case Callable():
|
case Callable():
|
||||||
reveal_type(obj, expected_text="(...) -> Any")
|
reveal_type(obj, expected_text="(...) -> Any")
|
||||||
return obj()
|
return obj()
|
||||||
|
|
||||||
|
|
||||||
|
def func6(obj: Callable[[], None]):
|
||||||
|
match obj:
|
||||||
|
case Callable():
|
||||||
|
reveal_type(obj, expected_text="() -> None")
|
||||||
|
return obj()
|
||||||
|
|
||||||
|
case x:
|
||||||
|
reveal_type(obj, expected_text="Never")
|
||||||
|
|
||||||
|
|
||||||
|
class CallableProto(Protocol):
|
||||||
|
def __call__(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func7(obj: CallableProto):
|
||||||
|
match obj:
|
||||||
|
case Callable():
|
||||||
|
reveal_type(obj, expected_text="CallableProto")
|
||||||
|
return obj()
|
||||||
|
|
||||||
|
case x:
|
||||||
|
reveal_type(obj, expected_text="Never")
|
||||||
|
Loading…
Reference in New Issue
Block a user