mirror of
https://github.com/microsoft/pyright.git
synced 2024-11-12 23:46:20 +03:00
Fixed false positive error that occurs when using an issubclass
type guard to narrow a type to an abstract base class. The resulting type should be instantiable without receiving a "cannot instantiate ABC" error.
This commit is contained in:
parent
1b09c1aea0
commit
e586d6f1f1
@ -1060,7 +1060,14 @@ function narrowTypeForIsInstance(
|
||||
]) as ClassType;
|
||||
}
|
||||
|
||||
filteredTypes.push(isInstanceCheck ? ClassType.cloneAsInstance(newClassType) : newClassType);
|
||||
const newClassInstanceType = ClassType.cloneAsInstance(newClassType);
|
||||
|
||||
// If this is a issubclass check, we do a double conversion from instantiable
|
||||
// to instance back to instantiable to make sure that the includeSubclasses flag
|
||||
// gets cleared.
|
||||
filteredTypes.push(
|
||||
isInstanceCheck ? newClassInstanceType : ClassType.cloneAsInstantiable(newClassInstanceType)
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (isTypeVar(filterType) && TypeBase.isInstantiable(filterType)) {
|
||||
@ -1198,7 +1205,14 @@ function narrowTypeForIsInstance(
|
||||
combineTypes(classTypeList.map((classType) => convertToInstance(classType)))
|
||||
);
|
||||
} else {
|
||||
anyOrUnknownSubstitutions.push(combineTypes(classTypeList));
|
||||
// We perform a double conversion from instance to instantiable
|
||||
// here to make sure that the includeSubclasses flag is cleared
|
||||
// if it's a class.
|
||||
anyOrUnknownSubstitutions.push(
|
||||
combineTypes(
|
||||
classTypeList.map((classType) => convertToInstantiable(convertToInstance(classType)))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
anyOrUnknown.push(subtype);
|
||||
|
@ -0,0 +1,19 @@
|
||||
# This sample tests the case where an issubclass type guard narrows
|
||||
# to an abstract base class. When attempting to instantiate the
|
||||
# class, there should be no "cannot instantiate ABC" error.
|
||||
|
||||
# pyright: strict
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any
|
||||
|
||||
|
||||
class Base(ABC):
|
||||
@abstractmethod
|
||||
def f(self) -> None:
|
||||
...
|
||||
|
||||
|
||||
def func(cls: Any):
|
||||
assert issubclass(cls, Base)
|
||||
_ = cls()
|
@ -374,6 +374,12 @@ test('TypeNarrowingIsinstance7', () => {
|
||||
TestUtils.validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('TypeNarrowingIsinstance8', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeNarrowingIsinstance8.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('TypeNarrowingTupleLength1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeNarrowingTupleLength1.py']);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user