@zzzen/pyright-internal 1.2.0-dev.20230611 → 1.2.0-dev.20230618

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 (58) hide show
  1. package/dist/analyzer/checker.js +11 -3
  2. package/dist/analyzer/checker.js.map +1 -1
  3. package/dist/analyzer/constraintSolver.js +4 -1
  4. package/dist/analyzer/constraintSolver.js.map +1 -1
  5. package/dist/analyzer/constructors.js +3 -2
  6. package/dist/analyzer/constructors.js.map +1 -1
  7. package/dist/analyzer/dataClasses.js +1 -1
  8. package/dist/analyzer/dataClasses.js.map +1 -1
  9. package/dist/analyzer/program.d.ts +2 -2
  10. package/dist/analyzer/program.js +2 -25
  11. package/dist/analyzer/program.js.map +1 -1
  12. package/dist/analyzer/protocols.d.ts +1 -1
  13. package/dist/analyzer/protocols.js +47 -26
  14. package/dist/analyzer/protocols.js.map +1 -1
  15. package/dist/analyzer/service.d.ts +2 -2
  16. package/dist/analyzer/service.js +2 -7
  17. package/dist/analyzer/service.js.map +1 -1
  18. package/dist/analyzer/typeEvaluator.js +216 -82
  19. package/dist/analyzer/typeEvaluator.js.map +1 -1
  20. package/dist/analyzer/typeEvaluatorTypes.d.ts +3 -2
  21. package/dist/analyzer/typeEvaluatorTypes.js +2 -0
  22. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  23. package/dist/analyzer/typeGuards.js +1 -1
  24. package/dist/analyzer/typeGuards.js.map +1 -1
  25. package/dist/analyzer/typeUtils.d.ts +10 -11
  26. package/dist/analyzer/typeUtils.js +57 -44
  27. package/dist/analyzer/typeUtils.js.map +1 -1
  28. package/dist/analyzer/types.d.ts +2 -0
  29. package/dist/analyzer/types.js +7 -3
  30. package/dist/analyzer/types.js.map +1 -1
  31. package/dist/common/extensibility.d.ts +6 -2
  32. package/dist/common/extensibility.js.map +1 -1
  33. package/dist/common/workspaceEditUtils.d.ts +3 -3
  34. package/dist/common/workspaceEditUtils.js +23 -13
  35. package/dist/common/workspaceEditUtils.js.map +1 -1
  36. package/dist/languageServerBase.d.ts +48 -0
  37. package/dist/languageServerBase.js +3 -3
  38. package/dist/languageServerBase.js.map +1 -1
  39. package/dist/languageService/completionProvider.js +2 -0
  40. package/dist/languageService/completionProvider.js.map +1 -1
  41. package/dist/localization/localize.d.ts +1 -0
  42. package/dist/localization/localize.js +1 -0
  43. package/dist/localization/localize.js.map +1 -1
  44. package/dist/localization/package.nls.en-us.json +1 -0
  45. package/dist/parser/parser.js +5 -2
  46. package/dist/parser/parser.js.map +1 -1
  47. package/dist/pyright.js +1 -1
  48. package/dist/pyright.js.map +1 -1
  49. package/dist/tests/typeEvaluator1.test.js +1 -1
  50. package/dist/tests/typeEvaluator2.test.js +17 -1
  51. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  52. package/dist/tests/typeEvaluator3.test.js +5 -1
  53. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  54. package/dist/tests/typeEvaluator4.test.js +1 -1
  55. package/dist/tests/typeEvaluator5.test.js +1 -1
  56. package/dist/tests/workspaceEditUtils.test.js +2 -3
  57. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  58. package/package.json +1 -1
@@ -659,7 +659,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
659
659
  if (!typeResult.isIncomplete && !typeResult.expectedTypeDiagAddendum) {
660
660
  const diag = new diagnostic_1.DiagnosticAddendum();
661
661
  // Make sure the resulting type is assignable to the expected type.
662
- if (!assignType(inferenceContext.expectedType, typeResult.type, diag)) {
662
+ if (!assignType(inferenceContext.expectedType, typeResult.type, diag,
663
+ /* destTypeVarContext */ undefined,
664
+ /* srcTypeVarContext */ undefined, 512 /* IgnoreTypeVarScope */)) {
663
665
  typeResult.typeErrors = true;
664
666
  typeResult.expectedTypeDiagAddendum = diag;
665
667
  diag.addTextRange(node);
@@ -984,6 +986,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
984
986
  flags |= 2 /* DoNotSpecialize */;
985
987
  }
986
988
  const decoratorTypeResult = getTypeOfExpression(node.expression, flags);
989
+ // Special-case typing.type_check_only. It's used in many stdlib
990
+ // functions, and pyright treats it as a no-op, so don't waste
991
+ // time evaluating it.
992
+ if ((0, types_1.isFunction)(decoratorTypeResult.type) &&
993
+ decoratorTypeResult.type.details.builtInName === 'type_check_only') {
994
+ return functionOrClassType;
995
+ }
987
996
  // Special-case the combination of a classmethod decorator applied
988
997
  // to a property. This is allowed in Python 3.9, but it's not reflected
989
998
  // in the builtins.pyi stub for classmethod.
@@ -3097,7 +3106,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3097
3106
  }
3098
3107
  // Is this a generic class that needs to be specialized?
3099
3108
  if ((0, types_1.isInstantiableClass)(type)) {
3100
- if ((flags & 128 /* ExpectingType */) !== 0) {
3109
+ if ((flags & 128 /* ExpectingType */) !== 0 && (flags & 512 /* AllowMissingTypeArgs */) === 0) {
3101
3110
  if (!type.typeAliasInfo && (0, typeUtils_1.requiresTypeArguments)(type)) {
3102
3111
  if (!type.typeArguments || !type.isTypeArgumentExplicit) {
3103
3112
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
@@ -5551,9 +5560,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5551
5560
  return types_1.NoneType.createInstance();
5552
5561
  }
5553
5562
  function getTypeOfSuperCall(node) {
5563
+ var _a;
5554
5564
  if (node.arguments.length > 2) {
5555
5565
  addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
5556
5566
  }
5567
+ const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
5568
+ const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
5557
5569
  // Determine which class the "super" call is applied to. If
5558
5570
  // there is no first argument, then the class is implicit.
5559
5571
  let targetClassType;
@@ -5565,10 +5577,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5565
5577
  }
5566
5578
  }
5567
5579
  else {
5568
- const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
5569
- if (enclosingClass) {
5570
- const classTypeInfo = getTypeOfClass(enclosingClass);
5571
- targetClassType = classTypeInfo ? classTypeInfo.classType : types_1.UnknownType.create();
5580
+ if (enclosingClassType) {
5581
+ targetClassType = enclosingClassType !== null && enclosingClassType !== void 0 ? enclosingClassType : types_1.UnknownType.create();
5572
5582
  }
5573
5583
  else {
5574
5584
  addError(localize_1.Localizer.Diagnostic.superCallZeroArgForm(), node.leftExpression);
@@ -5608,33 +5618,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5608
5618
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.superCallSecondArg().format({ type: printType(targetClassType) }), node.arguments[1].valueExpression);
5609
5619
  }
5610
5620
  }
5611
- else {
5621
+ else if (enclosingClassType) {
5622
+ bindToType = types_1.ClassType.cloneAsInstance(enclosingClassType);
5623
+ // Get the type from the self or cls parameter if it is explicitly annotated.
5624
+ // If it's a TypeVar, change the bindToType into a conditional type.
5612
5625
  const enclosingMethod = ParseTreeUtils.getEnclosingFunction(node);
5613
5626
  let implicitBindToType;
5614
- // Get the type from the self or cls parameter if it is explicitly annotated.
5615
5627
  if (enclosingMethod) {
5616
5628
  const methodTypeInfo = getTypeOfFunction(enclosingMethod);
5617
5629
  if (methodTypeInfo) {
5618
5630
  const methodType = methodTypeInfo.functionType;
5619
- if (types_1.FunctionType.isClassMethod(methodType)) {
5631
+ if (types_1.FunctionType.isClassMethod(methodType) ||
5632
+ types_1.FunctionType.isConstructorMethod(methodType) ||
5633
+ types_1.FunctionType.isInstanceMethod(methodType)) {
5620
5634
  if (methodType.details.parameters.length > 0 &&
5621
5635
  methodType.details.parameters[0].hasDeclaredType) {
5622
5636
  implicitBindToType = makeTopLevelTypeVarsConcrete(methodType.details.parameters[0].type);
5623
5637
  }
5624
5638
  }
5625
- else if (types_1.FunctionType.isInstanceMethod(methodType)) {
5626
- if (methodType.details.parameters.length > 0 &&
5627
- methodType.details.parameters[0].hasDeclaredType) {
5628
- implicitBindToType = makeTopLevelTypeVarsConcrete((0, typeUtils_1.convertToInstantiable)(methodType.details.parameters[0].type));
5629
- }
5630
- }
5631
5639
  }
5632
5640
  }
5633
- if (implicitBindToType && (0, types_1.isInstantiableClass)(implicitBindToType)) {
5634
- bindToType = implicitBindToType;
5635
- }
5636
- else if ((0, types_1.isInstantiableClass)(targetClassType)) {
5637
- bindToType = targetClassType;
5641
+ if (bindToType && implicitBindToType) {
5642
+ bindToType = (0, typeUtils_1.addConditionToType)(bindToType, (0, typeUtils_1.getTypeCondition)(implicitBindToType));
5638
5643
  }
5639
5644
  }
5640
5645
  // Determine whether super() should return an instance of the class or
@@ -5659,7 +5664,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5659
5664
  const parentNode = node.parent;
5660
5665
  if (parentNode.nodeType === 35 /* MemberAccess */) {
5661
5666
  const memberName = parentNode.memberName.value;
5662
- const lookupResults = (0, typeUtils_1.lookUpClassMember)(targetClassType, memberName, 1 /* SkipOriginalClass */);
5667
+ const effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
5668
+ const lookupResults = bindToType
5669
+ ? (0, typeUtils_1.lookUpClassMember)(bindToType, memberName, 0 /* Default */, effectiveTargetClass)
5670
+ : undefined;
5663
5671
  if (lookupResults && (0, types_1.isInstantiableClass)(lookupResults.classType)) {
5664
5672
  return {
5665
5673
  type: resultIsInstance
@@ -5867,6 +5875,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5867
5875
  if (matches.length < 2) {
5868
5876
  return matches;
5869
5877
  }
5878
+ // If the relevance of some matches differs, filter out the ones that
5879
+ // are lower relevance. This favors *args parameters in cases where
5880
+ // a *args argument is used.
5881
+ if (matches[0].matchResults.relevance !== matches[matches.length - 1].matchResults.relevance) {
5882
+ matches = matches.filter((m) => m.matchResults.relevance === matches[0].matchResults.relevance);
5883
+ if (matches.length < 2) {
5884
+ return matches;
5885
+ }
5886
+ }
5870
5887
  // If all of the return types match, select the first one.
5871
5888
  if ((0, typeUtils_1.areTypesSame)(matches.map((match) => match.returnType), { treatAnySameAsUnknown: true })) {
5872
5889
  return [matches[0]];
@@ -5875,6 +5892,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5875
5892
  if (!firstArgResults) {
5876
5893
  return matches;
5877
5894
  }
5895
+ let foundAmbiguousAnyArg = false;
5878
5896
  for (let i = 0; i < firstArgResults.length; i++) {
5879
5897
  // If the arg is Any or Unknown, see if the corresponding
5880
5898
  // parameter types differ in any way.
@@ -5883,10 +5901,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5883
5901
  ? match.matchResults.argParams[i].paramType
5884
5902
  : types_1.UnknownType.create());
5885
5903
  if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
5886
- return matches;
5904
+ foundAmbiguousAnyArg = true;
5887
5905
  }
5888
5906
  }
5889
5907
  }
5908
+ // If the first overload has a different number of effective arguments
5909
+ // than latter overloads, don't filter any of them. This typically means
5910
+ // that one of the arguments is an unpacked iterator, and it maps to
5911
+ // an indeterminate number of parameters, which means that the overload
5912
+ // selection is ambiguous.
5913
+ if (foundAmbiguousAnyArg || matches.some((match) => match.argResults.length !== firstArgResults.length)) {
5914
+ return matches;
5915
+ }
5890
5916
  return [matches[0]];
5891
5917
  }
5892
5918
  function getBestOverloadForArguments(errorNode, typeResult, argList) {
@@ -6993,6 +7019,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6993
7019
  unpackedDictionaryArgType = types_1.UnknownType.create();
6994
7020
  }
6995
7021
  }
7022
+ if (paramDetails.kwargsIndex !== undefined && unpackedDictionaryArgType) {
7023
+ const paramType = paramDetails.params[paramDetails.kwargsIndex].type;
7024
+ validateArgTypeParams.push({
7025
+ paramCategory: 0 /* Simple */,
7026
+ paramType,
7027
+ requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7028
+ argType: unpackedDictionaryArgType,
7029
+ argument: argList[argIndex],
7030
+ errorNode: argList[argIndex].valueExpression || errorNode,
7031
+ paramName: paramDetails.params[paramDetails.kwargsIndex].param.name,
7032
+ });
7033
+ }
6996
7034
  if (!isValidMappingType) {
6997
7035
  if (!isDiagnosticSuppressedForNode(errorNode)) {
6998
7036
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet
@@ -7265,7 +7303,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7265
7303
  // Special-case the builtin isinstance and issubclass functions.
7266
7304
  if (['isinstance', 'issubclass'].some((name) => name === typeResult.type.details.builtInName) &&
7267
7305
  validateArgTypeParams.length === 2) {
7268
- validateArgTypeParams[1].expectingType = true;
7306
+ validateArgTypeParams[1].isinstanceParam = true;
7269
7307
  }
7270
7308
  return {
7271
7309
  overload: typeResult.type,
@@ -7324,13 +7362,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7324
7362
  // the expected type if possible.
7325
7363
  // Determine which type arguments are needed to match the expected type.
7326
7364
  if ((0, types_1.isClassInstance)(effectiveReturnType)) {
7327
- // If the return type is a class and the expected type is a union that contains
7328
- // that class, see if we can eliminate the other subtypes in the union.
7365
+ // If the return type is a class and the expected type is a union
7366
+ // that is type compatible with that class, filter the subtypes in
7367
+ // the union to see if we can find one that is potentially compatible.
7329
7368
  if ((0, types_1.isUnion)(effectiveExpectedType)) {
7330
7369
  const filteredType = (0, typeUtils_1.mapSubtypes)(effectiveExpectedType, (subtype) => {
7331
- return (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isSameGenericClass(effectiveReturnType, subtype)
7332
- ? subtype
7333
- : undefined;
7370
+ if (!(0, types_1.isClassInstance)(subtype) || subtype.details.typeParameters.length === 0) {
7371
+ return undefined;
7372
+ }
7373
+ if (types_1.ClassType.isProtocolClass(subtype) ||
7374
+ subtype.details.mro.some((mroClass) => {
7375
+ return ((0, types_1.isClassInstance)(mroClass) &&
7376
+ mroClass.details.typeParameters.length > 0 &&
7377
+ types_1.ClassType.isSameGenericClass(effectiveReturnType, mroClass));
7378
+ })) {
7379
+ return subtype;
7380
+ }
7381
+ return undefined;
7334
7382
  });
7335
7383
  if ((0, types_1.isClassInstance)(filteredType)) {
7336
7384
  effectiveExpectedType = filteredType;
@@ -7849,8 +7897,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7849
7897
  argType = argParam.argType;
7850
7898
  }
7851
7899
  else {
7852
- const flags = argParam.expectingType
7853
- ? 8 /* EvaluateStringLiteralAsType */ |
7900
+ const flags = argParam.isinstanceParam
7901
+ ? 512 /* AllowMissingTypeArgs */ |
7902
+ 8 /* EvaluateStringLiteralAsType */ |
7854
7903
  32 /* DisallowParamSpec */ |
7855
7904
  64 /* DisallowTypeVarTuple */
7856
7905
  : 0 /* None */;
@@ -7888,7 +7937,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7888
7937
  if (argParam.argType) {
7889
7938
  argType = argParam.argType;
7890
7939
  }
7891
- else if (argParam.expectingType && !argParam.argument.typeResult && argParam.argument.valueExpression) {
7940
+ else if (argParam.isinstanceParam && !argParam.argument.typeResult && argParam.argument.valueExpression) {
7892
7941
  const argTypeResult = getTypeOfExpression(argParam.argument.valueExpression, 8 /* EvaluateStringLiteralAsType */ |
7893
7942
  32 /* DisallowParamSpec */ |
7894
7943
  64 /* DisallowTypeVarTuple */);
@@ -8714,6 +8763,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8714
8763
  // Infer the key and value types if possible.
8715
8764
  if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
8716
8765
  /* forceStrictInference */ true,
8766
+ /* isValueTypeInvariant */ true,
8717
8767
  /* expectedKeyType */ undefined,
8718
8768
  /* expectedValueType */ undefined, expectedTypedDictEntries, expectedDiagAddendum)) {
8719
8769
  isIncomplete = true;
@@ -8746,17 +8796,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8746
8796
  }
8747
8797
  const expectedKeyType = specializedDict.typeArguments[0];
8748
8798
  const expectedValueType = specializedDict.typeArguments[1];
8749
- // Infer the key and value types if possible.
8750
- if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
8751
- /* forceStrictInference */ true, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
8752
- isIncomplete = true;
8753
- }
8754
8799
  // Dict and MutableMapping types have invariant value types, so they
8755
8800
  // cannot be narrowed further. Other super-types like Mapping, Collection,
8756
8801
  // and Iterable use covariant value types, so they can be narrowed.
8757
8802
  const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
8758
8803
  (types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
8759
8804
  types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'MutableMapping'));
8805
+ // Infer the key and value types if possible.
8806
+ if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
8807
+ /* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
8808
+ isIncomplete = true;
8809
+ }
8760
8810
  const specializedKeyType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedKeyType), keyTypes.map((result) => result.type),
8761
8811
  /* isNarrowable */ false);
8762
8812
  const specializedValueType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedValueType), valueTypes.map((result) => result.type), !isValueTypeInvariant);
@@ -8778,7 +8828,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8778
8828
  let isIncomplete = false;
8779
8829
  // Infer the key and value types if possible.
8780
8830
  if (getKeyAndValueTypesFromDictionary(node, keyTypeResults, valueTypeResults,
8781
- /* forceStrictInference */ hasExpectedType)) {
8831
+ /* forceStrictInference */ hasExpectedType,
8832
+ /* isValueTypeInvariant */ false)) {
8782
8833
  isIncomplete = true;
8783
8834
  }
8784
8835
  // Strip any literal values.
@@ -8816,11 +8867,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8816
8867
  }
8817
8868
  return { type, isIncomplete };
8818
8869
  }
8819
- function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
8870
+ function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, isValueTypeInvariant, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
8820
8871
  let isIncomplete = false;
8821
8872
  // Infer the key and value types if possible.
8822
8873
  node.entries.forEach((entryNode, index) => {
8823
- var _a;
8874
+ var _a, _b, _c;
8824
8875
  let addUnknown = true;
8825
8876
  if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
8826
8877
  const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
@@ -8836,19 +8887,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8836
8887
  expectedDiagAddendum.addAddendum(keyTypeResult.expectedTypeDiagAddendum);
8837
8888
  }
8838
8889
  let valueTypeResult;
8890
+ let entryInferenceContext;
8839
8891
  if (expectedTypedDictEntries &&
8840
8892
  (0, types_1.isClassInstance)(keyType) &&
8841
8893
  types_1.ClassType.isBuiltIn(keyType, 'str') &&
8842
8894
  (0, typeUtils_1.isLiteralType)(keyType) &&
8843
8895
  expectedTypedDictEntries.has(keyType.literalValue)) {
8844
8896
  const effectiveValueType = expectedTypedDictEntries.get(keyType.literalValue).valueType;
8897
+ entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
8845
8898
  valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
8846
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
8899
+ /* flags */ undefined, entryInferenceContext);
8847
8900
  }
8848
8901
  else {
8849
8902
  const effectiveValueType = expectedValueType !== null && expectedValueType !== void 0 ? expectedValueType : (forceStrictInference ? types_1.NeverType.createNever() : undefined);
8903
+ entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
8850
8904
  valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
8851
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
8905
+ /* flags */ undefined, entryInferenceContext);
8906
+ }
8907
+ if (entryInferenceContext && !valueTypeResult.typeErrors) {
8908
+ valueTypeResult.type =
8909
+ (_a = inferTypeArgFromExpectedEntryType(entryInferenceContext, [valueTypeResult.type], !isValueTypeInvariant)) !== null && _a !== void 0 ? _a : valueTypeResult.type;
8852
8910
  }
8853
8911
  if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
8854
8912
  expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
@@ -8871,8 +8929,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8871
8929
  /* isTypeArgumentExplicit */ true));
8872
8930
  }
8873
8931
  }
8932
+ const entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(expectedType);
8874
8933
  const unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
8875
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedType));
8934
+ /* flags */ undefined, entryInferenceContext);
8935
+ if (entryInferenceContext && !unexpandedTypeResult.typeErrors) {
8936
+ unexpandedTypeResult.type =
8937
+ (_b = inferTypeArgFromExpectedEntryType(entryInferenceContext, [unexpandedTypeResult.type], !isValueTypeInvariant)) !== null && _b !== void 0 ? _b : unexpandedTypeResult.type;
8938
+ }
8876
8939
  if (unexpandedTypeResult.isIncomplete) {
8877
8940
  isIncomplete = true;
8878
8941
  }
@@ -8927,7 +8990,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8927
8990
  }
8928
8991
  // The result should be a tuple.
8929
8992
  if ((0, types_1.isClassInstance)(dictEntryType) && (0, typeUtils_1.isTupleClass)(dictEntryType)) {
8930
- const typeArgs = (_a = dictEntryType.tupleTypeArguments) === null || _a === void 0 ? void 0 : _a.map((t) => t.type);
8993
+ const typeArgs = (_c = dictEntryType.tupleTypeArguments) === null || _c === void 0 ? void 0 : _c.map((t) => t.type);
8931
8994
  if (typeArgs && typeArgs.length === 2) {
8932
8995
  if (forceStrictInference || index < maxEntriesToUseForInference) {
8933
8996
  keyTypes.push({ node: entryNode, type: typeArgs[0] });
@@ -9122,7 +9185,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9122
9185
  if ((0, types_1.isAnyOrUnknown)(inferenceContext.expectedType)) {
9123
9186
  return inferenceContext.expectedType;
9124
9187
  }
9125
- const typeVarContext = new typeVarContext_1.TypeVarContext();
9188
+ const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(inferenceContext.expectedType));
9126
9189
  const expectedType = inferenceContext.expectedType;
9127
9190
  let isCompatible = true;
9128
9191
  entryTypes.forEach((entryType) => {
@@ -9139,7 +9202,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9139
9202
  ? combinedTypes
9140
9203
  : stripLiteralValue(combinedTypes);
9141
9204
  }
9142
- return (0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext, { applyInScopePlaceholders: true });
9205
+ return (0, typeUtils_1.mapSubtypes)((0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext, { applyInScopePlaceholders: true }), (subtype) => {
9206
+ if (entryTypes.length !== 1) {
9207
+ return subtype;
9208
+ }
9209
+ const entryType = entryTypes[0];
9210
+ // If the entry type is a TypedDict instance, clone it with additional information.
9211
+ if ((0, types_1.isTypeSame)(subtype, entryType, { ignoreTypedDictNarrowEntries: true }) &&
9212
+ (0, types_1.isClass)(subtype) &&
9213
+ (0, types_1.isClass)(entryType) &&
9214
+ types_1.ClassType.isTypedDictClass(entryType)) {
9215
+ return types_1.ClassType.cloneForNarrowedTypedDictEntries(subtype, entryType.typedDictNarrowedEntries);
9216
+ }
9217
+ return subtype;
9218
+ });
9143
9219
  }
9144
9220
  function getTypeOfYield(node) {
9145
9221
  let expectedYieldType;
@@ -12004,10 +12080,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12004
12080
  inferredParamType = (0, types_1.combineTypes)([defaultValueType, types_1.UnknownType.create()]);
12005
12081
  }
12006
12082
  else {
12007
- // Do not infer certain types like tuple because it's likely to be
12008
- // more restrictive (narrower) than intended.
12009
- if (!(0, types_1.isClassInstance)(defaultValueType) ||
12010
- !types_1.ClassType.isBuiltIn(defaultValueType, ['tuple', 'list', 'set', 'dict'])) {
12083
+ let skipInference = false;
12084
+ if ((0, types_1.isFunction)(defaultValueType) || (0, types_1.isOverloadedFunction)(defaultValueType)) {
12085
+ // Do not infer parameter types that use a lambda or another function as a
12086
+ // default value. We're likely to generate false positives in this case.
12087
+ // It's not clear whether parameters should be positional-only or not.
12088
+ skipInference = true;
12089
+ }
12090
+ else if ((0, types_1.isClassInstance)(defaultValueType) &&
12091
+ types_1.ClassType.isBuiltIn(defaultValueType, ['tuple', 'list', 'set', 'dict'])) {
12092
+ // Do not infer certain types like tuple because it's likely to be
12093
+ // more restrictive (narrower) than intended.
12094
+ skipInference = true;
12095
+ }
12096
+ if (!skipInference) {
12011
12097
  inferredParamType = stripLiteralValue(defaultValueType);
12012
12098
  }
12013
12099
  }
@@ -15563,6 +15649,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15563
15649
  effectiveFlags &= ~8 /* SkipSolveTypeVars */;
15564
15650
  prevSrcType = curSrcType;
15565
15651
  }
15652
+ // If we're enforcing invariance, literal types must match as well.
15653
+ if ((flags & 1 /* EnforceInvariance */) !== 0) {
15654
+ const srcIsLiteral = srcType.literalValue !== undefined;
15655
+ const destIsLiteral = destType.literalValue !== undefined;
15656
+ if (srcIsLiteral !== destIsLiteral) {
15657
+ return false;
15658
+ }
15659
+ }
15566
15660
  if (destType.typeArguments) {
15567
15661
  // If the dest type is specialized, make sure the specialized source
15568
15662
  // type arguments are assignable to the dest type arguments.
@@ -16625,9 +16719,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16625
16719
  specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
16626
16720
  if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
16627
16721
  reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16628
- /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
16629
- 512 /* IgnoreTypeVarScope */ |
16630
- 128 /* RetainLiteralsForTypeVar */, recursionCount);
16722
+ /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
16631
16723
  specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext);
16632
16724
  }
16633
16725
  }
@@ -16635,9 +16727,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16635
16727
  specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
16636
16728
  if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
16637
16729
  reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16638
- /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
16639
- 512 /* IgnoreTypeVarScope */ |
16640
- 128 /* RetainLiteralsForTypeVar */, recursionCount);
16730
+ /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
16641
16731
  specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext);
16642
16732
  }
16643
16733
  if (reverseMatchingFailed) {
@@ -17103,9 +17193,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17103
17193
  });
17104
17194
  const srcParamSpec = effectiveSrcType.details.paramSpec;
17105
17195
  const destParamSpec = effectiveDestType.details.paramSpec;
17106
- const targetTypeVarContext = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? destTypeVarContext : srcTypeVarContext;
17107
- if (targetTypeVarContext.hasSolveForScope(destParamSpec.scopeId)) {
17108
- // Synthesize a function based on the remaining parameters.
17196
+ // If there are remaining parameters and the source and dest do not contain
17197
+ // the same ParamSpec, synthesize a function for the remaining parameters.
17198
+ if (remainingParams.length > 0 ||
17199
+ !srcParamSpec ||
17200
+ !(0, types_1.isTypeSame)(srcParamSpec, destParamSpec, { ignoreTypeFlags: true })) {
17109
17201
  const remainingFunction = types_1.FunctionType.createInstance('', '', '', effectiveSrcType.details.flags | 64 /* SynthesizedMethod */, effectiveSrcType.details.docString);
17110
17202
  remainingFunction.details.typeVarScopeId = effectiveSrcType.details.typeVarScopeId;
17111
17203
  remainingParams.forEach((param) => {
@@ -17114,28 +17206,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17114
17206
  remainingFunction.details.paramSpec = srcParamSpec
17115
17207
  ? (0, typeUtils_1.convertToInstance)(srcParamSpec)
17116
17208
  : undefined;
17117
- if (!(0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, destParamSpec, remainingFunction,
17118
- /* diag */ undefined, targetTypeVarContext)) {
17209
+ if (!assignType(destParamSpec, remainingFunction,
17210
+ /* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags)) {
17119
17211
  // If we couldn't assign the function to the ParamSpec, see if we can
17120
17212
  // assign only the ParamSpec. This is possible if there were no
17121
17213
  // remaining parameters.
17122
17214
  if (remainingParams.length > 0 ||
17123
17215
  !srcParamSpec ||
17124
- !(0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, destParamSpec, (0, typeUtils_1.convertToInstance)(srcParamSpec),
17125
- /* diag */ undefined, targetTypeVarContext)) {
17216
+ !assignType(destParamSpec, (0, typeUtils_1.convertToInstance)(srcParamSpec),
17217
+ /* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags)) {
17126
17218
  canAssign = false;
17127
17219
  }
17128
17220
  }
17129
17221
  }
17130
- else {
17131
- // If there are any remaining parameters or the source doesn't include the
17132
- // dest param spec itself, it is not assignable in this case.
17133
- if (!srcParamSpec ||
17134
- !(0, types_1.isTypeSame)(srcParamSpec, destParamSpec, { ignoreTypeFlags: true }) ||
17135
- remainingParams.length > 0) {
17136
- canAssign = false;
17137
- }
17138
- }
17139
17222
  }
17140
17223
  }
17141
17224
  // Match the return parameter.
@@ -17293,7 +17376,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17293
17376
  }
17294
17377
  return narrowedType;
17295
17378
  }
17296
- function validateOverrideMethod(baseMethod, overrideMethod, diag, enforceParamNames = true) {
17379
+ function validateOverrideMethod(baseMethod, overrideMethod, baseClass, diag, enforceParamNames = true) {
17297
17380
  // If we're overriding a non-method with a method, report it as an error.
17298
17381
  // This occurs when a non-property overrides a property.
17299
17382
  if (!(0, types_1.isFunction)(baseMethod) && !(0, types_1.isOverloadedFunction)(baseMethod)) {
@@ -17319,17 +17402,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17319
17402
  // For a non-overloaded method overriding an overloaded method, the
17320
17403
  // override must match all of the overloads.
17321
17404
  if ((0, types_1.isFunction)(overrideMethod)) {
17322
- return types_1.OverloadedFunctionType.getOverloads(baseMethod).every((overload) => validateOverrideMethodInternal(overload, overrideMethod, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), enforceParamNames));
17405
+ return types_1.OverloadedFunctionType.getOverloads(baseMethod).every((overload) => {
17406
+ // If the override isn't applicable for this base class, skip the check.
17407
+ if (baseClass && !isOverrideMethodApplicable(overload, baseClass)) {
17408
+ return true;
17409
+ }
17410
+ return validateOverrideMethodInternal(overload, overrideMethod, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), enforceParamNames);
17411
+ });
17323
17412
  }
17324
17413
  // For an overloaded method overriding an overloaded method, the overrides
17325
17414
  // must all match and be in the correct order. It is OK if the base method
17326
17415
  // has additional overloads that are not present in the override.
17327
17416
  let previousMatchIndex = -1;
17328
17417
  let overrideOverloadIndex = 0;
17418
+ const baseOverloads = types_1.OverloadedFunctionType.getOverloads(baseMethod);
17329
17419
  for (const overrideOverload of types_1.OverloadedFunctionType.getOverloads(overrideMethod)) {
17330
- const matchIndex = types_1.OverloadedFunctionType.getOverloads(baseMethod).findIndex((baseOverload) => {
17420
+ const matchIndex = baseOverloads.findIndex((baseOverload) => {
17421
+ // If the override isn't applicable for this base class, skip the check.
17422
+ if (baseClass && !isOverrideMethodApplicable(baseOverload, baseClass)) {
17423
+ return false;
17424
+ }
17331
17425
  return validateOverrideMethodInternal(baseOverload, overrideOverload,
17332
- /* diag */ undefined, enforceParamNames);
17426
+ /* diag */ undefined, enforceParamNames,
17427
+ /* exemptSelfClsParam */ false);
17333
17428
  });
17334
17429
  if (matchIndex < 0) {
17335
17430
  diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch().format({ index: overrideOverloadIndex }));
@@ -17344,7 +17439,46 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17344
17439
  }
17345
17440
  return true;
17346
17441
  }
17347
- function validateOverrideMethodInternal(baseMethod, overrideMethod, diag, enforceParamNames) {
17442
+ // Determines whether a child class override is applicable to a parent
17443
+ // class method signature. This is important in cases where the parent
17444
+ // class defines an overload where some of the overload signatures supply
17445
+ // explicit type annotations for the "self" or "cls" parameter and some
17446
+ // of these do not apply to the child class.
17447
+ function isOverrideMethodApplicable(baseMethod, childClass) {
17448
+ if (!types_1.FunctionType.isInstanceMethod(baseMethod) &&
17449
+ !types_1.FunctionType.isClassMethod(baseMethod) &&
17450
+ !types_1.FunctionType.isConstructorMethod(baseMethod)) {
17451
+ return true;
17452
+ }
17453
+ const baseParamDetails = (0, parameterUtils_1.getParameterListDetails)(baseMethod);
17454
+ if (baseParamDetails.params.length === 0) {
17455
+ return true;
17456
+ }
17457
+ const baseParamType = baseParamDetails.params[0].param;
17458
+ if (baseParamType.category !== 0 /* Simple */ || !baseParamType.hasDeclaredType) {
17459
+ return true;
17460
+ }
17461
+ // If this is a self or cls parameter, determine whether the override
17462
+ // class can be assigned to the base parameter type. If not, then this
17463
+ // override doesn't apply. This is important for overloads where the
17464
+ // base class contains some overload signatures that are not applicable
17465
+ // to the child class.
17466
+ const childSelfOrClsType = types_1.FunctionType.isInstanceMethod(baseMethod)
17467
+ ? types_1.ClassType.cloneAsInstance(childClass)
17468
+ : childClass;
17469
+ return assignType(baseParamType.type, childSelfOrClsType,
17470
+ /* diag */ undefined,
17471
+ /* destTypeVarContext */ undefined,
17472
+ /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */);
17473
+ }
17474
+ // Determines whether the override method is compatible with the overridden method.
17475
+ // This is used both for parent/child overrides and implicit overrides for peer
17476
+ // classes in a multi-inheritance case. If enforceParamNames is true, the parameter
17477
+ // names of non-positional-only parameters are enforced. If exemptSelfClsParam
17478
+ // is true, the "self" and "cls" parameters are exempted from type checks.
17479
+ // This is normally the case except with overloaded method overrides where the
17480
+ // "self" or "cls" parameter type must be honored to differentiate between overloads.
17481
+ function validateOverrideMethodInternal(baseMethod, overrideMethod, diag, enforceParamNames, exemptSelfClsParam = true) {
17348
17482
  var _a, _b;
17349
17483
  const baseParamDetails = (0, parameterUtils_1.getParameterListDetails)(baseMethod);
17350
17484
  const overrideParamDetails = (0, parameterUtils_1.getParameterListDetails)(overrideMethod);
@@ -17365,7 +17499,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17365
17499
  canOverride = false;
17366
17500
  }
17367
17501
  }
17368
- if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
17502
+ else if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
17369
17503
  if (!types_1.FunctionType.isInstanceMethod(overrideMethod)) {
17370
17504
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotInstanceMethod());
17371
17505
  canOverride = false;
@@ -17417,7 +17551,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17417
17551
  // If the first parameter is a "self" or "cls" parameter, skip the
17418
17552
  // test because these are allowed to violate the Liskov substitution
17419
17553
  // principle.
17420
- if (i === 0) {
17554
+ if (i === 0 && exemptSelfClsParam) {
17421
17555
  if (types_1.FunctionType.isInstanceMethod(overrideMethod) ||
17422
17556
  types_1.FunctionType.isClassMethod(overrideMethod) ||
17423
17557
  types_1.FunctionType.isConstructorMethod(overrideMethod)) {
@@ -17465,7 +17599,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17465
17599
  const overrideParamType = overrideParamDetails.params[i].type;
17466
17600
  const baseIsSynthesizedTypeVar = (0, types_1.isTypeVar)(baseParamType) && baseParamType.details.isSynthesized;
17467
17601
  const overrideIsSynthesizedTypeVar = (0, types_1.isTypeVar)(overrideParamType) && overrideParamType.details.isSynthesized;
17468
- if (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar) {
17602
+ if (!exemptSelfClsParam || (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar)) {
17469
17603
  if (baseParam.category !== overrideParam.category ||
17470
17604
  !assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
17471
17605
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
@@ -17510,11 +17644,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17510
17644
  // Now check any keyword-only parameters.
17511
17645
  const baseKwOnlyParams = baseParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
17512
17646
  paramInfo.param.category === 0 /* Simple */);
17513
- const overrideWkOnlyParams = overrideParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
17647
+ const overrideKwOnlyParams = overrideParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
17514
17648
  paramInfo.param.category === 0 /* Simple */);
17515
17649
  baseKwOnlyParams.forEach((paramInfo) => {
17516
17650
  var _a, _b, _c;
17517
- const overrideParamInfo = overrideWkOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
17651
+ const overrideParamInfo = overrideKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
17518
17652
  if (!overrideParamInfo && overrideParamDetails.kwargsIndex === undefined) {
17519
17653
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
17520
17654
  name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
@@ -17547,7 +17681,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17547
17681
  });
17548
17682
  // Verify that any keyword-only parameters added by the overload are compatible
17549
17683
  // with the **kwargs in the base.
17550
- overrideWkOnlyParams.forEach((paramInfo) => {
17684
+ overrideKwOnlyParams.forEach((paramInfo) => {
17551
17685
  var _a;
17552
17686
  const baseParamInfo = baseKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
17553
17687
  if (!baseParamInfo) {