@zzzen/pyright-internal 1.2.0-dev.20240901 → 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.
Files changed (152) hide show
  1. package/dist/analyzer/analysis.d.ts +1 -0
  2. package/dist/analyzer/analysis.js +2 -0
  3. package/dist/analyzer/analysis.js.map +1 -1
  4. package/dist/analyzer/backgroundAnalysisProgram.js +6 -2
  5. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  6. package/dist/analyzer/binder.js +14 -8
  7. package/dist/analyzer/binder.js.map +1 -1
  8. package/dist/analyzer/cacheManager.d.ts +2 -2
  9. package/dist/analyzer/cacheManager.js.map +1 -1
  10. package/dist/analyzer/checker.js +53 -192
  11. package/dist/analyzer/checker.js.map +1 -1
  12. package/dist/analyzer/codeFlowEngine.js +7 -2
  13. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  14. package/dist/analyzer/constraintSolver.d.ts +1 -2
  15. package/dist/analyzer/constraintSolver.js +2 -2
  16. package/dist/analyzer/constraintSolver.js.map +1 -1
  17. package/dist/analyzer/constructors.js +7 -1
  18. package/dist/analyzer/constructors.js.map +1 -1
  19. package/dist/analyzer/dataClasses.js +6 -1
  20. package/dist/analyzer/dataClasses.js.map +1 -1
  21. package/dist/analyzer/namedTuples.js +4 -1
  22. package/dist/analyzer/namedTuples.js.map +1 -1
  23. package/dist/analyzer/operations.js +5 -0
  24. package/dist/analyzer/operations.js.map +1 -1
  25. package/dist/analyzer/parseTreeWalker.js +1 -1
  26. package/dist/analyzer/parseTreeWalker.js.map +1 -1
  27. package/dist/analyzer/patternMatching.js +3 -1
  28. package/dist/analyzer/patternMatching.js.map +1 -1
  29. package/dist/analyzer/program.js +2 -3
  30. package/dist/analyzer/program.js.map +1 -1
  31. package/dist/analyzer/properties.js.map +1 -1
  32. package/dist/analyzer/protocols.d.ts +1 -2
  33. package/dist/analyzer/protocols.js +5 -8
  34. package/dist/analyzer/protocols.js.map +1 -1
  35. package/dist/analyzer/pythonPathUtils.d.ts +1 -1
  36. package/dist/analyzer/service.d.ts +3 -1
  37. package/dist/analyzer/service.js +50 -33
  38. package/dist/analyzer/service.js.map +1 -1
  39. package/dist/analyzer/sourceMapper.js +10 -5
  40. package/dist/analyzer/sourceMapper.js.map +1 -1
  41. package/dist/analyzer/tuples.d.ts +1 -2
  42. package/dist/analyzer/tuples.js.map +1 -1
  43. package/dist/analyzer/typeEvaluator.js +599 -181
  44. package/dist/analyzer/typeEvaluator.js.map +1 -1
  45. package/dist/analyzer/typeEvaluatorTypes.d.ts +33 -6
  46. package/dist/analyzer/typeEvaluatorTypes.js +66 -2
  47. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  48. package/dist/analyzer/typeGuards.d.ts +3 -12
  49. package/dist/analyzer/typeGuards.js +286 -461
  50. package/dist/analyzer/typeGuards.js.map +1 -1
  51. package/dist/analyzer/typeStubWriter.js +12 -1
  52. package/dist/analyzer/typeStubWriter.js.map +1 -1
  53. package/dist/analyzer/typeUtils.d.ts +4 -17
  54. package/dist/analyzer/typeUtils.js +61 -60
  55. package/dist/analyzer/typeUtils.js.map +1 -1
  56. package/dist/analyzer/typedDicts.d.ts +1 -2
  57. package/dist/analyzer/typedDicts.js.map +1 -1
  58. package/dist/analyzer/types.d.ts +9 -4
  59. package/dist/analyzer/types.js +80 -26
  60. package/dist/analyzer/types.js.map +1 -1
  61. package/dist/backgroundAnalysisBase.d.ts +23 -16
  62. package/dist/backgroundAnalysisBase.js +64 -35
  63. package/dist/backgroundAnalysisBase.js.map +1 -1
  64. package/dist/backgroundThreadBase.js +9 -0
  65. package/dist/backgroundThreadBase.js.map +1 -1
  66. package/dist/commands/dumpFileDebugInfoCommand.js +0 -1
  67. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  68. package/dist/common/languageServerInterface.d.ts +1 -1
  69. package/dist/common/uri/uriUtils.d.ts +1 -1
  70. package/dist/common/uri/uriUtils.js +6 -1
  71. package/dist/common/uri/uriUtils.js.map +1 -1
  72. package/dist/languageServerBase.d.ts +2 -2
  73. package/dist/languageServerBase.js +1 -3
  74. package/dist/languageServerBase.js.map +1 -1
  75. package/dist/languageService/analyzerServiceExecutor.d.ts +6 -1
  76. package/dist/languageService/analyzerServiceExecutor.js +7 -6
  77. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  78. package/dist/languageService/callHierarchyProvider.js +2 -1
  79. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  80. package/dist/languageService/completionProvider.js +12 -12
  81. package/dist/languageService/completionProvider.js.map +1 -1
  82. package/dist/languageService/definitionProvider.js +6 -6
  83. package/dist/languageService/definitionProvider.js.map +1 -1
  84. package/dist/languageService/documentSymbolCollector.js +9 -9
  85. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  86. package/dist/languageService/fileWatcherDynamicFeature.d.ts +5 -1
  87. package/dist/languageService/fileWatcherDynamicFeature.js +12 -2
  88. package/dist/languageService/fileWatcherDynamicFeature.js.map +1 -1
  89. package/dist/languageService/hoverProvider.d.ts +1 -0
  90. package/dist/languageService/hoverProvider.js +30 -3
  91. package/dist/languageService/hoverProvider.js.map +1 -1
  92. package/dist/languageService/signatureHelpProvider.js +2 -2
  93. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  94. package/dist/languageService/tooltipUtils.js +2 -2
  95. package/dist/languageService/tooltipUtils.js.map +1 -1
  96. package/dist/localization/localize.d.ts +10 -0
  97. package/dist/localization/localize.js +4 -0
  98. package/dist/localization/localize.js.map +1 -1
  99. package/dist/localization/package.nls.cs.json +155 -153
  100. package/dist/localization/package.nls.de.json +128 -126
  101. package/dist/localization/package.nls.en-us.json +1632 -404
  102. package/dist/localization/package.nls.es.json +151 -149
  103. package/dist/localization/package.nls.fr.json +129 -127
  104. package/dist/localization/package.nls.it.json +143 -141
  105. package/dist/localization/package.nls.ja.json +142 -140
  106. package/dist/localization/package.nls.ko.json +155 -153
  107. package/dist/localization/package.nls.pl.json +178 -176
  108. package/dist/localization/package.nls.pt-br.json +139 -137
  109. package/dist/localization/package.nls.qps-ploc.json +392 -390
  110. package/dist/localization/package.nls.ru.json +170 -168
  111. package/dist/localization/package.nls.tr.json +153 -151
  112. package/dist/localization/package.nls.zh-cn.json +149 -147
  113. package/dist/localization/package.nls.zh-tw.json +133 -131
  114. package/dist/parser/parseNodes.d.ts +2 -3
  115. package/dist/parser/parseNodes.js.map +1 -1
  116. package/dist/parser/parser.js +6 -20
  117. package/dist/parser/parser.js.map +1 -1
  118. package/dist/tests/checker.test.js +14 -1
  119. package/dist/tests/checker.test.js.map +1 -1
  120. package/dist/tests/envVarUtils.test.js +0 -3
  121. package/dist/tests/envVarUtils.test.js.map +1 -1
  122. package/dist/tests/harness/fourslash/testLanguageService.js +0 -3
  123. package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
  124. package/dist/tests/harness/fourslash/testState.js +2 -5
  125. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  126. package/dist/tests/harness/fourslash/testStateUtils.d.ts +1 -0
  127. package/dist/tests/harness/fourslash/testStateUtils.js +5 -0
  128. package/dist/tests/harness/fourslash/testStateUtils.js.map +1 -1
  129. package/dist/tests/harness/vfs/filesystem.d.ts +3 -2
  130. package/dist/tests/harness/vfs/filesystem.js +6 -3
  131. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  132. package/dist/tests/importStatementUtils.test.js +1 -1
  133. package/dist/tests/importStatementUtils.test.js.map +1 -1
  134. package/dist/tests/service.test.js +31 -0
  135. package/dist/tests/service.test.js.map +1 -1
  136. package/dist/tests/typeEvaluator1.test.js +5 -1
  137. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  138. package/dist/tests/typeEvaluator2.test.js +13 -1
  139. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  140. package/dist/tests/typeEvaluator3.test.js +5 -1
  141. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  142. package/dist/tests/typeEvaluator5.test.js +6 -0
  143. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  144. package/dist/tests/typeEvaluator6.test.js +5 -1
  145. package/dist/tests/typeEvaluator6.test.js.map +1 -1
  146. package/dist/tests/typeEvaluator7.test.js +1 -1
  147. package/dist/tests/typeEvaluator8.test.js +40 -0
  148. package/dist/tests/typeEvaluator8.test.js.map +1 -1
  149. package/dist/workspaceFactory.d.ts +2 -20
  150. package/dist/workspaceFactory.js +26 -64
  151. package/dist/workspaceFactory.js.map +1 -1
  152. 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.isIsinstanceFilterSuperclass = isIsinstanceFilterSuperclass;
39
- exports.isIsinstanceFilterSubclass = isIsinstanceFilterSubclass;
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
- // Use speculative mode here to avoid polluting the type cache. This is
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: narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck,
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 narrowTypeForIsInstance(evaluator, type, filterTypes,
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 "...".
@@ -800,7 +773,16 @@ function getIsInstanceClassTypes(evaluator, argType) {
800
773
  subtype = (0, typeUtils_1.convertToInstantiable)((0, typeUtils_1.getUnknownTypeForCallable)());
801
774
  }
802
775
  }
803
- if ((0, types_1.isInstantiableClass)(subtype) || ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstantiable(subtype))) {
776
+ if ((0, types_1.isInstantiableClass)(subtype)) {
777
+ // If this is a reference to a class that has type promotions (e.g.
778
+ // float or complex), remove the promotions for purposes of the
779
+ // isinstance check).
780
+ if (!subtype.priv.includeSubclasses && subtype.priv.includePromotions) {
781
+ subtype = types_1.ClassType.cloneRemoveTypePromotions(subtype);
782
+ }
783
+ classTypeList.push(subtype);
784
+ }
785
+ else if ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstantiable(subtype)) {
804
786
  classTypeList.push(subtype);
805
787
  }
806
788
  else if ((0, typeUtils_1.isNoneTypeClass)(subtype)) {
@@ -840,68 +822,50 @@ function getIsInstanceClassTypes(evaluator, argType) {
840
822
  });
841
823
  return foundNonClassType ? undefined : classTypeList;
842
824
  }
843
- function isIsinstanceFilterSuperclass(evaluator, varType, concreteVarType, filterType, concreteFilterType, isInstanceCheck) {
844
- if ((0, types_1.isTypeVar)(filterType) || concreteFilterType.priv.literalValue !== undefined) {
845
- return (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(filterType), varType);
846
- }
847
- // If the filter type represents all possible subclasses
848
- // of a type, we can't make any statements about its superclass
849
- // relationship with concreteVarType.
850
- if (concreteFilterType.priv.includeSubclasses) {
851
- return false;
852
- }
853
- if (types_1.ClassType.isDerivedFrom(concreteVarType, concreteFilterType)) {
854
- return true;
855
- }
856
- if (isInstanceCheck) {
857
- // We convert both types to instances in case they are protocol
858
- // classes. A protocol class isn't allowed to be assigned to
859
- // type[T], so this would otherwise fail.
860
- if (types_1.ClassType.isProtocolClass(concreteFilterType) &&
861
- evaluator.assignType(types_1.ClassType.cloneAsInstance(concreteFilterType), types_1.ClassType.cloneAsInstance(concreteVarType))) {
862
- return true;
863
- }
864
- }
865
- // Handle the special case where the variable type is a TypedDict and
866
- // we're filtering against 'dict'. TypedDict isn't derived from dict,
867
- // but at runtime, isinstance returns True.
868
- if (types_1.ClassType.isBuiltIn(concreteFilterType, 'dict') && types_1.ClassType.isTypedDictClass(concreteVarType)) {
869
- return true;
870
- }
871
- return false;
872
- }
873
- function isIsinstanceFilterSubclass(evaluator, varType, concreteFilterType, isInstanceCheck) {
874
- if (types_1.ClassType.isDerivedFrom(concreteFilterType, varType)) {
875
- return true;
876
- }
877
- if (isInstanceCheck) {
878
- // We convert both types to instances in case they are protocol
879
- // classes. A protocol class isn't allowed to be assigned to
880
- // type[T], so this would otherwise fail.
881
- if (types_1.ClassType.isProtocolClass(varType) &&
882
- evaluator.assignType(types_1.ClassType.cloneAsInstance(varType), types_1.ClassType.cloneAsInstance(concreteFilterType))) {
883
- return true;
884
- }
885
- }
886
- return false;
887
- }
888
- function narrowTypeForIsInstance(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest, errorNode) {
825
+ function narrowTypeForInstanceOrSubclass(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest, errorNode) {
889
826
  // First try with intersection types disallowed.
890
- const narrowedType = narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
827
+ const narrowedType = narrowTypeForInstanceOrSubclassInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
891
828
  /* allowIntersections */ false, errorNode);
892
829
  if (!(0, types_1.isNever)(narrowedType)) {
893
830
  return narrowedType;
894
831
  }
895
832
  // Try again with intersection types allowed.
896
- return narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
833
+ return narrowTypeForInstanceOrSubclassInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
897
834
  /* allowIntersections */ true, errorNode);
898
835
  }
899
- // Attempts to narrow a type (make it more constrained) based on a
900
- // call to isinstance or issubclass. For example, if the original
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
901
865
  // type of expression "x" is "Mammal" and the test expression is
902
- // "isinstance(x, Cow)", (assuming "Cow" is a subclass of "Mammal"),
903
- // we can conclude that x must be constrained to "Cow".
904
- function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest, allowIntersections, errorNode) {
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) {
905
869
  let expandedTypes = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
906
870
  return (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(subtype);
907
871
  });
@@ -919,29 +883,67 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
919
883
  // and returns the list of types the varType could be after
920
884
  // applying the filter.
921
885
  const filterClassType = (varType, concreteVarType, conditions, negativeFallbackType) => {
922
- var _a, _b, _c;
886
+ var _a, _b, _c, _d, _e;
923
887
  const filteredTypes = [];
924
888
  let foundSuperclass = false;
925
889
  let isClassRelationshipIndeterminate = false;
926
890
  for (const filterType of filterTypes) {
927
- let concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
891
+ const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
928
892
  if ((0, types_1.isInstantiableClass)(concreteFilterType)) {
929
- let filterIsSuperclass;
930
- let filterIsSubclass;
931
- if (isTypeIsCheck) {
932
- filterIsSuperclass = evaluator.assignType(filterType, concreteVarType);
933
- filterIsSubclass = evaluator.assignType(concreteVarType, filterType);
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
+ }
934
921
  }
935
- else {
936
- // If the class was implicitly specialized (e.g. because its type
937
- // parameters have default values), replace the default type arguments
938
- // with Unknown.
939
- if (concreteFilterType.priv.typeArgs && !concreteFilterType.priv.isTypeArgExplicit) {
940
- concreteFilterType = (0, typeUtils_1.specializeWithUnknownTypeArgs)(types_1.ClassType.specialize(concreteFilterType, /* typeArgs */ undefined), evaluator.getTupleClassType());
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
+ ]);
941
939
  }
942
- filterIsSuperclass = isIsinstanceFilterSuperclass(evaluator, varType, concreteVarType, filterType, concreteFilterType, isInstanceCheck);
943
- filterIsSubclass = isIsinstanceFilterSubclass(evaluator, concreteVarType, concreteFilterType, isInstanceCheck);
944
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 */);
945
947
  if (filterIsSuperclass) {
946
948
  foundSuperclass = true;
947
949
  }
@@ -950,10 +952,16 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
950
952
  // class whose type is unknown (e.g. an import failed). We'll
951
953
  // note this case specially so we don't do any narrowing, which
952
954
  // will generate false positives.
953
- if (filterIsSubclass &&
954
- filterIsSuperclass &&
955
- !types_1.ClassType.isSameGenericClass(concreteVarType, concreteFilterType)) {
956
- isClassRelationshipIndeterminate = true;
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
+ }
957
965
  }
958
966
  // If both the variable type and the filter type ar generics, we can't
959
967
  // determine the relationship between the two.
@@ -973,46 +981,44 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
973
981
  }
974
982
  }
975
983
  else if (filterIsSubclass) {
976
- if (evaluator.assignType((0, typeUtils_1.convertToInstance)(convertVarTypeToFree(concreteVarType)), (0, typeUtils_1.convertToInstance)(concreteFilterType),
977
- /* diag */ undefined,
978
- /* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */)) {
979
- // If the variable type is a superclass of the isinstance
980
- // filter, we can narrow the type to the subclass.
981
- let specializedFilterType = filterType;
982
- // Try to retain the type arguments for the filter type. This is
983
- // important because a specialized version of the filter cannot
984
- // be passed to isinstance or issubclass.
985
- if ((0, types_1.isClass)(filterType)) {
986
- if (types_1.ClassType.isSpecialBuiltIn(filterType) || filterType.shared.typeParams.length > 0) {
987
- if (!filterType.priv.isTypeArgExplicit &&
988
- !types_1.ClassType.isSameGenericClass(concreteVarType, filterType)) {
989
- const constraints = new constraintTracker_1.ConstraintTracker();
990
- const unspecializedFilterType = types_1.ClassType.specialize(filterType,
991
- /* typeArg */ undefined);
992
- if ((0, constraintSolver_1.addConstraintsForExpectedType)(evaluator, (0, typeUtils_1.convertToInstance)(unspecializedFilterType), (0, typeUtils_1.convertToInstance)(concreteVarType), constraints,
993
- /* liveTypeVarScopes */ undefined, errorNode.start)) {
994
- specializedFilterType = evaluator.solveAndApplyConstraints(unspecializedFilterType, constraints, {
995
- replaceUnsolved: {
996
- scopeIds: (0, typeUtils_1.getTypeVarScopeIds)(filterType),
997
- useUnknown: true,
998
- tupleClassType: evaluator.getTupleClassType(),
999
- },
1000
- });
1001
- }
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
+ });
1002
1006
  }
1003
1007
  }
1004
1008
  }
1005
- filteredTypes.push((0, typeUtils_1.addConditionToType)(specializedFilterType, conditions));
1006
1009
  }
1010
+ filteredTypes.push((0, typeUtils_1.addConditionToType)(specializedFilterType, conditions));
1007
1011
  }
1008
- else if (types_1.ClassType.isSameGenericClass(concreteVarType, concreteFilterType)) {
1009
- // Don't attempt to narrow in this case.
1010
- if (((_a = concreteVarType.priv) === null || _a === void 0 ? void 0 : _a.literalValue) === undefined &&
1011
- ((_b = concreteFilterType.priv) === null || _b === void 0 ? void 0 : _b.literalValue) === undefined) {
1012
- const intersection = intersectSameClassType(evaluator, concreteVarType, concreteFilterType);
1013
- filteredTypes.push(intersection !== null && intersection !== void 0 ? intersection : varType);
1014
- // Don't attempt to narrow in the negative direction.
1015
- isClassRelationshipIndeterminate = true;
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
+ }
1016
1022
  }
1017
1023
  }
1018
1024
  else if (allowIntersections &&
@@ -1029,17 +1035,22 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1029
1035
  }
1030
1036
  let newClassObjType = types_1.ClassType.cloneAsInstance(newClassType);
1031
1037
  newClassObjType = (0, typeUtils_1.addConditionToType)(newClassObjType, (_c = concreteVarType.props) === null || _c === void 0 ? void 0 : _c.condition);
1032
- // If this is a issubclass check, we do a double conversion from instantiable
1033
- // to instance back to instantiable to make sure that the includeSubclasses flag
1034
- // gets cleared.
1035
- filteredTypes.push(isInstanceCheck ? newClassObjType : types_1.ClassType.cloneAsInstantiable(newClassObjType));
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));
1036
1047
  }
1037
1048
  }
1038
1049
  }
1039
1050
  else if ((0, types_1.isTypeVar)(filterType) && types_1.TypeBase.isInstantiable(filterType)) {
1040
1051
  // Handle the case where the filter type is Type[T] and the unexpanded
1041
1052
  // subtype is some instance type, possibly T.
1042
- if (isInstanceCheck && types_1.TypeBase.isInstance(varType)) {
1053
+ if (types_1.TypeBase.isInstance(varType)) {
1043
1054
  if ((0, types_1.isTypeVar)(varType) && (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(filterType), varType)) {
1044
1055
  // If the unexpanded subtype is T, we can definitively filter
1045
1056
  // in both the positive and negative cases.
@@ -1062,51 +1073,53 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1062
1073
  }
1063
1074
  }
1064
1075
  }
1065
- else if (!isInstanceCheck && types_1.TypeBase.isInstantiable(varType)) {
1066
- if ((0, types_1.isTypeVar)(varType) && (0, types_1.isTypeSame)(filterType, varType)) {
1067
- if (isPositiveTest) {
1068
- filteredTypes.push(varType);
1069
- }
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;
1070
1083
  }
1071
1084
  else {
1072
- if (isPositiveTest) {
1073
- filteredTypes.push(filterType);
1074
- }
1075
- else {
1076
- filteredTypes.push(varType);
1077
- isClassRelationshipIndeterminate = true;
1078
- }
1085
+ isCallable = !!(0, typeUtils_1.lookUpClassMember)(concreteVarType, '__call__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
1079
1086
  }
1080
1087
  }
1081
- }
1082
- else if ((0, types_1.isFunction)(filterType)) {
1083
- // Handle an isinstance check against Callable.
1084
- if (isInstanceCheck) {
1085
- let isCallable = false;
1086
- if ((0, types_1.isClass)(concreteVarType)) {
1087
- if (types_1.TypeBase.isInstantiable(varType)) {
1088
- isCallable = true;
1089
- }
1090
- else {
1091
- isCallable = !!(0, typeUtils_1.lookUpClassMember)(concreteVarType, '__call__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
1092
- }
1088
+ if (isCallable) {
1089
+ if (isPositiveTest) {
1090
+ filteredTypes.push((0, typeUtils_1.convertToInstantiable)(varType));
1093
1091
  }
1094
- if (isCallable) {
1095
- if (isPositiveTest) {
1096
- filteredTypes.push(varType);
1097
- }
1098
- else {
1099
- foundSuperclass = true;
1100
- }
1092
+ else {
1093
+ foundSuperclass = true;
1101
1094
  }
1102
- else if (evaluator.assignType(convertVarTypeToFree(concreteVarType), filterType,
1103
- /* diag */ undefined,
1104
- /* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */)) {
1105
- if (isPositiveTest) {
1106
- filteredTypes.push(filterType);
1107
- }
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));
1108
1101
  }
1109
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
+ }
1110
1123
  }
1111
1124
  }
1112
1125
  // In the negative case, if one or more of the filters
@@ -1116,101 +1129,58 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1116
1129
  // match, then the original variable type survives the filter.
1117
1130
  if (!isPositiveTest) {
1118
1131
  if (!foundSuperclass || isClassRelationshipIndeterminate) {
1119
- filteredTypes.push(isInstanceCheck ? (0, typeUtils_1.convertToInstantiable)(negativeFallbackType) : negativeFallbackType);
1132
+ filteredTypes.push((0, typeUtils_1.convertToInstantiable)(negativeFallbackType));
1120
1133
  }
1121
1134
  }
1122
- if (!isInstanceCheck) {
1123
- // We perform a double conversion from instance to instantiable
1124
- // here to make sure that the includeSubclasses flag is cleared
1125
- // if it's a class.
1126
- return filteredTypes.map((t) => ((0, types_1.isInstantiableClass)(t) ? (0, typeUtils_1.convertToInstantiable)((0, typeUtils_1.convertToInstance)(t)) : t));
1127
- }
1128
1135
  return filteredTypes.map((t) => (0, typeUtils_1.convertToInstance)(t));
1129
1136
  };
1130
- // Filters the metaclassType (which is assumed to be a metaclass instance)
1131
- // by the classTypeList and returns the list of types the varType could be
1132
- // after applying the filter.
1133
- const filterMetaclassType = (metaclassType, negativeFallbackType) => {
1134
- const filteredTypes = [];
1135
- let foundPositiveMatch = false;
1136
- let isMatchIndeterminate = false;
1137
- for (const filterType of filterTypes) {
1138
- const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
1139
- if ((0, types_1.isInstantiableClass)(concreteFilterType)) {
1140
- const filterMetaclass = concreteFilterType.shared.effectiveMetaclass;
1141
- if (filterMetaclass && (0, types_1.isInstantiableClass)(filterMetaclass)) {
1142
- let isMetaclassOverlap = evaluator.assignType(convertVarTypeToFree(metaclassType), types_1.ClassType.cloneAsInstance(filterMetaclass));
1143
- // Handle the special case where the metaclass for the filter is type.
1144
- // This will normally be treated as type[Any], which is compatible with
1145
- // any metaclass, but we specifically want to treat type as the class
1146
- // type[object] in this case.
1147
- if (types_1.ClassType.isBuiltIn(filterMetaclass, 'type') && !filterMetaclass.priv.isTypeArgExplicit) {
1148
- if (!types_1.ClassType.isBuiltIn(metaclassType, 'type')) {
1149
- isMetaclassOverlap = false;
1150
- }
1151
- }
1152
- if (isMetaclassOverlap) {
1153
- if (isPositiveTest) {
1154
- filteredTypes.push(filterType);
1155
- foundPositiveMatch = true;
1156
- }
1157
- else if (!(0, types_1.isTypeSame)(metaclassType, filterMetaclass) ||
1158
- filterMetaclass.priv.includeSubclasses) {
1159
- filteredTypes.push(metaclassType);
1160
- isMatchIndeterminate = true;
1161
- }
1162
- }
1163
- }
1164
- else {
1165
- filteredTypes.push(metaclassType);
1166
- isMatchIndeterminate = true;
1167
- }
1168
- }
1169
- else {
1170
- filteredTypes.push(metaclassType);
1171
- isMatchIndeterminate = true;
1172
- }
1173
- }
1174
- // In the negative case, if one or more of the filters
1175
- // always match the type in the positive case, then there's nothing
1176
- // left after the filter is applied.
1177
- if (!isPositiveTest) {
1178
- if (!foundPositiveMatch || isMatchIndeterminate) {
1179
- filteredTypes.push(negativeFallbackType);
1180
- }
1181
- }
1182
- // We perform a double conversion from instance to instantiable
1183
- // here to make sure that the includeSubclasses flag is cleared
1184
- // if it's a class.
1185
- 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);
1186
1140
  };
1187
1141
  const filterFunctionType = (varType, unexpandedType) => {
1188
1142
  const filteredTypes = [];
1189
1143
  if (isPositiveTest) {
1190
1144
  for (const filterType of filterTypes) {
1191
1145
  const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
1192
- if (evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType))) {
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))) {
1193
1150
  // If the filter type is a Callable, use the original type. If the
1194
1151
  // filter type is a callback protocol, use the filter type.
1195
1152
  if ((0, types_1.isFunction)(filterType)) {
1196
- filteredTypes.push(unexpandedType);
1153
+ filteredTypes.push((0, typeUtils_1.convertToInstance)(unexpandedType));
1197
1154
  }
1198
1155
  else {
1199
1156
  filteredTypes.push((0, typeUtils_1.convertToInstance)(filterType));
1200
1157
  }
1201
1158
  }
1159
+ else if (evaluator.assignType((0, typeUtils_1.convertToInstance)(convertVarTypeToFree(concreteFilterType)), varType)) {
1160
+ filteredTypes.push((0, typeUtils_1.convertToInstance)(varType));
1161
+ }
1202
1162
  }
1203
1163
  }
1204
- else if (!filterTypes.some((filterType) => {
1205
- // If the filter type is a runtime checkable protocol class, it can
1206
- // be used in an instance check.
1207
- const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
1208
- if ((0, types_1.isClass)(concreteFilterType) && !types_1.ClassType.isProtocolClass(concreteFilterType)) {
1209
- return false;
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));
1210
1183
  }
1211
- return evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType));
1212
- })) {
1213
- filteredTypes.push(unexpandedType);
1214
1184
  }
1215
1185
  return filteredTypes;
1216
1186
  };
@@ -1233,77 +1203,36 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1233
1203
  // on a constrained TypeVar that they want to filter based on its constrained
1234
1204
  // parts.
1235
1205
  const negativeFallback = (0, typeUtils_1.getTypeCondition)(subtype) ? subtype : unexpandedSubtype;
1236
- const isSubtypeMetaclass = (0, typeUtils_1.isMetaclassInstance)(subtype);
1237
1206
  if (isPositiveTest && (0, types_1.isAnyOrUnknown)(subtype)) {
1238
1207
  // If this is a positive test and the effective type is Any or
1239
1208
  // Unknown, we can assume that the type matches one of the
1240
1209
  // specified types.
1241
- if (isInstanceCheck) {
1242
- anyOrUnknownSubstitutions.push((0, types_1.combineTypes)(filterTypes.map((classType) => (0, typeUtils_1.convertToInstance)(classType))));
1243
- }
1244
- else {
1245
- // We perform a double conversion from instance to instantiable
1246
- // here to make sure that the includeSubclasses flag is cleared
1247
- // if it's a class.
1248
- anyOrUnknownSubstitutions.push((0, types_1.combineTypes)(filterTypes.map((classType) => (0, typeUtils_1.convertToInstantiable)((0, typeUtils_1.convertToInstance)(classType)))));
1249
- }
1210
+ anyOrUnknownSubstitutions.push((0, types_1.combineTypes)(filterTypes.map((classType) => (0, typeUtils_1.convertToInstance)(classType))));
1250
1211
  anyOrUnknown.push(subtype);
1251
1212
  return undefined;
1252
1213
  }
1253
- if (isInstanceCheck) {
1254
- if ((0, typeUtils_1.isNoneInstance)(subtype)) {
1255
- return classListContainsNoneType() === isPositiveTest ? subtype : undefined;
1256
- }
1257
- if ((0, types_1.isModule)(subtype) || ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'ModuleType'))) {
1258
- // Handle type narrowing for runtime-checkable protocols
1259
- // when applied to modules.
1260
- if (isPositiveTest) {
1261
- const filteredTypes = filterTypes.filter((classType) => {
1262
- const concreteClassType = evaluator.makeTopLevelTypeVarsConcrete(classType);
1263
- return ((0, types_1.isInstantiableClass)(concreteClassType) && types_1.ClassType.isProtocolClass(concreteClassType));
1264
- });
1265
- if (filteredTypes.length > 0) {
1266
- return (0, typeUtils_1.convertToInstance)((0, types_1.combineTypes)(filteredTypes));
1267
- }
1268
- }
1269
- }
1270
- if ((0, types_1.isClassInstance)(subtype)) {
1271
- return (0, types_1.combineTypes)(filterClassType(unexpandedSubtype, types_1.ClassType.cloneAsInstantiable(subtype), (0, typeUtils_1.getTypeCondition)(subtype), negativeFallback));
1272
- }
1273
- if (((0, types_1.isFunction)(subtype) || (0, types_1.isOverloaded)(subtype)) && isInstanceCheck) {
1274
- return (0, types_1.combineTypes)(filterFunctionType(subtype, (0, typeUtils_1.convertToInstance)(unexpandedSubtype)));
1275
- }
1276
- if ((0, types_1.isInstantiableClass)(subtype) || isSubtypeMetaclass) {
1277
- // Handle the special case of isinstance(x, metaclass).
1278
- const includesMetaclassType = filterTypes.some((classType) => (0, typeUtils_1.isInstantiableMetaclass)(classType));
1279
- const includesObject = filterTypes.some((classType) => (0, types_1.isInstantiableClass)(classType) && types_1.ClassType.isBuiltIn(classType, 'object'));
1280
- if (isPositiveTest) {
1281
- return includesMetaclassType || includesObject ? negativeFallback : undefined;
1282
- }
1283
- else {
1284
- return includesMetaclassType ? undefined : negativeFallback;
1285
- }
1286
- }
1214
+ if ((0, typeUtils_1.isNoneInstance)(subtype)) {
1215
+ return classListContainsNoneType() === isPositiveTest ? subtype : undefined;
1287
1216
  }
1288
- else {
1289
- if ((0, typeUtils_1.isNoneTypeClass)(subtype)) {
1290
- return classListContainsNoneType() === isPositiveTest ? subtype : undefined;
1291
- }
1292
- if ((0, types_1.isClass)(subtype)) {
1293
- if ((0, types_1.isInstantiableClass)(subtype)) {
1294
- return (0, types_1.combineTypes)(filterClassType(unexpandedSubtype, subtype, (0, typeUtils_1.getTypeCondition)(subtype), negativeFallback));
1295
- }
1296
- else if ((0, typeUtils_1.isMetaclassInstance)(subtype)) {
1297
- return (0, types_1.combineTypes)(filterMetaclassType(subtype, negativeFallback));
1298
- }
1299
- }
1300
- if (isSubtypeMetaclass) {
1301
- const objectType = evaluator.getBuiltInObject(errorNode, 'object');
1302
- if (objectType && (0, types_1.isClassInstance)(objectType)) {
1303
- 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));
1304
1227
  }
1305
1228
  }
1306
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
+ }
1307
1236
  return isPositiveTest ? undefined : negativeFallback;
1308
1237
  });
1309
1238
  // If the result is Any/Unknown and contains no other subtypes and
@@ -1491,62 +1420,21 @@ function getElementTypeForContainerNarrowing(containerType) {
1491
1420
  return elementType;
1492
1421
  }
1493
1422
  function narrowTypeForContainerElementType(evaluator, referenceType, elementType) {
1494
- let canNarrow = true;
1495
- const elementTypeWithoutLiteral = evaluator.stripLiteralValue(elementType);
1496
- // Look for cases where one or more of the reference subtypes are
1497
- // supertypes of the element types. For example, if the element type
1498
- // is "int | str" and the reference type is "float | bytes", we can
1499
- // narrow the reference type to "float" because it is a supertype of "int".
1500
- const narrowedSupertypes = evaluator.mapSubtypesExpandTypeVars(referenceType,
1501
- /* options */ undefined, (referenceSubtype) => {
1502
- if ((0, types_1.isAnyOrUnknown)(referenceSubtype)) {
1503
- canNarrow = false;
1504
- return referenceSubtype;
1505
- }
1506
- // Handle "type" specially.
1507
- if ((0, types_1.isClassInstance)(referenceSubtype) && types_1.ClassType.isBuiltIn(referenceSubtype, 'type')) {
1508
- canNarrow = false;
1509
- return referenceSubtype;
1510
- }
1511
- if (evaluator.assignType(elementType, referenceSubtype)) {
1512
- return referenceSubtype;
1513
- }
1514
- if (evaluator.assignType(elementTypeWithoutLiteral, referenceSubtype)) {
1515
- return (0, typeUtils_1.mapSubtypes)(elementType, (elementSubtype) => {
1516
- if ((0, types_1.isClassInstance)(elementSubtype) &&
1517
- (0, types_1.isSameWithoutLiteralValue)(referenceSubtype, elementSubtype)) {
1518
- return elementSubtype;
1519
- }
1520
- return undefined;
1521
- });
1522
- }
1523
- return undefined;
1524
- });
1525
- // Look for cases where one or more of the reference subtypes are
1526
- // subtypes of the element types. For example, if the element type
1527
- // is "int | str" and the reference type is "object", we can
1528
- // narrow the reference type to "int | str" because they are both
1529
- // subtypes of "object".
1530
- const narrowedSubtypes = evaluator.mapSubtypesExpandTypeVars(elementType,
1531
- /* options */ undefined, (elementSubtype) => {
1532
- if ((0, types_1.isAnyOrUnknown)(elementSubtype)) {
1533
- canNarrow = false;
1534
- return referenceType;
1535
- }
1536
- // Handle the special case where the reference type is a dict or Mapping and
1537
- // the element type is a TypedDict. In this case, we can't say whether there
1538
- // is a type overlap, so don't apply narrowing.
1539
- if ((0, types_1.isClassInstance)(referenceType) && types_1.ClassType.isBuiltIn(referenceType, ['dict', 'Mapping'])) {
1540
- if ((0, types_1.isClassInstance)(elementSubtype) && types_1.ClassType.isTypedDictClass(elementSubtype)) {
1541
- 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;
1542
1428
  }
1543
- }
1544
- if (evaluator.assignType(referenceType, elementSubtype)) {
1545
- return elementSubtype;
1546
- }
1547
- return undefined;
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
+ });
1548
1437
  });
1549
- return canNarrow ? (0, types_1.combineTypes)([narrowedSupertypes, narrowedSubtypes]) : referenceType;
1550
1438
  }
1551
1439
  // Attempts to narrow a type based on whether it is a TypedDict with
1552
1440
  // a literal key value.
@@ -1783,8 +1671,7 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
1783
1671
  if (types_1.TypeBase.isInstance(concreteSubtype)) {
1784
1672
  return types_1.ClassType.isBuiltIn(concreteSubtype, 'object') ? classType : undefined;
1785
1673
  }
1786
- const isSuperType = isIsinstanceFilterSuperclass(evaluator, subtype, concreteSubtype, classType, classType,
1787
- /* isInstanceCheck */ false);
1674
+ const isSuperType = isFilterSuperclass(subtype, concreteSubtype, classType, classType);
1788
1675
  if (!classType.priv.includeSubclasses) {
1789
1676
  // Handle the case where the LHS and RHS operands are specific
1790
1677
  // classes, as opposed to types that represent classes and their
@@ -1792,11 +1679,10 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
1792
1679
  if (!concreteSubtype.priv.includeSubclasses) {
1793
1680
  return types_1.ClassType.isSameGenericClass(concreteSubtype, classType) ? classType : undefined;
1794
1681
  }
1795
- const isSubType = isIsinstanceFilterSubclass(evaluator, concreteSubtype, classType,
1796
- /* isInstanceCheck */ false);
1797
1682
  if (isSuperType) {
1798
1683
  return classType;
1799
1684
  }
1685
+ const isSubType = types_1.ClassType.isDerivedFrom(classType, concreteSubtype);
1800
1686
  if (isSubType) {
1801
1687
  return (0, typeUtils_1.addConditionToType)(classType, (0, typeUtils_1.getTypeCondition)(concreteSubtype));
1802
1688
  }
@@ -1817,6 +1703,27 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
1817
1703
  return subtype;
1818
1704
  });
1819
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
+ }
1820
1727
  // Attempts to narrow a type (make it more constrained) based on a comparison
1821
1728
  // (equal or not equal) to a literal value. It also handles "is" or "is not"
1822
1729
  // operators if isIsOperator is true.
@@ -1891,86 +1798,4 @@ function enumerateLiteralsForType(evaluator, type) {
1891
1798
  }
1892
1799
  return undefined;
1893
1800
  }
1894
- // Attempts to narrow a type (make it more constrained) based on a
1895
- // call to "callable". For example, if the original type of expression "x" is
1896
- // Union[Callable[..., Any], Type[int], int], it would remove the "int" because
1897
- // it's not callable.
1898
- function narrowTypeForCallable(evaluator, type, isPositiveTest, errorNode, allowIntersections) {
1899
- return evaluator.mapSubtypesExpandTypeVars(type, /* options */ undefined, (subtype) => {
1900
- var _a;
1901
- switch (subtype.category) {
1902
- case 4 /* TypeCategory.Function */:
1903
- case 5 /* TypeCategory.Overloaded */: {
1904
- return isPositiveTest ? subtype : undefined;
1905
- }
1906
- case 7 /* TypeCategory.Module */: {
1907
- return isPositiveTest ? undefined : subtype;
1908
- }
1909
- case 6 /* TypeCategory.Class */: {
1910
- if ((0, typeUtils_1.isNoneInstance)(subtype)) {
1911
- return isPositiveTest ? undefined : subtype;
1912
- }
1913
- if (types_1.TypeBase.isInstantiable(subtype)) {
1914
- return isPositiveTest ? subtype : undefined;
1915
- }
1916
- // See if the object is callable.
1917
- const callMemberType = (0, typeUtils_1.lookUpClassMember)(subtype, '__call__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
1918
- if (!callMemberType) {
1919
- if (!isPositiveTest) {
1920
- return subtype;
1921
- }
1922
- if (allowIntersections) {
1923
- // The type appears to not be callable. It's possible that the
1924
- // two type is a subclass that is callable. We'll synthesize a
1925
- // new intersection type.
1926
- const className = `<callable subtype of ${subtype.shared.name}>`;
1927
- const fileInfo = (0, analyzerNodeInfo_1.getFileInfo)(errorNode);
1928
- let newClassType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.fileUri, 0 /* ClassTypeFlags.None */, ParseTreeUtils.getTypeSourceId(errorNode),
1929
- /* declaredMetaclass */ undefined, subtype.shared.effectiveMetaclass, subtype.shared.docString);
1930
- newClassType.shared.baseClasses = [types_1.ClassType.cloneAsInstantiable(subtype)];
1931
- (0, typeUtils_1.computeMroLinearization)(newClassType);
1932
- newClassType = (0, typeUtils_1.addConditionToType)(newClassType, (_a = subtype.props) === null || _a === void 0 ? void 0 : _a.condition);
1933
- // Add a __call__ method to the new class.
1934
- const callMethod = types_1.FunctionType.createSynthesizedInstance('__call__');
1935
- const selfParam = types_1.FunctionParam.create(0 /* ParamCategory.Simple */, types_1.ClassType.cloneAsInstance(newClassType), types_1.FunctionParamFlags.TypeDeclared, 'self');
1936
- types_1.FunctionType.addParam(callMethod, selfParam);
1937
- types_1.FunctionType.addDefaultParams(callMethod);
1938
- callMethod.shared.declaredReturnType = types_1.UnknownType.create();
1939
- types_1.ClassType.getSymbolTable(newClassType).set('__call__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, callMethod));
1940
- return types_1.ClassType.cloneAsInstance(newClassType);
1941
- }
1942
- return undefined;
1943
- }
1944
- else {
1945
- return isPositiveTest ? subtype : undefined;
1946
- }
1947
- }
1948
- default: {
1949
- // For all other types, we can't determine whether it's
1950
- // callable or not, so we can't eliminate them.
1951
- return subtype;
1952
- }
1953
- }
1954
- });
1955
- }
1956
- class Animal {
1957
- }
1958
- exports.Animal = Animal;
1959
- class Dog extends Animal {
1960
- }
1961
- exports.Dog = Dog;
1962
- class Plant {
1963
- }
1964
- exports.Plant = Plant;
1965
- class Tree extends Plant {
1966
- }
1967
- exports.Tree = Tree;
1968
- function func1(val) {
1969
- if (val instanceof Tree) {
1970
- console.log(val);
1971
- }
1972
- else {
1973
- console.log(val);
1974
- }
1975
- }
1976
1801
  //# sourceMappingURL=typeGuards.js.map