@zzzen/pyright-internal 1.2.0-dev.20240908 → 1.2.0-dev.20240922

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 (132) 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/cacheManager.d.ts +2 -2
  7. package/dist/analyzer/cacheManager.js.map +1 -1
  8. package/dist/analyzer/checker.js +31 -156
  9. package/dist/analyzer/checker.js.map +1 -1
  10. package/dist/analyzer/codeFlowEngine.js +21 -3
  11. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  12. package/dist/analyzer/constraintSolver.d.ts +1 -2
  13. package/dist/analyzer/constraintSolver.js +5 -20
  14. package/dist/analyzer/constraintSolver.js.map +1 -1
  15. package/dist/analyzer/constraintTracker.d.ts +0 -4
  16. package/dist/analyzer/constraintTracker.js +0 -21
  17. package/dist/analyzer/constraintTracker.js.map +1 -1
  18. package/dist/analyzer/constructors.js +0 -1
  19. package/dist/analyzer/constructors.js.map +1 -1
  20. package/dist/analyzer/patternMatching.js +3 -1
  21. package/dist/analyzer/patternMatching.js.map +1 -1
  22. package/dist/analyzer/program.js +2 -3
  23. package/dist/analyzer/program.js.map +1 -1
  24. package/dist/analyzer/properties.js.map +1 -1
  25. package/dist/analyzer/protocols.d.ts +1 -2
  26. package/dist/analyzer/protocols.js +2 -2
  27. package/dist/analyzer/protocols.js.map +1 -1
  28. package/dist/analyzer/pythonPathUtils.d.ts +1 -1
  29. package/dist/analyzer/service.d.ts +2 -1
  30. package/dist/analyzer/service.js +56 -42
  31. package/dist/analyzer/service.js.map +1 -1
  32. package/dist/analyzer/sourceMapper.js +8 -4
  33. package/dist/analyzer/sourceMapper.js.map +1 -1
  34. package/dist/analyzer/tuples.d.ts +1 -2
  35. package/dist/analyzer/tuples.js.map +1 -1
  36. package/dist/analyzer/typeEvaluator.js +168 -108
  37. package/dist/analyzer/typeEvaluator.js.map +1 -1
  38. package/dist/analyzer/typeEvaluatorTypes.d.ts +27 -2
  39. package/dist/analyzer/typeEvaluatorTypes.js +62 -1
  40. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  41. package/dist/analyzer/typeGuards.d.ts +3 -12
  42. package/dist/analyzer/typeGuards.js +282 -456
  43. package/dist/analyzer/typeGuards.js.map +1 -1
  44. package/dist/analyzer/typePrinter.d.ts +1 -2
  45. package/dist/analyzer/typePrinter.js +4 -24
  46. package/dist/analyzer/typePrinter.js.map +1 -1
  47. package/dist/analyzer/typeStubWriter.js +12 -1
  48. package/dist/analyzer/typeStubWriter.js.map +1 -1
  49. package/dist/analyzer/typeUtils.d.ts +0 -17
  50. package/dist/analyzer/typeUtils.js +7 -59
  51. package/dist/analyzer/typeUtils.js.map +1 -1
  52. package/dist/analyzer/typedDicts.d.ts +1 -2
  53. package/dist/analyzer/typedDicts.js.map +1 -1
  54. package/dist/analyzer/types.d.ts +1 -0
  55. package/dist/analyzer/types.js +12 -0
  56. package/dist/analyzer/types.js.map +1 -1
  57. package/dist/backgroundAnalysisBase.d.ts +23 -16
  58. package/dist/backgroundAnalysisBase.js +65 -35
  59. package/dist/backgroundAnalysisBase.js.map +1 -1
  60. package/dist/backgroundThreadBase.js +9 -0
  61. package/dist/backgroundThreadBase.js.map +1 -1
  62. package/dist/common/commandLineOptions.d.ts +1 -0
  63. package/dist/common/commandLineOptions.js.map +1 -1
  64. package/dist/common/languageServerInterface.d.ts +1 -1
  65. package/dist/common/uri/uriUtils.d.ts +1 -1
  66. package/dist/common/uri/uriUtils.js +6 -1
  67. package/dist/common/uri/uriUtils.js.map +1 -1
  68. package/dist/languageServerBase.d.ts +2 -2
  69. package/dist/languageServerBase.js +1 -3
  70. package/dist/languageServerBase.js.map +1 -1
  71. package/dist/languageService/analyzerServiceExecutor.d.ts +6 -1
  72. package/dist/languageService/analyzerServiceExecutor.js +8 -7
  73. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  74. package/dist/languageService/fileWatcherDynamicFeature.d.ts +5 -1
  75. package/dist/languageService/fileWatcherDynamicFeature.js +12 -2
  76. package/dist/languageService/fileWatcherDynamicFeature.js.map +1 -1
  77. package/dist/languageService/hoverProvider.d.ts +1 -1
  78. package/dist/languageService/hoverProvider.js +9 -10
  79. package/dist/languageService/hoverProvider.js.map +1 -1
  80. package/dist/localization/localize.d.ts +8 -0
  81. package/dist/localization/localize.js +2 -0
  82. package/dist/localization/localize.js.map +1 -1
  83. package/dist/localization/package.nls.cs.json +157 -153
  84. package/dist/localization/package.nls.de.json +130 -126
  85. package/dist/localization/package.nls.en-us.json +1632 -406
  86. package/dist/localization/package.nls.es.json +153 -149
  87. package/dist/localization/package.nls.fr.json +131 -127
  88. package/dist/localization/package.nls.it.json +145 -141
  89. package/dist/localization/package.nls.ja.json +144 -140
  90. package/dist/localization/package.nls.ko.json +157 -153
  91. package/dist/localization/package.nls.pl.json +180 -176
  92. package/dist/localization/package.nls.pt-br.json +141 -137
  93. package/dist/localization/package.nls.qps-ploc.json +394 -390
  94. package/dist/localization/package.nls.ru.json +172 -168
  95. package/dist/localization/package.nls.tr.json +155 -151
  96. package/dist/localization/package.nls.zh-cn.json +151 -147
  97. package/dist/localization/package.nls.zh-tw.json +135 -131
  98. package/dist/parser/unicode.js +136 -8
  99. package/dist/parser/unicode.js.map +1 -1
  100. package/dist/tests/checker.test.js +9 -0
  101. package/dist/tests/checker.test.js.map +1 -1
  102. package/dist/tests/config.test.js +40 -3
  103. package/dist/tests/config.test.js.map +1 -1
  104. package/dist/tests/envVarUtils.test.js +0 -3
  105. package/dist/tests/envVarUtils.test.js.map +1 -1
  106. package/dist/tests/harness/fourslash/testLanguageService.js +0 -3
  107. package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
  108. package/dist/tests/harness/fourslash/testState.js +2 -5
  109. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  110. package/dist/tests/harness/fourslash/testStateUtils.d.ts +1 -0
  111. package/dist/tests/harness/fourslash/testStateUtils.js +5 -0
  112. package/dist/tests/harness/fourslash/testStateUtils.js.map +1 -1
  113. package/dist/tests/harness/vfs/filesystem.d.ts +3 -2
  114. package/dist/tests/harness/vfs/filesystem.js +6 -3
  115. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  116. package/dist/tests/service.test.js +31 -0
  117. package/dist/tests/service.test.js.map +1 -1
  118. package/dist/tests/typeEvaluator1.test.js +4 -0
  119. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  120. package/dist/tests/typeEvaluator2.test.js +4 -0
  121. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  122. package/dist/tests/typeEvaluator3.test.js +8 -0
  123. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  124. package/dist/tests/typeEvaluator6.test.js +5 -1
  125. package/dist/tests/typeEvaluator6.test.js.map +1 -1
  126. package/dist/tests/typeEvaluator7.test.js +5 -1
  127. package/dist/tests/typeEvaluator7.test.js.map +1 -1
  128. package/dist/tests/typeEvaluator8.test.js +2 -2
  129. package/dist/workspaceFactory.d.ts +2 -20
  130. package/dist/workspaceFactory.js +20 -58
  131. package/dist/workspaceFactory.js.map +1 -1
  132. 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 "...".
@@ -849,68 +822,50 @@ function getIsInstanceClassTypes(evaluator, argType) {
849
822
  });
850
823
  return foundNonClassType ? undefined : classTypeList;
851
824
  }
852
- function isIsinstanceFilterSuperclass(evaluator, varType, concreteVarType, filterType, concreteFilterType, isInstanceCheck) {
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 = narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
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 narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
833
+ return narrowTypeForInstanceOrSubclassInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
906
834
  /* allowIntersections */ true, errorNode);
907
835
  }
908
- // Attempts to narrow a type (make it more constrained) based on a
909
- // 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
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
- // we can conclude that x must be constrained to "Cow".
913
- 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) {
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
- let filterIsSuperclass;
939
- let filterIsSubclass;
940
- if (isTypeIsCheck) {
941
- filterIsSuperclass = evaluator.assignType(filterType, concreteVarType);
942
- 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
+ }
943
921
  }
944
- else {
945
- filterIsSuperclass = isIsinstanceFilterSuperclass(evaluator, varType, concreteVarType, filterType, concreteFilterType, isInstanceCheck);
946
- filterIsSubclass = isIsinstanceFilterSubclass(evaluator, concreteVarType, concreteFilterType, isInstanceCheck);
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
- filterIsSuperclass &&
958
- !types_1.ClassType.isSameGenericClass(concreteVarType, concreteFilterType)) {
959
- 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
+ }
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
- if (evaluator.assignType((0, typeUtils_1.convertToInstance)(convertVarTypeToFree(concreteVarType)), (0, typeUtils_1.convertToInstance)(concreteFilterType),
980
- /* diag */ undefined,
981
- /* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */)) {
982
- // If the variable type is a superclass of the isinstance
983
- // filter, we can narrow the type to the subclass.
984
- let specializedFilterType = filterType;
985
- // Try to retain the type arguments for the filter type. This is
986
- // important because a specialized version of the filter cannot
987
- // be passed to isinstance or issubclass.
988
- if ((0, types_1.isClass)(filterType)) {
989
- if (types_1.ClassType.isSpecialBuiltIn(filterType) || filterType.shared.typeParams.length > 0) {
990
- if (!filterType.priv.isTypeArgExplicit &&
991
- !types_1.ClassType.isSameGenericClass(concreteVarType, filterType)) {
992
- const constraints = new constraintTracker_1.ConstraintTracker();
993
- const unspecializedFilterType = types_1.ClassType.specialize(filterType,
994
- /* typeArg */ undefined);
995
- if ((0, constraintSolver_1.addConstraintsForExpectedType)(evaluator, (0, typeUtils_1.convertToInstance)(unspecializedFilterType), (0, typeUtils_1.convertToInstance)(concreteVarType), constraints,
996
- /* liveTypeVarScopes */ undefined, errorNode.start)) {
997
- specializedFilterType = evaluator.solveAndApplyConstraints(unspecializedFilterType, constraints, {
998
- replaceUnsolved: {
999
- scopeIds: (0, typeUtils_1.getTypeVarScopeIds)(filterType),
1000
- useUnknown: true,
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
- // Don't attempt to narrow in this case.
1013
- if (((_a = concreteVarType.priv) === null || _a === void 0 ? void 0 : _a.literalValue) === undefined &&
1014
- ((_b = concreteFilterType.priv) === null || _b === void 0 ? void 0 : _b.literalValue) === undefined) {
1015
- const intersection = intersectSameClassType(evaluator, concreteVarType, concreteFilterType);
1016
- filteredTypes.push(intersection !== null && intersection !== void 0 ? intersection : varType);
1017
- // Don't attempt to narrow in the negative direction.
1018
- 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
+ }
1019
1022
  }
1020
1023
  }
1021
1024
  else if (allowIntersections &&
@@ -1030,19 +1033,22 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1030
1033
  if ((0, types_1.isTypeVar)(varType) && !(0, types_1.isParamSpec)(varType) && !types_1.TypeVarType.hasConstraints(varType)) {
1031
1034
  newClassType = (0, typeUtils_1.addConditionToType)(newClassType, [{ typeVar: varType, constraintIndex: 0 }]);
1032
1035
  }
1033
- let newClassObjType = types_1.ClassType.cloneAsInstance(newClassType);
1034
- newClassObjType = (0, typeUtils_1.addConditionToType)(newClassObjType, (_c = concreteVarType.props) === null || _c === void 0 ? void 0 : _c.condition);
1035
- // If this is a issubclass check, we do a double conversion from instantiable
1036
- // to instance back to instantiable to make sure that the includeSubclasses flag
1037
- // gets cleared.
1038
- filteredTypes.push(isInstanceCheck ? newClassObjType : types_1.ClassType.cloneAsInstantiable(newClassObjType));
1036
+ filteredTypes.push((0, typeUtils_1.addConditionToType)(newClassType, (_c = concreteVarType.props) === null || _c === void 0 ? void 0 : _c.condition));
1037
+ }
1038
+ }
1039
+ else {
1040
+ if ((0, types_1.isAnyOrUnknown)(varType)) {
1041
+ filteredTypes.push((0, typeUtils_1.addConditionToType)(varType, conditions));
1042
+ }
1043
+ else if ((0, typeUtils_1.derivesFromAnyOrUnknown)(varType) && !(0, types_1.isTypeSame)(concreteVarType, concreteFilterType)) {
1044
+ filteredTypes.push((0, typeUtils_1.addConditionToType)(varType, conditions));
1039
1045
  }
1040
1046
  }
1041
1047
  }
1042
1048
  else if ((0, types_1.isTypeVar)(filterType) && types_1.TypeBase.isInstantiable(filterType)) {
1043
1049
  // Handle the case where the filter type is Type[T] and the unexpanded
1044
1050
  // subtype is some instance type, possibly T.
1045
- if (isInstanceCheck && types_1.TypeBase.isInstance(varType)) {
1051
+ if (types_1.TypeBase.isInstance(varType)) {
1046
1052
  if ((0, types_1.isTypeVar)(varType) && (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(filterType), varType)) {
1047
1053
  // If the unexpanded subtype is T, we can definitively filter
1048
1054
  // in both the positive and negative cases.
@@ -1065,51 +1071,53 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1065
1071
  }
1066
1072
  }
1067
1073
  }
1068
- else if (!isInstanceCheck && types_1.TypeBase.isInstantiable(varType)) {
1069
- if ((0, types_1.isTypeVar)(varType) && (0, types_1.isTypeSame)(filterType, varType)) {
1070
- if (isPositiveTest) {
1071
- filteredTypes.push(varType);
1072
- }
1074
+ }
1075
+ else if ((0, types_1.isFunction)(filterType)) {
1076
+ // Handle an isinstance check against Callable.
1077
+ let isCallable = false;
1078
+ if ((0, types_1.isClass)(concreteVarType)) {
1079
+ if (types_1.TypeBase.isInstantiable(varType)) {
1080
+ isCallable = true;
1073
1081
  }
1074
1082
  else {
1075
- if (isPositiveTest) {
1076
- filteredTypes.push(filterType);
1077
- }
1078
- else {
1079
- filteredTypes.push(varType);
1080
- isClassRelationshipIndeterminate = true;
1081
- }
1083
+ isCallable = !!(0, typeUtils_1.lookUpClassMember)(concreteVarType, '__call__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
1082
1084
  }
1083
1085
  }
1084
- }
1085
- else if ((0, types_1.isFunction)(filterType)) {
1086
- // Handle an isinstance check against Callable.
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
- }
1086
+ if (isCallable) {
1087
+ if (isPositiveTest) {
1088
+ filteredTypes.push((0, typeUtils_1.convertToInstantiable)(varType));
1096
1089
  }
1097
- if (isCallable) {
1098
- if (isPositiveTest) {
1099
- filteredTypes.push(varType);
1100
- }
1101
- else {
1102
- foundSuperclass = true;
1103
- }
1090
+ else {
1091
+ foundSuperclass = true;
1104
1092
  }
1105
- else if (evaluator.assignType(convertVarTypeToFree(concreteVarType), filterType,
1106
- /* diag */ undefined,
1107
- /* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */)) {
1108
- if (isPositiveTest) {
1109
- filteredTypes.push(filterType);
1110
- }
1093
+ }
1094
+ else if (evaluator.assignType(convertVarTypeToFree(concreteVarType), filterType,
1095
+ /* diag */ undefined,
1096
+ /* constraints */ undefined, 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */)) {
1097
+ if (isPositiveTest) {
1098
+ filteredTypes.push((0, typeUtils_1.addConditionToType)(filterType, (_d = concreteVarType.props) === null || _d === void 0 ? void 0 : _d.condition));
1111
1099
  }
1112
1100
  }
1101
+ else if (allowIntersections && isPositiveTest) {
1102
+ // The type appears to not be callable. It's possible that the
1103
+ // two type is a subclass that is callable. We'll synthesize a
1104
+ // new intersection type.
1105
+ const className = `<callable subtype of ${concreteVarType.shared.name}>`;
1106
+ const fileInfo = (0, analyzerNodeInfo_1.getFileInfo)(errorNode);
1107
+ let newClassType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.fileUri, 0 /* ClassTypeFlags.None */, ParseTreeUtils.getTypeSourceId(errorNode),
1108
+ /* declaredMetaclass */ undefined, concreteVarType.shared.effectiveMetaclass, concreteVarType.shared.docString);
1109
+ newClassType.shared.baseClasses = [concreteVarType];
1110
+ (0, typeUtils_1.computeMroLinearization)(newClassType);
1111
+ newClassType = (0, typeUtils_1.addConditionToType)(newClassType, (_e = concreteVarType.props) === null || _e === void 0 ? void 0 : _e.condition);
1112
+ // Add a __call__ method to the new class.
1113
+ const callMethod = types_1.FunctionType.createSynthesizedInstance('__call__');
1114
+ const selfParam = types_1.FunctionParam.create(0 /* ParamCategory.Simple */, types_1.ClassType.cloneAsInstance(newClassType), types_1.FunctionParamFlags.TypeDeclared, 'self');
1115
+ types_1.FunctionType.addParam(callMethod, selfParam);
1116
+ types_1.FunctionType.addDefaultParams(callMethod);
1117
+ callMethod.shared.declaredReturnType = types_1.UnknownType.create();
1118
+ types_1.ClassType.getSymbolTable(newClassType).set('__call__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, callMethod));
1119
+ filteredTypes.push(types_1.ClassType.cloneAsInstance(newClassType));
1120
+ }
1113
1121
  }
1114
1122
  }
1115
1123
  // In the negative case, if one or more of the filters
@@ -1119,101 +1127,58 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1119
1127
  // match, then the original variable type survives the filter.
1120
1128
  if (!isPositiveTest) {
1121
1129
  if (!foundSuperclass || isClassRelationshipIndeterminate) {
1122
- filteredTypes.push(isInstanceCheck ? (0, typeUtils_1.convertToInstantiable)(negativeFallbackType) : negativeFallbackType);
1130
+ filteredTypes.push((0, typeUtils_1.convertToInstantiable)(negativeFallbackType));
1123
1131
  }
1124
1132
  }
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
1133
  return filteredTypes.map((t) => (0, typeUtils_1.convertToInstance)(t));
1132
1134
  };
1133
- // Filters the metaclassType (which is assumed to be a metaclass instance)
1134
- // by the classTypeList and returns the list of types the varType could be
1135
- // after applying the filter.
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));
1135
+ const isFilterTypeCallbackProtocol = (filterType) => {
1136
+ return ((0, types_1.isInstantiableClass)(filterType) &&
1137
+ evaluator.getCallbackProtocolType((0, typeUtils_1.convertToInstance)(filterType)) !== undefined);
1189
1138
  };
1190
1139
  const filterFunctionType = (varType, unexpandedType) => {
1191
1140
  const filteredTypes = [];
1192
1141
  if (isPositiveTest) {
1193
1142
  for (const filterType of filterTypes) {
1194
1143
  const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
1195
- if (evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType))) {
1144
+ if (!isTypeIsCheck && isFilterTypeCallbackProtocol(concreteFilterType)) {
1145
+ filteredTypes.push((0, typeUtils_1.convertToInstance)(varType));
1146
+ }
1147
+ else if (evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType))) {
1196
1148
  // If the filter type is a Callable, use the original type. If the
1197
1149
  // filter type is a callback protocol, use the filter type.
1198
1150
  if ((0, types_1.isFunction)(filterType)) {
1199
- filteredTypes.push(unexpandedType);
1151
+ filteredTypes.push((0, typeUtils_1.convertToInstance)(unexpandedType));
1200
1152
  }
1201
1153
  else {
1202
1154
  filteredTypes.push((0, typeUtils_1.convertToInstance)(filterType));
1203
1155
  }
1204
1156
  }
1157
+ else if (evaluator.assignType((0, typeUtils_1.convertToInstance)(convertVarTypeToFree(concreteFilterType)), varType)) {
1158
+ filteredTypes.push((0, typeUtils_1.convertToInstance)(varType));
1159
+ }
1205
1160
  }
1206
1161
  }
1207
- else if (!filterTypes.some((filterType) => {
1208
- // If the filter type is a runtime checkable protocol class, it can
1209
- // be used in an instance check.
1210
- const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
1211
- if ((0, types_1.isClass)(concreteFilterType) && !types_1.ClassType.isProtocolClass(concreteFilterType)) {
1212
- return false;
1162
+ else {
1163
+ // If one or more filters does not always filter the type,
1164
+ // we can't eliminate the type in the negative case.
1165
+ if (filterTypes.every((filterType) => {
1166
+ const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
1167
+ // If the filter type is a callback protocol, the runtime
1168
+ // isinstance check will filter all objects that have a __call__
1169
+ // method regardless of their signature types.
1170
+ if (!isTypeIsCheck && isFilterTypeCallbackProtocol(concreteFilterType)) {
1171
+ return false;
1172
+ }
1173
+ if ((0, types_1.isFunction)(concreteFilterType) && types_1.FunctionType.isGradualCallableForm(concreteFilterType)) {
1174
+ return false;
1175
+ }
1176
+ const isSubtype = evaluator.assignType((0, typeUtils_1.convertToInstance)(convertVarTypeToFree(concreteFilterType)), varType);
1177
+ const isSupertype = evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType));
1178
+ return !isSubtype || isSupertype;
1179
+ })) {
1180
+ filteredTypes.push((0, typeUtils_1.convertToInstance)(varType));
1213
1181
  }
1214
- return evaluator.assignType(convertVarTypeToFree(varType), (0, typeUtils_1.convertToInstance)(concreteFilterType));
1215
- })) {
1216
- filteredTypes.push(unexpandedType);
1217
1182
  }
1218
1183
  return filteredTypes;
1219
1184
  };
@@ -1236,77 +1201,36 @@ function narrowTypeForIsInstanceInternal(evaluator, type, filterTypes, isInstanc
1236
1201
  // on a constrained TypeVar that they want to filter based on its constrained
1237
1202
  // parts.
1238
1203
  const negativeFallback = (0, typeUtils_1.getTypeCondition)(subtype) ? subtype : unexpandedSubtype;
1239
- const isSubtypeMetaclass = (0, typeUtils_1.isMetaclassInstance)(subtype);
1240
1204
  if (isPositiveTest && (0, types_1.isAnyOrUnknown)(subtype)) {
1241
1205
  // If this is a positive test and the effective type is Any or
1242
1206
  // Unknown, we can assume that the type matches one of the
1243
1207
  // specified types.
1244
- if (isInstanceCheck) {
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
- }
1208
+ anyOrUnknownSubstitutions.push((0, types_1.combineTypes)(filterTypes.map((classType) => (0, typeUtils_1.convertToInstance)(classType))));
1253
1209
  anyOrUnknown.push(subtype);
1254
1210
  return undefined;
1255
1211
  }
1256
- if (isInstanceCheck) {
1257
- if ((0, typeUtils_1.isNoneInstance)(subtype)) {
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
- }
1212
+ if ((0, typeUtils_1.isNoneInstance)(subtype)) {
1213
+ return classListContainsNoneType() === isPositiveTest ? subtype : undefined;
1290
1214
  }
1291
- else {
1292
- if ((0, typeUtils_1.isNoneTypeClass)(subtype)) {
1293
- return classListContainsNoneType() === isPositiveTest ? subtype : undefined;
1294
- }
1295
- if ((0, types_1.isClass)(subtype)) {
1296
- if ((0, types_1.isInstantiableClass)(subtype)) {
1297
- return (0, types_1.combineTypes)(filterClassType(unexpandedSubtype, subtype, (0, typeUtils_1.getTypeCondition)(subtype), negativeFallback));
1298
- }
1299
- else if ((0, typeUtils_1.isMetaclassInstance)(subtype)) {
1300
- return (0, types_1.combineTypes)(filterMetaclassType(subtype, negativeFallback));
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));
1215
+ if ((0, types_1.isModule)(subtype) || ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'ModuleType'))) {
1216
+ // Handle type narrowing for runtime-checkable protocols
1217
+ // when applied to modules.
1218
+ if (isPositiveTest) {
1219
+ const filteredTypes = filterTypes.filter((classType) => {
1220
+ const concreteClassType = evaluator.makeTopLevelTypeVarsConcrete(classType);
1221
+ return (0, types_1.isInstantiableClass)(concreteClassType) && types_1.ClassType.isProtocolClass(concreteClassType);
1222
+ });
1223
+ if (filteredTypes.length > 0) {
1224
+ return (0, typeUtils_1.convertToInstance)((0, types_1.combineTypes)(filteredTypes));
1307
1225
  }
1308
1226
  }
1309
1227
  }
1228
+ if ((0, types_1.isClass)(subtype)) {
1229
+ return (0, types_1.combineTypes)(filterClassType(unexpandedSubtype, types_1.ClassType.cloneAsInstantiable(subtype), (0, typeUtils_1.getTypeCondition)(subtype), negativeFallback));
1230
+ }
1231
+ if ((0, types_1.isFunction)(subtype) || (0, types_1.isOverloaded)(subtype)) {
1232
+ return (0, types_1.combineTypes)(filterFunctionType(subtype, unexpandedSubtype));
1233
+ }
1310
1234
  return isPositiveTest ? undefined : negativeFallback;
1311
1235
  });
1312
1236
  // If the result is Any/Unknown and contains no other subtypes and
@@ -1383,6 +1307,12 @@ function narrowTypeForTupleLength(evaluator, referenceType, lengthValue, isPosit
1383
1307
  return isPositiveTest ? undefined : subtype;
1384
1308
  }
1385
1309
  if (!isPositiveTest) {
1310
+ // If this is an equality check for the minimum length (e.g.
1311
+ // "len(x) == 0"), we can expand the minimum length by one).
1312
+ const minLen = concreteSubtype.priv.tupleTypeArgs.length - 1;
1313
+ if (lengthValue === minLen) {
1314
+ return expandUnboundedTupleElement(concreteSubtype, 1, /* keepUnbounded */ true);
1315
+ }
1386
1316
  return subtype;
1387
1317
  }
1388
1318
  return expandUnboundedTupleElement(concreteSubtype, elementsToAdd, /* keepUnbounded */ false);
@@ -1494,62 +1424,21 @@ function getElementTypeForContainerNarrowing(containerType) {
1494
1424
  return elementType;
1495
1425
  }
1496
1426
  function narrowTypeForContainerElementType(evaluator, referenceType, elementType) {
1497
- let canNarrow = true;
1498
- const elementTypeWithoutLiteral = evaluator.stripLiteralValue(elementType);
1499
- // Look for cases where one or more of the reference subtypes are
1500
- // supertypes of the element types. For example, if the element type
1501
- // is "int | str" and the reference type is "float | bytes", we can
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;
1427
+ return evaluator.mapSubtypesExpandTypeVars(referenceType, /* options */ undefined, (referenceSubtype) => {
1428
+ return (0, typeUtils_1.mapSubtypes)(elementType, (elementSubtype) => {
1429
+ var _a, _b;
1430
+ if ((0, types_1.isAnyOrUnknown)(referenceSubtype)) {
1431
+ return referenceSubtype;
1545
1432
  }
1546
- }
1547
- if (evaluator.assignType(referenceType, elementSubtype)) {
1548
- return elementSubtype;
1549
- }
1550
- return undefined;
1433
+ if (evaluator.assignType(referenceSubtype, elementSubtype)) {
1434
+ return (0, typeUtils_1.stripTypeForm)((0, typeUtils_1.addConditionToType)(elementSubtype, (_a = referenceSubtype.props) === null || _a === void 0 ? void 0 : _a.condition));
1435
+ }
1436
+ if (evaluator.assignType(elementSubtype, referenceSubtype)) {
1437
+ return (0, typeUtils_1.stripTypeForm)((0, typeUtils_1.addConditionToType)(referenceSubtype, (_b = elementSubtype.props) === null || _b === void 0 ? void 0 : _b.condition));
1438
+ }
1439
+ return undefined;
1440
+ });
1551
1441
  });
1552
- return canNarrow ? (0, types_1.combineTypes)([narrowedSupertypes, narrowedSubtypes]) : referenceType;
1553
1442
  }
1554
1443
  // Attempts to narrow a type based on whether it is a TypedDict with
1555
1444
  // a literal key value.
@@ -1786,8 +1675,7 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
1786
1675
  if (types_1.TypeBase.isInstance(concreteSubtype)) {
1787
1676
  return types_1.ClassType.isBuiltIn(concreteSubtype, 'object') ? classType : undefined;
1788
1677
  }
1789
- const isSuperType = isIsinstanceFilterSuperclass(evaluator, subtype, concreteSubtype, classType, classType,
1790
- /* isInstanceCheck */ false);
1678
+ const isSuperType = isFilterSuperclass(subtype, concreteSubtype, classType, classType);
1791
1679
  if (!classType.priv.includeSubclasses) {
1792
1680
  // Handle the case where the LHS and RHS operands are specific
1793
1681
  // classes, as opposed to types that represent classes and their
@@ -1795,11 +1683,10 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
1795
1683
  if (!concreteSubtype.priv.includeSubclasses) {
1796
1684
  return types_1.ClassType.isSameGenericClass(concreteSubtype, classType) ? classType : undefined;
1797
1685
  }
1798
- const isSubType = isIsinstanceFilterSubclass(evaluator, concreteSubtype, classType,
1799
- /* isInstanceCheck */ false);
1800
1686
  if (isSuperType) {
1801
1687
  return classType;
1802
1688
  }
1689
+ const isSubType = types_1.ClassType.isDerivedFrom(classType, concreteSubtype);
1803
1690
  if (isSubType) {
1804
1691
  return (0, typeUtils_1.addConditionToType)(classType, (0, typeUtils_1.getTypeCondition)(concreteSubtype));
1805
1692
  }
@@ -1820,6 +1707,27 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
1820
1707
  return subtype;
1821
1708
  });
1822
1709
  }
1710
+ function isFilterSuperclass(varType, concreteVarType, filterType, concreteFilterType) {
1711
+ if ((0, types_1.isTypeVar)(filterType) || concreteFilterType.priv.literalValue !== undefined) {
1712
+ return (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(filterType), varType);
1713
+ }
1714
+ // If the filter type represents all possible subclasses
1715
+ // of a type, we can't make any statements about its superclass
1716
+ // relationship with concreteVarType.
1717
+ if (concreteFilterType.priv.includeSubclasses) {
1718
+ return false;
1719
+ }
1720
+ if (types_1.ClassType.isDerivedFrom(concreteVarType, concreteFilterType)) {
1721
+ return true;
1722
+ }
1723
+ // Handle the special case where the variable type is a TypedDict and
1724
+ // we're filtering against 'dict'. TypedDict isn't derived from dict,
1725
+ // but at runtime, isinstance returns True.
1726
+ if (types_1.ClassType.isBuiltIn(concreteFilterType, 'dict') && types_1.ClassType.isTypedDictClass(concreteVarType)) {
1727
+ return true;
1728
+ }
1729
+ return false;
1730
+ }
1823
1731
  // Attempts to narrow a type (make it more constrained) based on a comparison
1824
1732
  // (equal or not equal) to a literal value. It also handles "is" or "is not"
1825
1733
  // operators if isIsOperator is true.
@@ -1894,86 +1802,4 @@ function enumerateLiteralsForType(evaluator, type) {
1894
1802
  }
1895
1803
  return undefined;
1896
1804
  }
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
1805
  //# sourceMappingURL=typeGuards.js.map