@zzzen/pyright-internal 1.2.0-dev.20240908 → 1.2.0-dev.20240915
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/analysis.d.ts +1 -0
- package/dist/analyzer/analysis.js +2 -0
- package/dist/analyzer/analysis.js.map +1 -1
- package/dist/analyzer/backgroundAnalysisProgram.js +6 -2
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/cacheManager.d.ts +2 -2
- package/dist/analyzer/cacheManager.js.map +1 -1
- package/dist/analyzer/checker.js +30 -151
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constraintSolver.d.ts +1 -2
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/patternMatching.js +3 -1
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.js +2 -3
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +1 -2
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/pythonPathUtils.d.ts +1 -1
- package/dist/analyzer/service.d.ts +3 -1
- package/dist/analyzer/service.js +50 -33
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceMapper.js +8 -4
- package/dist/analyzer/sourceMapper.js.map +1 -1
- package/dist/analyzer/tuples.d.ts +1 -2
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +103 -66
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +22 -1
- package/dist/analyzer/typeEvaluatorTypes.js +62 -1
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +3 -12
- package/dist/analyzer/typeGuards.js +276 -454
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.d.ts +1 -2
- package/dist/analyzer/typePrinter.js +4 -24
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeStubWriter.js +12 -1
- package/dist/analyzer/typeStubWriter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +0 -17
- package/dist/analyzer/typeUtils.js +7 -59
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +1 -2
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +1 -0
- package/dist/analyzer/types.js +12 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +23 -16
- package/dist/backgroundAnalysisBase.js +64 -35
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.js +9 -0
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/common/languageServerInterface.d.ts +1 -1
- package/dist/common/uri/uriUtils.d.ts +1 -1
- package/dist/common/uri/uriUtils.js +6 -1
- package/dist/common/uri/uriUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +2 -2
- package/dist/languageServerBase.js +1 -3
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/analyzerServiceExecutor.d.ts +6 -1
- package/dist/languageService/analyzerServiceExecutor.js +7 -6
- package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
- package/dist/languageService/fileWatcherDynamicFeature.d.ts +5 -1
- package/dist/languageService/fileWatcherDynamicFeature.js +12 -2
- package/dist/languageService/fileWatcherDynamicFeature.js.map +1 -1
- package/dist/localization/localize.d.ts +8 -0
- package/dist/localization/localize.js +2 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +155 -153
- package/dist/localization/package.nls.de.json +128 -126
- package/dist/localization/package.nls.en-us.json +1632 -406
- package/dist/localization/package.nls.es.json +151 -149
- package/dist/localization/package.nls.fr.json +129 -127
- package/dist/localization/package.nls.it.json +143 -141
- package/dist/localization/package.nls.ja.json +142 -140
- package/dist/localization/package.nls.ko.json +155 -153
- package/dist/localization/package.nls.pl.json +178 -176
- package/dist/localization/package.nls.pt-br.json +139 -137
- package/dist/localization/package.nls.qps-ploc.json +392 -390
- package/dist/localization/package.nls.ru.json +170 -168
- package/dist/localization/package.nls.tr.json +153 -151
- package/dist/localization/package.nls.zh-cn.json +149 -147
- package/dist/localization/package.nls.zh-tw.json +133 -131
- package/dist/tests/checker.test.js +9 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/envVarUtils.test.js +0 -3
- package/dist/tests/envVarUtils.test.js.map +1 -1
- package/dist/tests/harness/fourslash/testLanguageService.js +0 -3
- package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.js +2 -5
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/harness/fourslash/testStateUtils.d.ts +1 -0
- package/dist/tests/harness/fourslash/testStateUtils.js +5 -0
- package/dist/tests/harness/fourslash/testStateUtils.js.map +1 -1
- package/dist/tests/harness/vfs/filesystem.d.ts +3 -2
- package/dist/tests/harness/vfs/filesystem.js +6 -3
- package/dist/tests/harness/vfs/filesystem.js.map +1 -1
- package/dist/tests/service.test.js +31 -0
- package/dist/tests/service.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +4 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +4 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator6.test.js +5 -1
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +1 -1
- package/dist/tests/typeEvaluator8.test.js +2 -2
- package/dist/workspaceFactory.d.ts +2 -20
- package/dist/workspaceFactory.js +19 -57
- package/dist/workspaceFactory.js.map +1 -1
- package/package.json +1 -1
@@ -33,17 +33,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
33
33
|
return result;
|
34
34
|
};
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
36
|
-
exports.Tree = exports.Plant = exports.Dog = exports.Animal = void 0;
|
37
36
|
exports.getTypeNarrowingCallback = getTypeNarrowingCallback;
|
38
|
-
exports.
|
39
|
-
exports.
|
37
|
+
exports.getIsInstanceClassTypes = getIsInstanceClassTypes;
|
38
|
+
exports.narrowTypeForInstanceOrSubclass = narrowTypeForInstanceOrSubclass;
|
40
39
|
exports.getElementTypeForContainerNarrowing = getElementTypeForContainerNarrowing;
|
41
40
|
exports.narrowTypeForContainerElementType = narrowTypeForContainerElementType;
|
42
41
|
exports.narrowTypeForDiscriminatedDictEntryComparison = narrowTypeForDiscriminatedDictEntryComparison;
|
43
42
|
exports.narrowTypeForDiscriminatedTupleComparison = narrowTypeForDiscriminatedTupleComparison;
|
44
43
|
exports.narrowTypeForDiscriminatedLiteralFieldComparison = narrowTypeForDiscriminatedLiteralFieldComparison;
|
45
44
|
exports.enumerateLiteralsForType = enumerateLiteralsForType;
|
46
|
-
exports.func1 = func1;
|
47
45
|
const debug_1 = require("../common/debug");
|
48
46
|
const parseNodes_1 = require("../parser/parseNodes");
|
49
47
|
const analyzerNodeInfo_1 = require("./analyzerNodeInfo");
|
@@ -127,7 +125,7 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
127
125
|
if (ParseTreeUtils.isMatchingExpression(reference, leftExpression)) {
|
128
126
|
return (type) => {
|
129
127
|
return {
|
130
|
-
type: narrowTypeForIsEllipsis(evaluator, type, adjIsPositiveTest),
|
128
|
+
type: narrowTypeForIsEllipsis(evaluator, testExpression, type, adjIsPositiveTest),
|
131
129
|
isIncomplete: false,
|
132
130
|
};
|
133
131
|
};
|
@@ -230,12 +228,7 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
230
228
|
// Look for X == <literal> or X != <literal>
|
231
229
|
const adjIsPositiveTest = testExpression.d.operator === 12 /* OperatorType.Equals */ ? isPositiveTest : !isPositiveTest;
|
232
230
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpr)) {
|
233
|
-
|
234
|
-
// important in cases where evaluation of the right expression creates
|
235
|
-
// a false dependency on another variable.
|
236
|
-
const rightTypeResult = evaluator.useSpeculativeMode(testExpression.d.rightExpr, () => {
|
237
|
-
return evaluator.getTypeOfExpression(testExpression.d.rightExpr);
|
238
|
-
});
|
231
|
+
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpr);
|
239
232
|
const rightType = rightTypeResult.type;
|
240
233
|
if ((0, types_1.isClassInstance)(rightType) && rightType.priv.literalValue !== undefined) {
|
241
234
|
return (type) => {
|
@@ -417,7 +410,7 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
417
410
|
if (classTypeList) {
|
418
411
|
return (type) => {
|
419
412
|
return {
|
420
|
-
type:
|
413
|
+
type: narrowTypeForInstanceOrSubclass(evaluator, type, classTypeList, isInstanceCheck,
|
421
414
|
/* isTypeIsCheck */ false, isPositiveTest, testExpression),
|
422
415
|
isIncomplete,
|
423
416
|
};
|
@@ -436,26 +429,6 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
436
429
|
}
|
437
430
|
}
|
438
431
|
}
|
439
|
-
// Look for "callable(X)"
|
440
|
-
if (testExpression.d.args.length === 1) {
|
441
|
-
const arg0Expr = testExpression.d.args[0].d.valueExpr;
|
442
|
-
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
443
|
-
const callTypeResult = evaluator.getTypeOfExpression(testExpression.d.leftExpr, 2 /* EvalFlags.CallBaseDefaults */);
|
444
|
-
const callType = callTypeResult.type;
|
445
|
-
if ((0, types_1.isFunction)(callType) && types_1.FunctionType.isBuiltIn(callType, 'callable')) {
|
446
|
-
return (type) => {
|
447
|
-
let narrowedType = narrowTypeForCallable(evaluator, type, isPositiveTest, testExpression,
|
448
|
-
/* allowIntersections */ false);
|
449
|
-
if (isPositiveTest && (0, types_1.isNever)(narrowedType)) {
|
450
|
-
// Try again with intersections allowed.
|
451
|
-
narrowedType = narrowTypeForCallable(evaluator, type, isPositiveTest, testExpression,
|
452
|
-
/* allowIntersections */ true);
|
453
|
-
}
|
454
|
-
return { type: narrowedType, isIncomplete: !!callTypeResult.isIncomplete };
|
455
|
-
};
|
456
|
-
}
|
457
|
-
}
|
458
|
-
}
|
459
432
|
// Look for "bool(X)"
|
460
433
|
if (testExpression.d.args.length === 1 && !testExpression.d.args[0].d.name) {
|
461
434
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.d.args[0].d.valueExpr)) {
|
@@ -650,7 +623,7 @@ function narrowTypeForUserDefinedTypeGuard(evaluator, type, typeGuardType, isPos
|
|
650
623
|
(0, typeUtils_1.doForEachSubtype)(typeGuardType, (typeGuardSubtype) => {
|
651
624
|
filterTypes.push((0, typeUtils_1.convertToInstantiable)(typeGuardSubtype));
|
652
625
|
});
|
653
|
-
return
|
626
|
+
return narrowTypeForInstanceOrSubclass(evaluator, type, filterTypes,
|
654
627
|
/* isInstanceCheck */ true,
|
655
628
|
/* isTypeIsCheck */ true, isPositiveTest, errorNode);
|
656
629
|
}
|
@@ -752,10 +725,12 @@ function narrowTypeForIsNone(evaluator, type, isPositiveTest) {
|
|
752
725
|
return result;
|
753
726
|
}
|
754
727
|
// Handle type narrowing for expressions of the form "x is ..." and "x is not ...".
|
755
|
-
function narrowTypeForIsEllipsis(evaluator, type, isPositiveTest) {
|
728
|
+
function narrowTypeForIsEllipsis(evaluator, node, type, isPositiveTest) {
|
729
|
+
var _a, _b;
|
756
730
|
const expandedType = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
757
731
|
return (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(subtype);
|
758
732
|
});
|
733
|
+
const ellipsisType = (_b = (_a = evaluator.getBuiltInObject(node, 'EllipsisType')) !== null && _a !== void 0 ? _a : evaluator.getBuiltInObject(node, 'ellipsis')) !== null && _b !== void 0 ? _b : types_1.AnyType.create();
|
759
734
|
return evaluator.mapSubtypesExpandTypeVars(expandedType, /* options */ undefined, (subtype, unexpandedSubtype) => {
|
760
735
|
var _a;
|
761
736
|
if ((0, types_1.isAnyOrUnknown)(subtype)) {
|
@@ -771,9 +746,7 @@ function narrowTypeForIsEllipsis(evaluator, type, isPositiveTest) {
|
|
771
746
|
: subtype;
|
772
747
|
// See if it's a match for object.
|
773
748
|
if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'object')) {
|
774
|
-
return isPositiveTest
|
775
|
-
? (0, typeUtils_1.addConditionToType)(evaluator.getNoneType(), (_a = subtype.props) === null || _a === void 0 ? void 0 : _a.condition)
|
776
|
-
: adjustedSubtype;
|
749
|
+
return isPositiveTest ? (0, typeUtils_1.addConditionToType)(ellipsisType, (_a = subtype.props) === null || _a === void 0 ? void 0 : _a.condition) : adjustedSubtype;
|
777
750
|
}
|
778
751
|
const isEllipsis = (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, ['EllipsisType', 'ellipsis']);
|
779
752
|
// See if it's a match for "...".
|
@@ -849,68 +822,50 @@ function getIsInstanceClassTypes(evaluator, argType) {
|
|
849
822
|
});
|
850
823
|
return foundNonClassType ? undefined : classTypeList;
|
851
824
|
}
|
852
|
-
function
|
853
|
-
if ((0, types_1.isTypeVar)(filterType) || concreteFilterType.priv.literalValue !== undefined) {
|
854
|
-
return (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(filterType), varType);
|
855
|
-
}
|
856
|
-
// If the filter type represents all possible subclasses
|
857
|
-
// of a type, we can't make any statements about its superclass
|
858
|
-
// relationship with concreteVarType.
|
859
|
-
if (concreteFilterType.priv.includeSubclasses) {
|
860
|
-
return false;
|
861
|
-
}
|
862
|
-
if (types_1.ClassType.isDerivedFrom(concreteVarType, concreteFilterType)) {
|
863
|
-
return true;
|
864
|
-
}
|
865
|
-
if (isInstanceCheck) {
|
866
|
-
// We convert both types to instances in case they are protocol
|
867
|
-
// classes. A protocol class isn't allowed to be assigned to
|
868
|
-
// type[T], so this would otherwise fail.
|
869
|
-
if (types_1.ClassType.isProtocolClass(concreteFilterType) &&
|
870
|
-
evaluator.assignType(types_1.ClassType.cloneAsInstance(concreteFilterType), types_1.ClassType.cloneAsInstance(concreteVarType))) {
|
871
|
-
return true;
|
872
|
-
}
|
873
|
-
}
|
874
|
-
// Handle the special case where the variable type is a TypedDict and
|
875
|
-
// we're filtering against 'dict'. TypedDict isn't derived from dict,
|
876
|
-
// but at runtime, isinstance returns True.
|
877
|
-
if (types_1.ClassType.isBuiltIn(concreteFilterType, 'dict') && types_1.ClassType.isTypedDictClass(concreteVarType)) {
|
878
|
-
return true;
|
879
|
-
}
|
880
|
-
return false;
|
881
|
-
}
|
882
|
-
function isIsinstanceFilterSubclass(evaluator, varType, concreteFilterType, isInstanceCheck) {
|
883
|
-
if (types_1.ClassType.isDerivedFrom(concreteFilterType, varType)) {
|
884
|
-
return true;
|
885
|
-
}
|
886
|
-
if (isInstanceCheck) {
|
887
|
-
// We convert both types to instances in case they are protocol
|
888
|
-
// classes. A protocol class isn't allowed to be assigned to
|
889
|
-
// type[T], so this would otherwise fail.
|
890
|
-
if (types_1.ClassType.isProtocolClass(varType) &&
|
891
|
-
evaluator.assignType(types_1.ClassType.cloneAsInstance(varType), types_1.ClassType.cloneAsInstance(concreteFilterType))) {
|
892
|
-
return true;
|
893
|
-
}
|
894
|
-
}
|
895
|
-
return false;
|
896
|
-
}
|
897
|
-
function narrowTypeForIsInstance(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest, errorNode) {
|
825
|
+
function narrowTypeForInstanceOrSubclass(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest, errorNode) {
|
898
826
|
// First try with intersection types disallowed.
|
899
|
-
const narrowedType =
|
827
|
+
const narrowedType = narrowTypeForInstanceOrSubclassInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
|
900
828
|
/* allowIntersections */ false, errorNode);
|
901
829
|
if (!(0, types_1.isNever)(narrowedType)) {
|
902
830
|
return narrowedType;
|
903
831
|
}
|
904
832
|
// Try again with intersection types allowed.
|
905
|
-
return
|
833
|
+
return narrowTypeForInstanceOrSubclassInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
|
906
834
|
/* allowIntersections */ true, errorNode);
|
907
835
|
}
|
908
|
-
|
909
|
-
|
836
|
+
function narrowTypeForInstanceOrSubclassInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest, allowIntersections, errorNode) {
|
837
|
+
const result = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
838
|
+
let adjSubtype = subtype;
|
839
|
+
let resultRequiresAdj = false;
|
840
|
+
let adjFilterTypes = filterTypes;
|
841
|
+
if (!isInstanceCheck) {
|
842
|
+
const isTypeInstance = (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'type');
|
843
|
+
if ((0, typeUtils_1.isMetaclassInstance)(subtype) && !isTypeInstance) {
|
844
|
+
// Handle metaclass instances specially.
|
845
|
+
adjFilterTypes = filterTypes.map((filterType) => (0, typeUtils_1.convertToInstantiable)(filterType));
|
846
|
+
}
|
847
|
+
else {
|
848
|
+
const convSubtype = (0, typeUtils_1.convertToInstance)(subtype);
|
849
|
+
// Handle type[Any] specially for this case.
|
850
|
+
if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'type') && (0, types_1.isAnyOrUnknown)(convSubtype)) {
|
851
|
+
adjSubtype = (0, typeUtils_1.convertToInstance)(evaluator.getObjectType());
|
852
|
+
}
|
853
|
+
else {
|
854
|
+
adjSubtype = convSubtype;
|
855
|
+
}
|
856
|
+
resultRequiresAdj = true;
|
857
|
+
}
|
858
|
+
}
|
859
|
+
const narrowedResult = narrowTypeForInstance(evaluator, adjSubtype, adjFilterTypes, isTypeIsCheck, isPositiveTest, allowIntersections, errorNode);
|
860
|
+
return resultRequiresAdj ? (0, typeUtils_1.convertToInstantiable)(narrowedResult) : narrowedResult;
|
861
|
+
});
|
862
|
+
return result;
|
863
|
+
}
|
864
|
+
// Narrows a type based on a call to isinstance. For example, if the original
|
910
865
|
// type of expression "x" is "Mammal" and the test expression is
|
911
|
-
// "isinstance(x, Cow)", (assuming "Cow" is a subclass of "Mammal"),
|
912
|
-
//
|
913
|
-
function
|
866
|
+
// "isinstance(x, Cow)", (assuming "Cow" is a subclass of "Mammal"), we can
|
867
|
+
// narrow x to "Cow".
|
868
|
+
function narrowTypeForInstance(evaluator, type, filterTypes, isTypeIsCheck, isPositiveTest, allowIntersections, errorNode) {
|
914
869
|
let expandedTypes = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
915
870
|
return (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(subtype);
|
916
871
|
});
|
@@ -928,23 +883,67 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
|
|
928
883
|
// and returns the list of types the varType could be after
|
929
884
|
// applying the filter.
|
930
885
|
const filterClassType = (varType, concreteVarType, conditions, negativeFallbackType) => {
|
931
|
-
var _a, _b, _c;
|
886
|
+
var _a, _b, _c, _d, _e;
|
932
887
|
const filteredTypes = [];
|
933
888
|
let foundSuperclass = false;
|
934
889
|
let isClassRelationshipIndeterminate = false;
|
935
890
|
for (const filterType of filterTypes) {
|
936
891
|
const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
|
937
892
|
if ((0, types_1.isInstantiableClass)(concreteFilterType)) {
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
893
|
+
const filterMetaclass = concreteFilterType.shared.effectiveMetaclass;
|
894
|
+
if ((0, typeUtils_1.isInstantiableMetaclass)(concreteVarType) &&
|
895
|
+
types_1.TypeBase.getInstantiableDepth(concreteFilterType) > 0 &&
|
896
|
+
filterMetaclass &&
|
897
|
+
(0, types_1.isInstantiableClass)(filterMetaclass)) {
|
898
|
+
const metaclassType = (0, typeUtils_1.convertToInstance)(concreteVarType);
|
899
|
+
let isMetaclassOverlap = evaluator.assignType(convertVarTypeToFree(metaclassType), types_1.ClassType.cloneAsInstance(filterMetaclass));
|
900
|
+
// Handle the special case where the metaclass for the filter is type.
|
901
|
+
// This will normally be treated as type[Any], which is compatible with
|
902
|
+
// any metaclass, but we specifically want to treat type as the class
|
903
|
+
// type[object] in this case.
|
904
|
+
if (types_1.ClassType.isBuiltIn(filterMetaclass, 'type') && !filterMetaclass.priv.isTypeArgExplicit) {
|
905
|
+
if (!types_1.ClassType.isBuiltIn(metaclassType, 'type')) {
|
906
|
+
isMetaclassOverlap = false;
|
907
|
+
}
|
908
|
+
}
|
909
|
+
if (isMetaclassOverlap) {
|
910
|
+
if (isPositiveTest) {
|
911
|
+
filteredTypes.push(filterType);
|
912
|
+
foundSuperclass = true;
|
913
|
+
}
|
914
|
+
else if (!(0, types_1.isTypeSame)(metaclassType, filterMetaclass) ||
|
915
|
+
filterMetaclass.priv.includeSubclasses) {
|
916
|
+
filteredTypes.push(metaclassType);
|
917
|
+
isClassRelationshipIndeterminate = true;
|
918
|
+
}
|
919
|
+
continue;
|
920
|
+
}
|
943
921
|
}
|
944
|
-
|
945
|
-
|
946
|
-
|
922
|
+
let runtimeVarType = concreteVarType;
|
923
|
+
// Type variables are erased for runtime types, so switch from
|
924
|
+
// bound to free type variables. We'll retain the bound type
|
925
|
+
// variables for TypeIs checks.
|
926
|
+
if (!isTypeIsCheck) {
|
927
|
+
runtimeVarType = (0, typeUtils_1.makeTypeVarsFree)(runtimeVarType, ParseTreeUtils.getTypeVarScopesForNode(errorNode));
|
928
|
+
}
|
929
|
+
// If the value is a TypedDict, convert it into its runtime form,
|
930
|
+
// which is a dict[str, Any].
|
931
|
+
if ((0, types_1.isInstantiableClass)(runtimeVarType) && types_1.ClassType.isTypedDictClass(runtimeVarType)) {
|
932
|
+
const dictClass = evaluator.getDictClassType();
|
933
|
+
const strType = evaluator.getStrClassType();
|
934
|
+
if (dictClass && strType) {
|
935
|
+
runtimeVarType = types_1.ClassType.specialize(dictClass, [
|
936
|
+
types_1.ClassType.cloneAsInstance(strType),
|
937
|
+
types_1.UnknownType.create(),
|
938
|
+
]);
|
939
|
+
}
|
947
940
|
}
|
941
|
+
const filterIsSuperclass = evaluator.assignType(filterType, runtimeVarType,
|
942
|
+
/* diag */ undefined,
|
943
|
+
/* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */ | 65536 /* AssignTypeFlags.AllowProtocolClassSource */);
|
944
|
+
const filterIsSubclass = evaluator.assignType(runtimeVarType, filterType,
|
945
|
+
/* diag */ undefined,
|
946
|
+
/* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */ | 65536 /* AssignTypeFlags.AllowProtocolClassSource */);
|
948
947
|
if (filterIsSuperclass) {
|
949
948
|
foundSuperclass = true;
|
950
949
|
}
|
@@ -953,10 +952,16 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
|
|
953
952
|
// class whose type is unknown (e.g. an import failed). We'll
|
954
953
|
// note this case specially so we don't do any narrowing, which
|
955
954
|
// will generate false positives.
|
956
|
-
if (filterIsSubclass &&
|
957
|
-
|
958
|
-
|
959
|
-
|
955
|
+
if (filterIsSubclass && filterIsSuperclass) {
|
956
|
+
if (!isTypeIsCheck && concreteFilterType.priv.includeSubclasses) {
|
957
|
+
// If the filter type includes subclasses, we can't eliminate
|
958
|
+
// this type in the negative direction. We'll relax this for
|
959
|
+
// TypeIs checks.
|
960
|
+
isClassRelationshipIndeterminate = true;
|
961
|
+
}
|
962
|
+
if (!types_1.ClassType.isSameGenericClass(runtimeVarType, concreteFilterType)) {
|
963
|
+
isClassRelationshipIndeterminate = true;
|
964
|
+
}
|
960
965
|
}
|
961
966
|
// If both the variable type and the filter type ar generics, we can't
|
962
967
|
// determine the relationship between the two.
|
@@ -976,46 +981,44 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
|
|
976
981
|
}
|
977
982
|
}
|
978
983
|
else if (filterIsSubclass) {
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
tupleClassType: evaluator.getTupleClassType(),
|
1002
|
-
},
|
1003
|
-
});
|
1004
|
-
}
|
984
|
+
// If the variable type is a superclass of the isinstance
|
985
|
+
// filter, we can narrow the type to the subclass.
|
986
|
+
let specializedFilterType = filterType;
|
987
|
+
// Try to retain the type arguments for the filter type. This is
|
988
|
+
// important because a specialized version of the filter cannot
|
989
|
+
// be passed to isinstance or issubclass.
|
990
|
+
if ((0, types_1.isClass)(filterType)) {
|
991
|
+
if (types_1.ClassType.isSpecialBuiltIn(filterType) || filterType.shared.typeParams.length > 0) {
|
992
|
+
if (!filterType.priv.isTypeArgExplicit &&
|
993
|
+
!types_1.ClassType.isSameGenericClass(concreteVarType, filterType)) {
|
994
|
+
const constraints = new constraintTracker_1.ConstraintTracker();
|
995
|
+
const unspecializedFilterType = types_1.ClassType.specialize(filterType,
|
996
|
+
/* typeArg */ undefined);
|
997
|
+
if ((0, constraintSolver_1.addConstraintsForExpectedType)(evaluator, (0, typeUtils_1.convertToInstance)(unspecializedFilterType), (0, typeUtils_1.convertToInstance)(concreteVarType), constraints,
|
998
|
+
/* liveTypeVarScopes */ undefined, errorNode.start)) {
|
999
|
+
specializedFilterType = evaluator.solveAndApplyConstraints(unspecializedFilterType, constraints, {
|
1000
|
+
replaceUnsolved: {
|
1001
|
+
scopeIds: (0, typeUtils_1.getTypeVarScopeIds)(filterType),
|
1002
|
+
useUnknown: true,
|
1003
|
+
tupleClassType: evaluator.getTupleClassType(),
|
1004
|
+
},
|
1005
|
+
});
|
1005
1006
|
}
|
1006
1007
|
}
|
1007
1008
|
}
|
1008
|
-
filteredTypes.push((0, typeUtils_1.addConditionToType)(specializedFilterType, conditions));
|
1009
1009
|
}
|
1010
|
+
filteredTypes.push((0, typeUtils_1.addConditionToType)(specializedFilterType, conditions));
|
1010
1011
|
}
|
1011
|
-
else if (types_1.ClassType.isSameGenericClass(concreteVarType, concreteFilterType)) {
|
1012
|
-
|
1013
|
-
|
1014
|
-
((
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1012
|
+
else if (types_1.ClassType.isSameGenericClass(types_1.ClassType.cloneAsInstance(concreteVarType), types_1.ClassType.cloneAsInstance(concreteFilterType))) {
|
1013
|
+
if (!isTypeIsCheck) {
|
1014
|
+
// Don't attempt to narrow in this case.
|
1015
|
+
if (((_a = concreteVarType.priv) === null || _a === void 0 ? void 0 : _a.literalValue) === undefined &&
|
1016
|
+
((_b = concreteFilterType.priv) === null || _b === void 0 ? void 0 : _b.literalValue) === undefined) {
|
1017
|
+
const intersection = intersectSameClassType(evaluator, concreteVarType, concreteFilterType);
|
1018
|
+
filteredTypes.push(intersection !== null && intersection !== void 0 ? intersection : varType);
|
1019
|
+
// Don't attempt to narrow in the negative direction.
|
1020
|
+
isClassRelationshipIndeterminate = true;
|
1021
|
+
}
|
1019
1022
|
}
|
1020
1023
|
}
|
1021
1024
|
else if (allowIntersections &&
|
@@ -1032,17 +1035,22 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
|
|
1032
1035
|
}
|
1033
1036
|
let newClassObjType = types_1.ClassType.cloneAsInstance(newClassType);
|
1034
1037
|
newClassObjType = (0, typeUtils_1.addConditionToType)(newClassObjType, (_c = concreteVarType.props) === null || _c === void 0 ? void 0 : _c.condition);
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1038
|
+
filteredTypes.push(newClassObjType);
|
1039
|
+
}
|
1040
|
+
}
|
1041
|
+
else {
|
1042
|
+
if ((0, types_1.isAnyOrUnknown)(varType)) {
|
1043
|
+
filteredTypes.push((0, typeUtils_1.addConditionToType)(varType, conditions));
|
1044
|
+
}
|
1045
|
+
else if ((0, typeUtils_1.derivesFromAnyOrUnknown)(varType) && !(0, types_1.isTypeSame)(concreteVarType, concreteFilterType)) {
|
1046
|
+
filteredTypes.push((0, typeUtils_1.addConditionToType)(varType, conditions));
|
1039
1047
|
}
|
1040
1048
|
}
|
1041
1049
|
}
|
1042
1050
|
else if ((0, types_1.isTypeVar)(filterType) && types_1.TypeBase.isInstantiable(filterType)) {
|
1043
1051
|
// Handle the case where the filter type is Type[T] and the unexpanded
|
1044
1052
|
// subtype is some instance type, possibly T.
|
1045
|
-
if (
|
1053
|
+
if (types_1.TypeBase.isInstance(varType)) {
|
1046
1054
|
if ((0, types_1.isTypeVar)(varType) && (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(filterType), varType)) {
|
1047
1055
|
// If the unexpanded subtype is T, we can definitively filter
|
1048
1056
|
// in both the positive and negative cases.
|
@@ -1065,51 +1073,53 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
|
|
1065
1073
|
}
|
1066
1074
|
}
|
1067
1075
|
}
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1076
|
+
}
|
1077
|
+
else if ((0, types_1.isFunction)(filterType)) {
|
1078
|
+
// Handle an isinstance check against Callable.
|
1079
|
+
let isCallable = false;
|
1080
|
+
if ((0, types_1.isClass)(concreteVarType)) {
|
1081
|
+
if (types_1.TypeBase.isInstantiable(varType)) {
|
1082
|
+
isCallable = true;
|
1073
1083
|
}
|
1074
1084
|
else {
|
1075
|
-
|
1076
|
-
filteredTypes.push(filterType);
|
1077
|
-
}
|
1078
|
-
else {
|
1079
|
-
filteredTypes.push(varType);
|
1080
|
-
isClassRelationshipIndeterminate = true;
|
1081
|
-
}
|
1085
|
+
isCallable = !!(0, typeUtils_1.lookUpClassMember)(concreteVarType, '__call__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
|
1082
1086
|
}
|
1083
1087
|
}
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
if (isInstanceCheck) {
|
1088
|
-
let isCallable = false;
|
1089
|
-
if ((0, types_1.isClass)(concreteVarType)) {
|
1090
|
-
if (types_1.TypeBase.isInstantiable(varType)) {
|
1091
|
-
isCallable = true;
|
1092
|
-
}
|
1093
|
-
else {
|
1094
|
-
isCallable = !!(0, typeUtils_1.lookUpClassMember)(concreteVarType, '__call__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
|
1095
|
-
}
|
1088
|
+
if (isCallable) {
|
1089
|
+
if (isPositiveTest) {
|
1090
|
+
filteredTypes.push((0, typeUtils_1.convertToInstantiable)(varType));
|
1096
1091
|
}
|
1097
|
-
|
1098
|
-
|
1099
|
-
filteredTypes.push(varType);
|
1100
|
-
}
|
1101
|
-
else {
|
1102
|
-
foundSuperclass = true;
|
1103
|
-
}
|
1092
|
+
else {
|
1093
|
+
foundSuperclass = true;
|
1104
1094
|
}
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1095
|
+
}
|
1096
|
+
else if (evaluator.assignType(convertVarTypeToFree(concreteVarType), filterType,
|
1097
|
+
/* diag */ undefined,
|
1098
|
+
/* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */)) {
|
1099
|
+
if (isPositiveTest) {
|
1100
|
+
filteredTypes.push((0, typeUtils_1.addConditionToType)(filterType, (_d = concreteVarType.props) === null || _d === void 0 ? void 0 : _d.condition));
|
1111
1101
|
}
|
1112
1102
|
}
|
1103
|
+
else if (allowIntersections && isPositiveTest) {
|
1104
|
+
// The type appears to not be callable. It's possible that the
|
1105
|
+
// two type is a subclass that is callable. We'll synthesize a
|
1106
|
+
// new intersection type.
|
1107
|
+
const className = `<callable subtype of ${concreteVarType.shared.name}>`;
|
1108
|
+
const fileInfo = (0, analyzerNodeInfo_1.getFileInfo)(errorNode);
|
1109
|
+
let newClassType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.fileUri, 0 /* ClassTypeFlags.None */, ParseTreeUtils.getTypeSourceId(errorNode),
|
1110
|
+
/* declaredMetaclass */ undefined, concreteVarType.shared.effectiveMetaclass, concreteVarType.shared.docString);
|
1111
|
+
newClassType.shared.baseClasses = [concreteVarType];
|
1112
|
+
(0, typeUtils_1.computeMroLinearization)(newClassType);
|
1113
|
+
newClassType = (0, typeUtils_1.addConditionToType)(newClassType, (_e = concreteVarType.props) === null || _e === void 0 ? void 0 : _e.condition);
|
1114
|
+
// Add a __call__ method to the new class.
|
1115
|
+
const callMethod = types_1.FunctionType.createSynthesizedInstance('__call__');
|
1116
|
+
const selfParam = types_1.FunctionParam.create(0 /* ParamCategory.Simple */, types_1.ClassType.cloneAsInstance(newClassType), types_1.FunctionParamFlags.TypeDeclared, 'self');
|
1117
|
+
types_1.FunctionType.addParam(callMethod, selfParam);
|
1118
|
+
types_1.FunctionType.addDefaultParams(callMethod);
|
1119
|
+
callMethod.shared.declaredReturnType = types_1.UnknownType.create();
|
1120
|
+
types_1.ClassType.getSymbolTable(newClassType).set('__call__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, callMethod));
|
1121
|
+
filteredTypes.push(types_1.ClassType.cloneAsInstance(newClassType));
|
1122
|
+
}
|
1113
1123
|
}
|
1114
1124
|
}
|
1115
1125
|
// In the negative case, if one or more of the filters
|
@@ -1119,101 +1129,58 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
|
|
1119
1129
|
// match, then the original variable type survives the filter.
|
1120
1130
|
if (!isPositiveTest) {
|
1121
1131
|
if (!foundSuperclass || isClassRelationshipIndeterminate) {
|
1122
|
-
filteredTypes.push(
|
1132
|
+
filteredTypes.push((0, typeUtils_1.convertToInstantiable)(negativeFallbackType));
|
1123
1133
|
}
|
1124
1134
|
}
|
1125
|
-
if (!isInstanceCheck) {
|
1126
|
-
// We perform a double conversion from instance to instantiable
|
1127
|
-
// here to make sure that the includeSubclasses flag is cleared
|
1128
|
-
// if it's a class.
|
1129
|
-
return filteredTypes.map((t) => ((0, types_1.isInstantiableClass)(t) ? (0, typeUtils_1.convertToInstantiable)((0, typeUtils_1.convertToInstance)(t)) : t));
|
1130
|
-
}
|
1131
1135
|
return filteredTypes.map((t) => (0, typeUtils_1.convertToInstance)(t));
|
1132
1136
|
};
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
const filterMetaclassType = (metaclassType, negativeFallbackType) => {
|
1137
|
-
const filteredTypes = [];
|
1138
|
-
let foundPositiveMatch = false;
|
1139
|
-
let isMatchIndeterminate = false;
|
1140
|
-
for (const filterType of filterTypes) {
|
1141
|
-
const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
|
1142
|
-
if ((0, types_1.isInstantiableClass)(concreteFilterType)) {
|
1143
|
-
const filterMetaclass = concreteFilterType.shared.effectiveMetaclass;
|
1144
|
-
if (filterMetaclass && (0, types_1.isInstantiableClass)(filterMetaclass)) {
|
1145
|
-
let isMetaclassOverlap = evaluator.assignType(convertVarTypeToFree(metaclassType), types_1.ClassType.cloneAsInstance(filterMetaclass));
|
1146
|
-
// Handle the special case where the metaclass for the filter is type.
|
1147
|
-
// This will normally be treated as type[Any], which is compatible with
|
1148
|
-
// any metaclass, but we specifically want to treat type as the class
|
1149
|
-
// type[object] in this case.
|
1150
|
-
if (types_1.ClassType.isBuiltIn(filterMetaclass, 'type') && !filterMetaclass.priv.isTypeArgExplicit) {
|
1151
|
-
if (!types_1.ClassType.isBuiltIn(metaclassType, 'type')) {
|
1152
|
-
isMetaclassOverlap = false;
|
1153
|
-
}
|
1154
|
-
}
|
1155
|
-
if (isMetaclassOverlap) {
|
1156
|
-
if (isPositiveTest) {
|
1157
|
-
filteredTypes.push(filterType);
|
1158
|
-
foundPositiveMatch = true;
|
1159
|
-
}
|
1160
|
-
else if (!(0, types_1.isTypeSame)(metaclassType, filterMetaclass) ||
|
1161
|
-
filterMetaclass.priv.includeSubclasses) {
|
1162
|
-
filteredTypes.push(metaclassType);
|
1163
|
-
isMatchIndeterminate = true;
|
1164
|
-
}
|
1165
|
-
}
|
1166
|
-
}
|
1167
|
-
else {
|
1168
|
-
filteredTypes.push(metaclassType);
|
1169
|
-
isMatchIndeterminate = true;
|
1170
|
-
}
|
1171
|
-
}
|
1172
|
-
else {
|
1173
|
-
filteredTypes.push(metaclassType);
|
1174
|
-
isMatchIndeterminate = true;
|
1175
|
-
}
|
1176
|
-
}
|
1177
|
-
// In the negative case, if one or more of the filters
|
1178
|
-
// always match the type in the positive case, then there's nothing
|
1179
|
-
// left after the filter is applied.
|
1180
|
-
if (!isPositiveTest) {
|
1181
|
-
if (!foundPositiveMatch || isMatchIndeterminate) {
|
1182
|
-
filteredTypes.push(negativeFallbackType);
|
1183
|
-
}
|
1184
|
-
}
|
1185
|
-
// We perform a double conversion from instance to instantiable
|
1186
|
-
// here to make sure that the includeSubclasses flag is cleared
|
1187
|
-
// if it's a class.
|
1188
|
-
return filteredTypes.map((t) => ((0, types_1.isInstantiableClass)(t) ? (0, typeUtils_1.convertToInstantiable)((0, typeUtils_1.convertToInstance)(t)) : t));
|
1137
|
+
const isFilterTypeCallbackProtocol = (filterType) => {
|
1138
|
+
return ((0, types_1.isInstantiableClass)(filterType) &&
|
1139
|
+
evaluator.getCallbackProtocolType((0, typeUtils_1.convertToInstance)(filterType)) !== undefined);
|
1189
1140
|
};
|
1190
1141
|
const filterFunctionType = (varType, unexpandedType) => {
|
1191
1142
|
const filteredTypes = [];
|
1192
1143
|
if (isPositiveTest) {
|
1193
1144
|
for (const filterType of filterTypes) {
|
1194
1145
|
const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
|
1195
|
-
if (
|
1146
|
+
if (!isTypeIsCheck && isFilterTypeCallbackProtocol(concreteFilterType)) {
|
1147
|
+
filteredTypes.push((0, typeUtils_1.convertToInstance)(varType));
|
1148
|
+
}
|
1149
|
+
else if (evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType))) {
|
1196
1150
|
// If the filter type is a Callable, use the original type. If the
|
1197
1151
|
// filter type is a callback protocol, use the filter type.
|
1198
1152
|
if ((0, types_1.isFunction)(filterType)) {
|
1199
|
-
filteredTypes.push(unexpandedType);
|
1153
|
+
filteredTypes.push((0, typeUtils_1.convertToInstance)(unexpandedType));
|
1200
1154
|
}
|
1201
1155
|
else {
|
1202
1156
|
filteredTypes.push((0, typeUtils_1.convertToInstance)(filterType));
|
1203
1157
|
}
|
1204
1158
|
}
|
1159
|
+
else if (evaluator.assignType((0, typeUtils_1.convertToInstance)(convertVarTypeToFree(concreteFilterType)), varType)) {
|
1160
|
+
filteredTypes.push((0, typeUtils_1.convertToInstance)(varType));
|
1161
|
+
}
|
1205
1162
|
}
|
1206
1163
|
}
|
1207
|
-
else
|
1208
|
-
// If
|
1209
|
-
//
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1164
|
+
else {
|
1165
|
+
// If one or more filters does not always filter the type,
|
1166
|
+
// we can't eliminate the type in the negative case.
|
1167
|
+
if (filterTypes.every((filterType) => {
|
1168
|
+
const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
|
1169
|
+
// If the filter type is a callback protocol, the runtime
|
1170
|
+
// isinstance check will filter all objects that have a __call__
|
1171
|
+
// method regardless of their signature types.
|
1172
|
+
if (!isTypeIsCheck && isFilterTypeCallbackProtocol(concreteFilterType)) {
|
1173
|
+
return false;
|
1174
|
+
}
|
1175
|
+
if ((0, types_1.isFunction)(concreteFilterType) && types_1.FunctionType.isGradualCallableForm(concreteFilterType)) {
|
1176
|
+
return false;
|
1177
|
+
}
|
1178
|
+
const isSubtype = evaluator.assignType((0, typeUtils_1.convertToInstance)(convertVarTypeToFree(concreteFilterType)), varType);
|
1179
|
+
const isSupertype = evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType));
|
1180
|
+
return !isSubtype || isSupertype;
|
1181
|
+
})) {
|
1182
|
+
filteredTypes.push((0, typeUtils_1.convertToInstance)(varType));
|
1213
1183
|
}
|
1214
|
-
return evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType));
|
1215
|
-
})) {
|
1216
|
-
filteredTypes.push(unexpandedType);
|
1217
1184
|
}
|
1218
1185
|
return filteredTypes;
|
1219
1186
|
};
|
@@ -1236,77 +1203,36 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
|
|
1236
1203
|
// on a constrained TypeVar that they want to filter based on its constrained
|
1237
1204
|
// parts.
|
1238
1205
|
const negativeFallback = (0, typeUtils_1.getTypeCondition)(subtype) ? subtype : unexpandedSubtype;
|
1239
|
-
const isSubtypeMetaclass = (0, typeUtils_1.isMetaclassInstance)(subtype);
|
1240
1206
|
if (isPositiveTest && (0, types_1.isAnyOrUnknown)(subtype)) {
|
1241
1207
|
// If this is a positive test and the effective type is Any or
|
1242
1208
|
// Unknown, we can assume that the type matches one of the
|
1243
1209
|
// specified types.
|
1244
|
-
|
1245
|
-
anyOrUnknownSubstitutions.push((0, types_1.combineTypes)(filterTypes.map((classType) => (0, typeUtils_1.convertToInstance)(classType))));
|
1246
|
-
}
|
1247
|
-
else {
|
1248
|
-
// We perform a double conversion from instance to instantiable
|
1249
|
-
// here to make sure that the includeSubclasses flag is cleared
|
1250
|
-
// if it's a class.
|
1251
|
-
anyOrUnknownSubstitutions.push((0, types_1.combineTypes)(filterTypes.map((classType) => (0, typeUtils_1.convertToInstantiable)((0, typeUtils_1.convertToInstance)(classType)))));
|
1252
|
-
}
|
1210
|
+
anyOrUnknownSubstitutions.push((0, types_1.combineTypes)(filterTypes.map((classType) => (0, typeUtils_1.convertToInstance)(classType))));
|
1253
1211
|
anyOrUnknown.push(subtype);
|
1254
1212
|
return undefined;
|
1255
1213
|
}
|
1256
|
-
if (
|
1257
|
-
|
1258
|
-
return classListContainsNoneType() === isPositiveTest ? subtype : undefined;
|
1259
|
-
}
|
1260
|
-
if ((0, types_1.isModule)(subtype) || ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'ModuleType'))) {
|
1261
|
-
// Handle type narrowing for runtime-checkable protocols
|
1262
|
-
// when applied to modules.
|
1263
|
-
if (isPositiveTest) {
|
1264
|
-
const filteredTypes = filterTypes.filter((classType) => {
|
1265
|
-
const concreteClassType = evaluator.makeTopLevelTypeVarsConcrete(classType);
|
1266
|
-
return ((0, types_1.isInstantiableClass)(concreteClassType) && types_1.ClassType.isProtocolClass(concreteClassType));
|
1267
|
-
});
|
1268
|
-
if (filteredTypes.length > 0) {
|
1269
|
-
return (0, typeUtils_1.convertToInstance)((0, types_1.combineTypes)(filteredTypes));
|
1270
|
-
}
|
1271
|
-
}
|
1272
|
-
}
|
1273
|
-
if ((0, types_1.isClassInstance)(subtype)) {
|
1274
|
-
return (0, types_1.combineTypes)(filterClassType(unexpandedSubtype, types_1.ClassType.cloneAsInstantiable(subtype), (0, typeUtils_1.getTypeCondition)(subtype), negativeFallback));
|
1275
|
-
}
|
1276
|
-
if (((0, types_1.isFunction)(subtype) || (0, types_1.isOverloaded)(subtype)) && isInstanceCheck) {
|
1277
|
-
return (0, types_1.combineTypes)(filterFunctionType(subtype, (0, typeUtils_1.convertToInstance)(unexpandedSubtype)));
|
1278
|
-
}
|
1279
|
-
if ((0, types_1.isInstantiableClass)(subtype) || isSubtypeMetaclass) {
|
1280
|
-
// Handle the special case of isinstance(x, metaclass).
|
1281
|
-
const includesMetaclassType = filterTypes.some((classType) => (0, typeUtils_1.isInstantiableMetaclass)(classType));
|
1282
|
-
const includesObject = filterTypes.some((classType) => (0, types_1.isInstantiableClass)(classType) && types_1.ClassType.isBuiltIn(classType, 'object'));
|
1283
|
-
if (isPositiveTest) {
|
1284
|
-
return includesMetaclassType || includesObject ? negativeFallback : undefined;
|
1285
|
-
}
|
1286
|
-
else {
|
1287
|
-
return includesMetaclassType ? undefined : negativeFallback;
|
1288
|
-
}
|
1289
|
-
}
|
1214
|
+
if ((0, typeUtils_1.isNoneInstance)(subtype)) {
|
1215
|
+
return classListContainsNoneType() === isPositiveTest ? subtype : undefined;
|
1290
1216
|
}
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
return (0, types_1.
|
1298
|
-
}
|
1299
|
-
|
1300
|
-
return (0,
|
1301
|
-
}
|
1302
|
-
}
|
1303
|
-
if (isSubtypeMetaclass) {
|
1304
|
-
const objectType = evaluator.getBuiltInObject(errorNode, 'object');
|
1305
|
-
if (objectType && (0, types_1.isClassInstance)(objectType)) {
|
1306
|
-
return (0, types_1.combineTypes)(filterClassType((0, typeUtils_1.convertToInstantiable)(unexpandedSubtype), types_1.ClassType.cloneAsInstantiable(objectType), (0, typeUtils_1.getTypeCondition)(subtype), negativeFallback));
|
1217
|
+
if ((0, types_1.isModule)(subtype) || ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'ModuleType'))) {
|
1218
|
+
// Handle type narrowing for runtime-checkable protocols
|
1219
|
+
// when applied to modules.
|
1220
|
+
if (isPositiveTest) {
|
1221
|
+
const filteredTypes = filterTypes.filter((classType) => {
|
1222
|
+
const concreteClassType = evaluator.makeTopLevelTypeVarsConcrete(classType);
|
1223
|
+
return (0, types_1.isInstantiableClass)(concreteClassType) && types_1.ClassType.isProtocolClass(concreteClassType);
|
1224
|
+
});
|
1225
|
+
if (filteredTypes.length > 0) {
|
1226
|
+
return (0, typeUtils_1.convertToInstance)((0, types_1.combineTypes)(filteredTypes));
|
1307
1227
|
}
|
1308
1228
|
}
|
1309
1229
|
}
|
1230
|
+
if ((0, types_1.isClass)(subtype)) {
|
1231
|
+
return (0, types_1.combineTypes)(filterClassType(unexpandedSubtype, types_1.ClassType.cloneAsInstantiable(subtype), (0, typeUtils_1.getTypeCondition)(subtype), negativeFallback));
|
1232
|
+
}
|
1233
|
+
if ((0, types_1.isFunction)(subtype) || (0, types_1.isOverloaded)(subtype)) {
|
1234
|
+
return (0, types_1.combineTypes)(filterFunctionType(subtype, unexpandedSubtype));
|
1235
|
+
}
|
1310
1236
|
return isPositiveTest ? undefined : negativeFallback;
|
1311
1237
|
});
|
1312
1238
|
// If the result is Any/Unknown and contains no other subtypes and
|
@@ -1494,62 +1420,21 @@ function getElementTypeForContainerNarrowing(containerType) {
|
|
1494
1420
|
return elementType;
|
1495
1421
|
}
|
1496
1422
|
function narrowTypeForContainerElementType(evaluator, referenceType, elementType) {
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
// narrow the reference type to "float" because it is a supertype of "int".
|
1503
|
-
const narrowedSupertypes = evaluator.mapSubtypesExpandTypeVars(referenceType,
|
1504
|
-
/* options */ undefined, (referenceSubtype) => {
|
1505
|
-
if ((0, types_1.isAnyOrUnknown)(referenceSubtype)) {
|
1506
|
-
canNarrow = false;
|
1507
|
-
return referenceSubtype;
|
1508
|
-
}
|
1509
|
-
// Handle "type" specially.
|
1510
|
-
if ((0, types_1.isClassInstance)(referenceSubtype) && types_1.ClassType.isBuiltIn(referenceSubtype, 'type')) {
|
1511
|
-
canNarrow = false;
|
1512
|
-
return referenceSubtype;
|
1513
|
-
}
|
1514
|
-
if (evaluator.assignType(elementType, referenceSubtype)) {
|
1515
|
-
return referenceSubtype;
|
1516
|
-
}
|
1517
|
-
if (evaluator.assignType(elementTypeWithoutLiteral, referenceSubtype)) {
|
1518
|
-
return (0, typeUtils_1.mapSubtypes)(elementType, (elementSubtype) => {
|
1519
|
-
if ((0, types_1.isClassInstance)(elementSubtype) &&
|
1520
|
-
(0, types_1.isSameWithoutLiteralValue)(referenceSubtype, elementSubtype)) {
|
1521
|
-
return elementSubtype;
|
1522
|
-
}
|
1523
|
-
return undefined;
|
1524
|
-
});
|
1525
|
-
}
|
1526
|
-
return undefined;
|
1527
|
-
});
|
1528
|
-
// Look for cases where one or more of the reference subtypes are
|
1529
|
-
// subtypes of the element types. For example, if the element type
|
1530
|
-
// is "int | str" and the reference type is "object", we can
|
1531
|
-
// narrow the reference type to "int | str" because they are both
|
1532
|
-
// subtypes of "object".
|
1533
|
-
const narrowedSubtypes = evaluator.mapSubtypesExpandTypeVars(elementType,
|
1534
|
-
/* options */ undefined, (elementSubtype) => {
|
1535
|
-
if ((0, types_1.isAnyOrUnknown)(elementSubtype)) {
|
1536
|
-
canNarrow = false;
|
1537
|
-
return referenceType;
|
1538
|
-
}
|
1539
|
-
// Handle the special case where the reference type is a dict or Mapping and
|
1540
|
-
// the element type is a TypedDict. In this case, we can't say whether there
|
1541
|
-
// is a type overlap, so don't apply narrowing.
|
1542
|
-
if ((0, types_1.isClassInstance)(referenceType) && types_1.ClassType.isBuiltIn(referenceType, ['dict', 'Mapping'])) {
|
1543
|
-
if ((0, types_1.isClassInstance)(elementSubtype) && types_1.ClassType.isTypedDictClass(elementSubtype)) {
|
1544
|
-
return elementSubtype;
|
1423
|
+
return evaluator.mapSubtypesExpandTypeVars(referenceType, /* options */ undefined, (referenceSubtype) => {
|
1424
|
+
return (0, typeUtils_1.mapSubtypes)(elementType, (elementSubtype) => {
|
1425
|
+
var _a, _b;
|
1426
|
+
if ((0, types_1.isAnyOrUnknown)(referenceSubtype)) {
|
1427
|
+
return referenceSubtype;
|
1545
1428
|
}
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1429
|
+
if (evaluator.assignType(referenceSubtype, elementSubtype)) {
|
1430
|
+
return (0, typeUtils_1.stripTypeForm)((0, typeUtils_1.addConditionToType)(elementSubtype, (_a = referenceSubtype.props) === null || _a === void 0 ? void 0 : _a.condition));
|
1431
|
+
}
|
1432
|
+
if (evaluator.assignType(elementSubtype, referenceSubtype)) {
|
1433
|
+
return (0, typeUtils_1.stripTypeForm)((0, typeUtils_1.addConditionToType)(referenceSubtype, (_b = elementSubtype.props) === null || _b === void 0 ? void 0 : _b.condition));
|
1434
|
+
}
|
1435
|
+
return undefined;
|
1436
|
+
});
|
1551
1437
|
});
|
1552
|
-
return canNarrow ? (0, types_1.combineTypes)([narrowedSupertypes, narrowedSubtypes]) : referenceType;
|
1553
1438
|
}
|
1554
1439
|
// Attempts to narrow a type based on whether it is a TypedDict with
|
1555
1440
|
// a literal key value.
|
@@ -1786,8 +1671,7 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
|
|
1786
1671
|
if (types_1.TypeBase.isInstance(concreteSubtype)) {
|
1787
1672
|
return types_1.ClassType.isBuiltIn(concreteSubtype, 'object') ? classType : undefined;
|
1788
1673
|
}
|
1789
|
-
const isSuperType =
|
1790
|
-
/* isInstanceCheck */ false);
|
1674
|
+
const isSuperType = isFilterSuperclass(subtype, concreteSubtype, classType, classType);
|
1791
1675
|
if (!classType.priv.includeSubclasses) {
|
1792
1676
|
// Handle the case where the LHS and RHS operands are specific
|
1793
1677
|
// classes, as opposed to types that represent classes and their
|
@@ -1795,11 +1679,10 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
|
|
1795
1679
|
if (!concreteSubtype.priv.includeSubclasses) {
|
1796
1680
|
return types_1.ClassType.isSameGenericClass(concreteSubtype, classType) ? classType : undefined;
|
1797
1681
|
}
|
1798
|
-
const isSubType = isIsinstanceFilterSubclass(evaluator, concreteSubtype, classType,
|
1799
|
-
/* isInstanceCheck */ false);
|
1800
1682
|
if (isSuperType) {
|
1801
1683
|
return classType;
|
1802
1684
|
}
|
1685
|
+
const isSubType = types_1.ClassType.isDerivedFrom(classType, concreteSubtype);
|
1803
1686
|
if (isSubType) {
|
1804
1687
|
return (0, typeUtils_1.addConditionToType)(classType, (0, typeUtils_1.getTypeCondition)(concreteSubtype));
|
1805
1688
|
}
|
@@ -1820,6 +1703,27 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
|
|
1820
1703
|
return subtype;
|
1821
1704
|
});
|
1822
1705
|
}
|
1706
|
+
function isFilterSuperclass(varType, concreteVarType, filterType, concreteFilterType) {
|
1707
|
+
if ((0, types_1.isTypeVar)(filterType) || concreteFilterType.priv.literalValue !== undefined) {
|
1708
|
+
return (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(filterType), varType);
|
1709
|
+
}
|
1710
|
+
// If the filter type represents all possible subclasses
|
1711
|
+
// of a type, we can't make any statements about its superclass
|
1712
|
+
// relationship with concreteVarType.
|
1713
|
+
if (concreteFilterType.priv.includeSubclasses) {
|
1714
|
+
return false;
|
1715
|
+
}
|
1716
|
+
if (types_1.ClassType.isDerivedFrom(concreteVarType, concreteFilterType)) {
|
1717
|
+
return true;
|
1718
|
+
}
|
1719
|
+
// Handle the special case where the variable type is a TypedDict and
|
1720
|
+
// we're filtering against 'dict'. TypedDict isn't derived from dict,
|
1721
|
+
// but at runtime, isinstance returns True.
|
1722
|
+
if (types_1.ClassType.isBuiltIn(concreteFilterType, 'dict') && types_1.ClassType.isTypedDictClass(concreteVarType)) {
|
1723
|
+
return true;
|
1724
|
+
}
|
1725
|
+
return false;
|
1726
|
+
}
|
1823
1727
|
// Attempts to narrow a type (make it more constrained) based on a comparison
|
1824
1728
|
// (equal or not equal) to a literal value. It also handles "is" or "is not"
|
1825
1729
|
// operators if isIsOperator is true.
|
@@ -1894,86 +1798,4 @@ function enumerateLiteralsForType(evaluator, type) {
|
|
1894
1798
|
}
|
1895
1799
|
return undefined;
|
1896
1800
|
}
|
1897
|
-
// Attempts to narrow a type (make it more constrained) based on a
|
1898
|
-
// call to "callable". For example, if the original type of expression "x" is
|
1899
|
-
// Union[Callable[..., Any], Type[int], int], it would remove the "int" because
|
1900
|
-
// it's not callable.
|
1901
|
-
function narrowTypeForCallable(evaluator, type, isPositiveTest, errorNode, allowIntersections) {
|
1902
|
-
return evaluator.mapSubtypesExpandTypeVars(type, /* options */ undefined, (subtype) => {
|
1903
|
-
var _a;
|
1904
|
-
switch (subtype.category) {
|
1905
|
-
case 4 /* TypeCategory.Function */:
|
1906
|
-
case 5 /* TypeCategory.Overloaded */: {
|
1907
|
-
return isPositiveTest ? subtype : undefined;
|
1908
|
-
}
|
1909
|
-
case 7 /* TypeCategory.Module */: {
|
1910
|
-
return isPositiveTest ? undefined : subtype;
|
1911
|
-
}
|
1912
|
-
case 6 /* TypeCategory.Class */: {
|
1913
|
-
if ((0, typeUtils_1.isNoneInstance)(subtype)) {
|
1914
|
-
return isPositiveTest ? undefined : subtype;
|
1915
|
-
}
|
1916
|
-
if (types_1.TypeBase.isInstantiable(subtype)) {
|
1917
|
-
return isPositiveTest ? subtype : undefined;
|
1918
|
-
}
|
1919
|
-
// See if the object is callable.
|
1920
|
-
const callMemberType = (0, typeUtils_1.lookUpClassMember)(subtype, '__call__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
|
1921
|
-
if (!callMemberType) {
|
1922
|
-
if (!isPositiveTest) {
|
1923
|
-
return subtype;
|
1924
|
-
}
|
1925
|
-
if (allowIntersections) {
|
1926
|
-
// The type appears to not be callable. It's possible that the
|
1927
|
-
// two type is a subclass that is callable. We'll synthesize a
|
1928
|
-
// new intersection type.
|
1929
|
-
const className = `<callable subtype of ${subtype.shared.name}>`;
|
1930
|
-
const fileInfo = (0, analyzerNodeInfo_1.getFileInfo)(errorNode);
|
1931
|
-
let newClassType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.fileUri, 0 /* ClassTypeFlags.None */, ParseTreeUtils.getTypeSourceId(errorNode),
|
1932
|
-
/* declaredMetaclass */ undefined, subtype.shared.effectiveMetaclass, subtype.shared.docString);
|
1933
|
-
newClassType.shared.baseClasses = [types_1.ClassType.cloneAsInstantiable(subtype)];
|
1934
|
-
(0, typeUtils_1.computeMroLinearization)(newClassType);
|
1935
|
-
newClassType = (0, typeUtils_1.addConditionToType)(newClassType, (_a = subtype.props) === null || _a === void 0 ? void 0 : _a.condition);
|
1936
|
-
// Add a __call__ method to the new class.
|
1937
|
-
const callMethod = types_1.FunctionType.createSynthesizedInstance('__call__');
|
1938
|
-
const selfParam = types_1.FunctionParam.create(0 /* ParamCategory.Simple */, types_1.ClassType.cloneAsInstance(newClassType), types_1.FunctionParamFlags.TypeDeclared, 'self');
|
1939
|
-
types_1.FunctionType.addParam(callMethod, selfParam);
|
1940
|
-
types_1.FunctionType.addDefaultParams(callMethod);
|
1941
|
-
callMethod.shared.declaredReturnType = types_1.UnknownType.create();
|
1942
|
-
types_1.ClassType.getSymbolTable(newClassType).set('__call__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, callMethod));
|
1943
|
-
return types_1.ClassType.cloneAsInstance(newClassType);
|
1944
|
-
}
|
1945
|
-
return undefined;
|
1946
|
-
}
|
1947
|
-
else {
|
1948
|
-
return isPositiveTest ? subtype : undefined;
|
1949
|
-
}
|
1950
|
-
}
|
1951
|
-
default: {
|
1952
|
-
// For all other types, we can't determine whether it's
|
1953
|
-
// callable or not, so we can't eliminate them.
|
1954
|
-
return subtype;
|
1955
|
-
}
|
1956
|
-
}
|
1957
|
-
});
|
1958
|
-
}
|
1959
|
-
class Animal {
|
1960
|
-
}
|
1961
|
-
exports.Animal = Animal;
|
1962
|
-
class Dog extends Animal {
|
1963
|
-
}
|
1964
|
-
exports.Dog = Dog;
|
1965
|
-
class Plant {
|
1966
|
-
}
|
1967
|
-
exports.Plant = Plant;
|
1968
|
-
class Tree extends Plant {
|
1969
|
-
}
|
1970
|
-
exports.Tree = Tree;
|
1971
|
-
function func1(val) {
|
1972
|
-
if (val instanceof Tree) {
|
1973
|
-
console.log(val);
|
1974
|
-
}
|
1975
|
-
else {
|
1976
|
-
console.log(val);
|
1977
|
-
}
|
1978
|
-
}
|
1979
1801
|
//# sourceMappingURL=typeGuards.js.map
|