mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Fixed a bug in the isinstance
and issubclass
type narrowing code paths. They were not handling nested tuples for the second argument.
This commit is contained in:
parent
255497446a
commit
6df560a638
@ -859,8 +859,8 @@ function narrowTypeForIsNone(evaluator: TypeEvaluator, type: Type, isPositiveTes
|
||||
|
||||
// The "isinstance" and "issubclass" calls support two forms - a simple form
|
||||
// that accepts a single class, and a more complex form that accepts a tuple
|
||||
// of classes. This method determines which form and returns a list of classes
|
||||
// or undefined.
|
||||
// of classes (including arbitrarily-nested tuples). This method determines
|
||||
// which form and returns a list of classes or undefined.
|
||||
function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | NoneType | FunctionType)[] | undefined {
|
||||
let foundNonClassType = false;
|
||||
const classTypeList: (ClassType | TypeVarType | NoneType | FunctionType)[] = [];
|
||||
@ -886,16 +886,24 @@ function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | None
|
||||
});
|
||||
};
|
||||
|
||||
doForEachSubtype(argType, (subtype) => {
|
||||
const addClassTypesRecursive = (subtype: Type, recursionCount = 0) => {
|
||||
if (recursionCount > maxTypeRecursionCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isClass(subtype) && TypeBase.isInstance(subtype) && isTupleClass(subtype)) {
|
||||
if (subtype.tupleTypeArguments) {
|
||||
addClassTypesToList(subtype.tupleTypeArguments.map((t) => t.type));
|
||||
subtype.tupleTypeArguments.forEach((tupleEntry) => {
|
||||
addClassTypesRecursive(tupleEntry.type, recursionCount + 1);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
addClassTypesToList([subtype]);
|
||||
}
|
||||
};
|
||||
|
||||
return undefined;
|
||||
doForEachSubtype(argType, (subtype) => {
|
||||
addClassTypesRecursive(subtype);
|
||||
});
|
||||
|
||||
return foundNonClassType ? undefined : classTypeList;
|
||||
|
@ -150,3 +150,13 @@ def handler(node: Base1) -> Any:
|
||||
reveal_type(node.value, expected_text="Base1")
|
||||
if isinstance(node.value, Sub1):
|
||||
reveal_type(node.value, expected_text="Sub1")
|
||||
|
||||
|
||||
def func8(a: int | list[int] | dict[str, int] | None):
|
||||
if isinstance(
|
||||
a,
|
||||
(str, (int, list, type(None))),
|
||||
):
|
||||
reveal_type(a, expected_text="int | list[int] | None")
|
||||
else:
|
||||
reveal_type(a, expected_text="dict[str, int]")
|
||||
|
Loading…
Reference in New Issue
Block a user