@zzzen/pyright-internal 1.2.0-dev.20231015 → 1.2.0-dev.20231029

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 (166) hide show
  1. package/dist/analyzer/backgroundAnalysisProgram.d.ts +3 -4
  2. package/dist/analyzer/backgroundAnalysisProgram.js +6 -3
  3. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  4. package/dist/analyzer/binder.js +1 -6
  5. package/dist/analyzer/binder.js.map +1 -1
  6. package/dist/analyzer/cacheManager.d.ts +3 -0
  7. package/dist/analyzer/cacheManager.js +11 -0
  8. package/dist/analyzer/cacheManager.js.map +1 -1
  9. package/dist/analyzer/checker.js +6 -13
  10. package/dist/analyzer/checker.js.map +1 -1
  11. package/dist/analyzer/codeFlowEngine.d.ts +0 -1
  12. package/dist/analyzer/codeFlowEngine.js +1 -1
  13. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  14. package/dist/analyzer/constraintSolver.js +68 -28
  15. package/dist/analyzer/constraintSolver.js.map +1 -1
  16. package/dist/analyzer/constructors.js +3 -4
  17. package/dist/analyzer/constructors.js.map +1 -1
  18. package/dist/analyzer/importResolver.d.ts +5 -2
  19. package/dist/analyzer/importResolver.js +40 -5
  20. package/dist/analyzer/importResolver.js.map +1 -1
  21. package/dist/analyzer/parseTreeUtils.d.ts +1 -0
  22. package/dist/analyzer/parseTreeUtils.js +11 -2
  23. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  24. package/dist/analyzer/patternMatching.js +4 -0
  25. package/dist/analyzer/patternMatching.js.map +1 -1
  26. package/dist/analyzer/program.d.ts +2 -3
  27. package/dist/analyzer/program.js +14 -24
  28. package/dist/analyzer/program.js.map +1 -1
  29. package/dist/analyzer/properties.js +6 -2
  30. package/dist/analyzer/properties.js.map +1 -1
  31. package/dist/analyzer/protocols.js +52 -36
  32. package/dist/analyzer/protocols.js.map +1 -1
  33. package/dist/analyzer/service.d.ts +1 -2
  34. package/dist/analyzer/service.js +5 -2
  35. package/dist/analyzer/service.js.map +1 -1
  36. package/dist/analyzer/sourceFile.d.ts +0 -1
  37. package/dist/analyzer/sourceFile.js +10 -13
  38. package/dist/analyzer/sourceFile.js.map +1 -1
  39. package/dist/analyzer/sourceFileInfo.d.ts +0 -4
  40. package/dist/analyzer/sourceFileInfo.js +0 -9
  41. package/dist/analyzer/sourceFileInfo.js.map +1 -1
  42. package/dist/analyzer/typeEvaluator.js +233 -185
  43. package/dist/analyzer/typeEvaluator.js.map +1 -1
  44. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
  45. package/dist/analyzer/typeEvaluatorTypes.js +3 -0
  46. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  47. package/dist/analyzer/typeGuards.js +28 -20
  48. package/dist/analyzer/typeGuards.js.map +1 -1
  49. package/dist/analyzer/typePrinter.js +4 -1
  50. package/dist/analyzer/typePrinter.js.map +1 -1
  51. package/dist/analyzer/typeUtils.d.ts +9 -1
  52. package/dist/analyzer/typeUtils.js +51 -46
  53. package/dist/analyzer/typeUtils.js.map +1 -1
  54. package/dist/analyzer/typedDicts.js +105 -33
  55. package/dist/analyzer/typedDicts.js.map +1 -1
  56. package/dist/analyzer/types.d.ts +4 -3
  57. package/dist/analyzer/types.js +31 -13
  58. package/dist/analyzer/types.js.map +1 -1
  59. package/dist/backgroundAnalysisBase.d.ts +3 -1
  60. package/dist/backgroundAnalysisBase.js +27 -0
  61. package/dist/backgroundAnalysisBase.js.map +1 -1
  62. package/dist/common/fullAccessHost.js +16 -1
  63. package/dist/common/fullAccessHost.js.map +1 -1
  64. package/dist/common/pathUtils.d.ts +4 -2
  65. package/dist/common/pathUtils.js +85 -28
  66. package/dist/common/pathUtils.js.map +1 -1
  67. package/dist/common/realFileSystem.js +15 -2
  68. package/dist/common/realFileSystem.js.map +1 -1
  69. package/dist/common/serviceProviderExtensions.d.ts +3 -3
  70. package/dist/common/serviceProviderExtensions.js +5 -7
  71. package/dist/common/serviceProviderExtensions.js.map +1 -1
  72. package/dist/common/uriParser.d.ts +10 -1
  73. package/dist/common/uriParser.js.map +1 -1
  74. package/dist/languageServerBase.d.ts +2 -6
  75. package/dist/languageServerBase.js +2 -19
  76. package/dist/languageServerBase.js.map +1 -1
  77. package/dist/languageService/documentSymbolCollector.d.ts +7 -0
  78. package/dist/languageService/documentSymbolCollector.js +28 -3
  79. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  80. package/dist/languageService/hoverProvider.d.ts +6 -2
  81. package/dist/languageService/hoverProvider.js +33 -65
  82. package/dist/languageService/hoverProvider.js.map +1 -1
  83. package/dist/languageService/referencesProvider.js +1 -0
  84. package/dist/languageService/referencesProvider.js.map +1 -1
  85. package/dist/languageService/tooltipUtils.js +1 -3
  86. package/dist/languageService/tooltipUtils.js.map +1 -1
  87. package/dist/localization/localize.d.ts +4 -3
  88. package/dist/localization/localize.js +3 -1
  89. package/dist/localization/localize.js.map +1 -1
  90. package/dist/localization/package.nls.cs.json +7 -1
  91. package/dist/localization/package.nls.de.json +7 -1
  92. package/dist/localization/package.nls.en-us.json +1 -1
  93. package/dist/localization/package.nls.es.json +7 -1
  94. package/dist/localization/package.nls.fr.json +7 -1
  95. package/dist/localization/package.nls.it.json +7 -1
  96. package/dist/localization/package.nls.ja.json +7 -1
  97. package/dist/localization/package.nls.ko.json +7 -1
  98. package/dist/localization/package.nls.pl.json +7 -1
  99. package/dist/localization/package.nls.pt-br.json +7 -1
  100. package/dist/localization/package.nls.qps-ploc.json +7 -1
  101. package/dist/localization/package.nls.ru.json +7 -1
  102. package/dist/localization/package.nls.tr.json +7 -1
  103. package/dist/localization/package.nls.zh-cn.json +7 -1
  104. package/dist/localization/package.nls.zh-tw.json +7 -1
  105. package/dist/pyrightFileSystem.d.ts +1 -15
  106. package/dist/pyrightFileSystem.js +1 -57
  107. package/dist/pyrightFileSystem.js.map +1 -1
  108. package/dist/server.js +3 -1
  109. package/dist/server.js.map +1 -1
  110. package/dist/tests/fourslash/completions.importInterimFile.fourslash.js +46 -0
  111. package/dist/tests/fourslash/completions.importInterimFile.fourslash.js.map +1 -0
  112. package/dist/tests/fourslash/completions.wildcardimports.fourslash.js +4 -0
  113. package/dist/tests/fourslash/completions.wildcardimports.fourslash.js.map +1 -1
  114. package/dist/tests/fourslash/findDefinitions.classes.fourslash.js +4 -0
  115. package/dist/tests/fourslash/findDefinitions.classes.fourslash.js.map +1 -1
  116. package/dist/tests/fourslash/findDefinitions.fields.fourslash.js +4 -0
  117. package/dist/tests/fourslash/findDefinitions.fields.fourslash.js.map +1 -1
  118. package/dist/tests/fourslash/findDefinitions.functions.fourslash.js +4 -0
  119. package/dist/tests/fourslash/findDefinitions.functions.fourslash.js.map +1 -1
  120. package/dist/tests/fourslash/findDefinitions.methods.fourslash.js +4 -0
  121. package/dist/tests/fourslash/findDefinitions.methods.fourslash.js.map +1 -1
  122. package/dist/tests/fourslash/findDefinitions.parameters.fourslash.js +4 -0
  123. package/dist/tests/fourslash/findDefinitions.parameters.fourslash.js.map +1 -1
  124. package/dist/tests/fourslash/findDefinitions.variables.fourslash.js +4 -0
  125. package/dist/tests/fourslash/findDefinitions.variables.fourslash.js.map +1 -1
  126. package/dist/tests/fourslash/findDefinitions.wildcardimports.fourslash.js +4 -0
  127. package/dist/tests/fourslash/findDefinitions.wildcardimports.fourslash.js.map +1 -1
  128. package/dist/tests/fourslash/findTypeDefinitions.classes.fourslash.js +4 -0
  129. package/dist/tests/fourslash/findTypeDefinitions.classes.fourslash.js.map +1 -1
  130. package/dist/tests/fourslash/fourslash.d.ts +4 -1
  131. package/dist/tests/fourslash/hover.class.docString.fourslash.js +4 -0
  132. package/dist/tests/fourslash/hover.class.docString.fourslash.js.map +1 -1
  133. package/dist/tests/fourslash/hover.docFromSrc.fourslash.js +4 -0
  134. package/dist/tests/fourslash/hover.docFromSrc.fourslash.js.map +1 -1
  135. package/dist/tests/fourslash/hover.docFromSrc.stringFormat.fourslash.d.ts +1 -0
  136. package/dist/tests/fourslash/{hover.docFromScr.stringFormat.fourslash.js → hover.docFromSrc.stringFormat.fourslash.js} +1 -1
  137. package/dist/tests/fourslash/{hover.docFromScr.stringFormat.fourslash.js.map → hover.docFromSrc.stringFormat.fourslash.js.map} +1 -1
  138. package/dist/tests/fourslash/hover.unpackedTypedDict.key.fourslash.d.ts +1 -0
  139. package/dist/tests/fourslash/hover.unpackedTypedDict.key.fourslash.js +24 -0
  140. package/dist/tests/fourslash/hover.unpackedTypedDict.key.fourslash.js.map +1 -0
  141. package/dist/tests/fourslash/hover.wildcardimports.fourslash.js +4 -0
  142. package/dist/tests/fourslash/hover.wildcardimports.fourslash.js.map +1 -1
  143. package/dist/tests/fourslash/signature.docstrings.wildcardimports.fourslash.js +4 -0
  144. package/dist/tests/fourslash/signature.docstrings.wildcardimports.fourslash.js.map +1 -1
  145. package/dist/tests/harness/fourslash/testLanguageService.js +2 -2
  146. package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
  147. package/dist/tests/harness/fourslash/testState.d.ts +7 -5
  148. package/dist/tests/harness/fourslash/testState.js +25 -10
  149. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  150. package/dist/tests/harness/vfs/filesystem.js +4 -0
  151. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  152. package/dist/tests/harness/vfs/pathValidation.js +10 -1
  153. package/dist/tests/harness/vfs/pathValidation.js.map +1 -1
  154. package/dist/tests/ipythonMode.test.js +0 -31
  155. package/dist/tests/ipythonMode.test.js.map +1 -1
  156. package/dist/tests/pathUtils.test.js +18 -0
  157. package/dist/tests/pathUtils.test.js.map +1 -1
  158. package/dist/tests/pyrightFileSystem.test.js +0 -20
  159. package/dist/tests/pyrightFileSystem.test.js.map +1 -1
  160. package/dist/tests/typeEvaluator2.test.js +11 -3
  161. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  162. package/dist/tests/typeEvaluator4.test.js +1 -1
  163. package/dist/tests/typeEvaluator5.test.js +8 -2
  164. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  165. package/package.json +1 -1
  166. /package/dist/tests/fourslash/{hover.docFromScr.stringFormat.fourslash.d.ts → completions.importInterimFile.fourslash.d.ts} +0 -0
@@ -1358,8 +1358,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1358
1358
  const unboundMethodType = getTypeOfMember(memberInfo);
1359
1359
  if ((0, types_1.isFunction)(unboundMethodType) || (0, types_1.isOverloadedFunction)(unboundMethodType)) {
1360
1360
  const boundMethod = bindFunctionToClassOrObject(types_1.ClassType.cloneAsInstance(classType), unboundMethodType,
1361
- /* memberClass */ undefined,
1362
- /* errorNode */ undefined, recursionCount, treatConstructorAsClassMember);
1361
+ /* memberClass */ undefined, treatConstructorAsClassMember,
1362
+ /* firstParamType */ undefined,
1363
+ /* diag */ undefined, recursionCount);
1363
1364
  if (boundMethod) {
1364
1365
  return boundMethod;
1365
1366
  }
@@ -1574,8 +1575,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1574
1575
  if (setItemMember) {
1575
1576
  const setItemType = getTypeOfMember(setItemMember);
1576
1577
  if ((0, types_1.isFunction)(setItemType)) {
1577
- const boundFunction = bindFunctionToClassOrObject(baseType, setItemType, (0, types_1.isInstantiableClass)(setItemMember.classType) ? setItemMember.classType : undefined, expression,
1578
- /* recursionCount */ undefined,
1578
+ const boundFunction = bindFunctionToClassOrObjectWithErrors(baseType, setItemType, (0, types_1.isInstantiableClass)(setItemMember.classType) ? setItemMember.classType : undefined, expression,
1579
1579
  /* treatConstructorAsClassMember */ false);
1580
1580
  if (boundFunction && (0, types_1.isFunction)(boundFunction)) {
1581
1581
  if (boundFunction.details.parameters.length >= 2) {
@@ -1621,8 +1621,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1621
1621
  }
1622
1622
  if ((0, types_1.isFunction)(declaredType) || (0, types_1.isOverloadedFunction)(declaredType)) {
1623
1623
  if (bindFunction) {
1624
- declaredType = bindFunctionToClassOrObject(classOrObjectBase, declaredType,
1625
- /* memberClass */ undefined, expression);
1624
+ declaredType = bindFunctionToClassOrObjectWithErrors(classOrObjectBase, declaredType,
1625
+ /* memberAccessClass */ undefined, expression);
1626
1626
  }
1627
1627
  }
1628
1628
  }
@@ -1935,9 +1935,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1935
1935
  const codeFlowResult = analyzer.getTypeFromCodeFlow(flowNode,
1936
1936
  /* reference */ undefined,
1937
1937
  /* targetSymbolId */ undefined,
1938
- /* typeAtStart */ types_1.UnboundType.create(), {
1939
- skipNoReturnCallAnalysis: true,
1940
- });
1938
+ /* typeAtStart */ types_1.UnboundType.create());
1941
1939
  return codeFlowResult.type !== undefined && !(0, types_1.isNever)(codeFlowResult.type);
1942
1940
  }
1943
1941
  // Determines whether there is a code flow path from sourceNode to sinkNode.
@@ -2449,15 +2447,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2449
2447
  const boundType = types_1.TypeBase.isInstantiable(subtype)
2450
2448
  ? (0, typeUtils_1.convertToInstantiable)(subtype.details.boundType)
2451
2449
  : subtype.details.boundType;
2452
- return subtype.details.isSynthesized
2453
- ? boundType
2454
- : (0, typeUtils_1.addConditionToType)(boundType, [
2455
- {
2456
- typeVarName: types_1.TypeVarType.getNameWithScope(subtype),
2457
- constraintIndex: 0,
2458
- isConstrainedTypeVar: false,
2459
- },
2460
- ]);
2450
+ // Handle Self and type[Self] specially.
2451
+ if (subtype.details.isSynthesizedSelf && (0, types_1.isClass)(boundType)) {
2452
+ return types_1.ClassType.cloneIncludeSubclasses(boundType);
2453
+ }
2454
+ return (0, typeUtils_1.addConditionToType)(boundType, [
2455
+ {
2456
+ typeVarName: types_1.TypeVarType.getNameWithScope(subtype),
2457
+ constraintIndex: 0,
2458
+ isConstrainedTypeVar: false,
2459
+ },
2460
+ ]);
2461
2461
  }
2462
2462
  // If this is a recursive type alias placeholder
2463
2463
  // that hasn't yet been resolved, return it as is.
@@ -2849,8 +2849,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2849
2849
  return memberType;
2850
2850
  }
2851
2851
  if ((0, types_1.isFunction)(memberType) || (0, types_1.isOverloadedFunction)(memberType)) {
2852
- const methodType = bindFunctionToClassOrObject(bindToClass || objType, memberType, classMember && (0, types_1.isInstantiableClass)(classMember.classType) ? classMember.classType : undefined, errorNode,
2853
- /* recursionCount */ undefined,
2852
+ const methodType = bindFunctionToClassOrObjectWithErrors(bindToClass || objType, memberType, classMember && (0, types_1.isInstantiableClass)(classMember.classType) ? classMember.classType : undefined, errorNode,
2854
2853
  /* treatConstructorAsClassMember */ false,
2855
2854
  /* firstParamType */ bindToClass);
2856
2855
  if (methodType) {
@@ -2870,7 +2869,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2870
2869
  return undefined;
2871
2870
  }
2872
2871
  function getTypeOfName(node, flags) {
2873
- var _a;
2874
2872
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2875
2873
  const name = node.value;
2876
2874
  let symbol;
@@ -3018,29 +3016,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3018
3016
  type = types_1.UnknownType.create();
3019
3017
  }
3020
3018
  }
3021
- if ((0, types_1.isTypeVar)(type) &&
3022
- !type.details.isParamSpec &&
3023
- !type.isVariadicInUnion &&
3024
- (flags & 128 /* ExpectingInstantiableType */) === 0 &&
3025
- type.details.name === name) {
3026
- // Handle the special case of a PEP 604 union. These can appear within
3027
- // an implied type alias where we are not expecting a type.
3028
- const isPep604Union = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 7 /* BinaryOperation */ &&
3029
- node.parent.operator === 6 /* BitwiseOr */;
3030
- if (!isPep604Union) {
3031
- // A TypeVar in contexts where we're not expecting a type is
3032
- // simply a TypeVar or TypeVarTuple object.
3033
- const typeVarType = type.details.isVariadic
3034
- ? getTypingType(node, 'TypeVarTuple')
3035
- : getTypingType(node, 'TypeVar');
3036
- if (typeVarType && (0, types_1.isInstantiableClass)(typeVarType)) {
3037
- type = types_1.ClassType.cloneAsInstance(typeVarType);
3038
- }
3039
- else {
3040
- type = types_1.UnknownType.create();
3041
- }
3042
- }
3043
- }
3019
+ type = convertTypeVarToRuntimeInstance(node, type, flags);
3044
3020
  if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
3045
3021
  reportUseOfTypeCheckOnly(type, node);
3046
3022
  }
@@ -3061,6 +3037,37 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3061
3037
  }
3062
3038
  return { type, isIncomplete };
3063
3039
  }
3040
+ // If the type is a TypeVar and we're not expecting a type, convert
3041
+ // a TypeVar or TypeVarTuple into a runtime type. We don't currently
3042
+ // do this for ParamSpec (although we arguably should) because it's
3043
+ // problematic for handling P.args and P.kwargs.
3044
+ function convertTypeVarToRuntimeInstance(node, type, flags) {
3045
+ var _a;
3046
+ if (node.nodeType === 38 /* Name */ &&
3047
+ (0, types_1.isTypeVar)(type) &&
3048
+ node.value === type.details.name &&
3049
+ !type.isVariadicInUnion &&
3050
+ (flags & 128 /* ExpectingInstantiableType */) === 0) {
3051
+ if ((flags & 33554432 /* SkipConvertParamSpecToRuntimeObject */) !== 0 && type.details.isParamSpec) {
3052
+ return type;
3053
+ }
3054
+ // Handle the special case of a PEP 604 union. These can appear within
3055
+ // an implied type alias where we are not expecting a type.
3056
+ const isPep604Union = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 7 /* BinaryOperation */ &&
3057
+ node.parent.operator === 6 /* BitwiseOr */;
3058
+ if (!isPep604Union) {
3059
+ // A TypeVar in contexts where we're not expecting a type is
3060
+ // simply a runtime object.
3061
+ if (type.details.runtimeClass) {
3062
+ type = types_1.ClassType.cloneAsInstance(type.details.runtimeClass);
3063
+ }
3064
+ else {
3065
+ type = types_1.UnknownType.create();
3066
+ }
3067
+ }
3068
+ }
3069
+ return type;
3070
+ }
3064
3071
  // Handles the case where a variable or parameter is defined in an outer
3065
3072
  // scope and captured by an inner scope (either a function or a lambda).
3066
3073
  function getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType) {
@@ -3386,15 +3393,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3386
3393
  return { type, isRescoped: false, foundInterveningClass: false };
3387
3394
  }
3388
3395
  function getTypeOfMemberAccess(node, flags) {
3389
- const baseTypeFlags = 16777218 /* MemberAccessBaseDefaults */ |
3390
- (flags &
3396
+ // Compute flags specifically for evaluating the left expression.
3397
+ let leftExprFlags = 16777218 /* MemberAccessBaseDefaults */;
3398
+ leftExprFlags |=
3399
+ flags &
3391
3400
  (256 /* ExpectingTypeAnnotation */ |
3392
3401
  32768 /* VariableTypeAnnotation */ |
3393
3402
  4 /* AllowForwardReferences */ |
3394
3403
  524288 /* NotParsedByInterpreter */ |
3395
3404
  2048 /* DisallowTypeVarsWithScopeId */ |
3396
- 8192 /* AssociateTypeVarsWithCurrentScope */));
3397
- const baseTypeResult = getTypeOfExpression(node.leftExpression, baseTypeFlags);
3405
+ 8192 /* AssociateTypeVarsWithCurrentScope */);
3406
+ // Handle special casing for ParamSpec "args" and "kwargs" accesses.
3407
+ if ((flags & 128 /* ExpectingInstantiableType */) !== 0) {
3408
+ const memberName = node.memberName.value;
3409
+ if (memberName === 'args' || memberName === 'kwargs') {
3410
+ leftExprFlags |= 33554432 /* SkipConvertParamSpecToRuntimeObject */;
3411
+ }
3412
+ }
3413
+ const baseTypeResult = getTypeOfExpression(node.leftExpression, leftExprFlags);
3398
3414
  if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
3399
3415
  return {
3400
3416
  type: types_1.UnknownType.create(/* isIncomplete */ true),
@@ -4102,8 +4118,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4102
4118
  bindToClass = accessMethod.classType;
4103
4119
  }
4104
4120
  }
4105
- let boundMethodType = bindFunctionToClassOrObject(lookupClass, methodType, bindToClass, errorNode,
4106
- /* recursionCount */ undefined,
4121
+ let boundMethodType = bindFunctionToClassOrObjectWithErrors(lookupClass, methodType, bindToClass, errorNode,
4107
4122
  /* treatConstructorAsClassMember */ undefined, isAccessedThroughMetaclass ? concreteSubtype : undefined);
4108
4123
  // The synthesized access method for the property may contain
4109
4124
  // type variables associated with the "bindToClass", so we need
@@ -4211,8 +4226,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4211
4226
  effectiveBindToType = (0, typeUtils_1.convertToInstance)(bindToType);
4212
4227
  }
4213
4228
  }
4214
- return bindFunctionToClassOrObject(isAccessedThroughObject ? types_1.ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode,
4215
- /* recursionCount */ undefined, treatConstructorAsClassMember, effectiveBindToType);
4229
+ // If the bind-to type is a specific class, add the "includeSubclasses" flag
4230
+ // to the type to indicate that it could be a subclass.
4231
+ if (effectiveBindToType && (0, types_1.isClass)(effectiveBindToType)) {
4232
+ effectiveBindToType = types_1.ClassType.cloneIncludeSubclasses(effectiveBindToType);
4233
+ }
4234
+ return bindFunctionToClassOrObjectWithErrors(isAccessedThroughObject ? types_1.ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode, treatConstructorAsClassMember, effectiveBindToType);
4216
4235
  }
4217
4236
  }
4218
4237
  if (usage.method === 'set') {
@@ -4395,7 +4414,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4395
4414
  });
4396
4415
  }
4397
4416
  if ((0, types_1.isFunction)(accessMemberType) || (0, types_1.isOverloadedFunction)(accessMemberType)) {
4398
- const boundMethodType = bindFunctionToClassOrObject(classType, accessMemberType, classType, errorNode);
4417
+ const boundMethodType = bindFunctionToClassOrObjectWithErrors(classType, accessMemberType, classType, errorNode);
4399
4418
  if (boundMethodType && ((0, types_1.isFunction)(boundMethodType) || (0, types_1.isOverloadedFunction)(boundMethodType))) {
4400
4419
  const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(boundMethodType));
4401
4420
  const callResult = validateCallArguments(errorNode, argList, { type: boundMethodType }, typeVarContext,
@@ -4451,7 +4470,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4451
4470
  }
4452
4471
  }
4453
4472
  }
4454
- const indexTypeResult = getTypeOfIndexWithBaseType(node, baseTypeResult, { method: 'get' }, flags);
4473
+ const indexTypeResult = getTypeOfIndexWithBaseType(node, baseTypeResult, { method: 'get' }, flags & ~16777216 /* DisallowPep695TypeAlias */);
4455
4474
  if ((0, codeFlowTypes_1.isCodeFlowSupportedForReference)(node)) {
4456
4475
  // We limit type narrowing for index expressions to built-in types that are
4457
4476
  // known to have symmetric __getitem__ and __setitem__ methods (i.e. the value
@@ -5527,7 +5546,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5527
5546
  else {
5528
5547
  baseTypeResult = getTypeOfExpression(node.leftExpression, 16777218 /* CallBaseDefaults */ | (flags & 4 /* AllowForwardReferences */));
5529
5548
  }
5530
- const argList = node.arguments.map((arg) => {
5549
+ const argList = ParseTreeUtils.getArgumentsByRuntimeOrder(node).map((arg) => {
5531
5550
  const functionArg = {
5532
5551
  valueExpression: arg.valueExpression,
5533
5552
  argumentCategory: arg.argumentCategory,
@@ -6947,7 +6966,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6947
6966
  const remainingArgCount = positionalArgCount - argIndex;
6948
6967
  const remainingParamCount = positionParamLimitIndex - paramIndex - 1;
6949
6968
  if (paramIndex >= positionParamLimitIndex) {
6950
- if (!typeResult.type.details.paramSpec) {
6969
+ if (paramSpecArgList) {
6970
+ // Push the remaining positional args onto the param spec arg list.
6971
+ while (argIndex < positionalArgCount) {
6972
+ paramSpecArgList.push(argList[argIndex]);
6973
+ argIndex++;
6974
+ }
6975
+ }
6976
+ else {
6951
6977
  let tooManyPositionals = false;
6952
6978
  if (foundUnpackedListArg && argList[argIndex].argumentCategory === 1 /* UnpackedList */) {
6953
6979
  // If this is an unpacked iterable, we will conservatively assume that it
@@ -7294,14 +7320,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7294
7320
  else if (typeResult.type.details.paramSpec &&
7295
7321
  (0, parameterUtils_1.isParamSpecKwargsArgument)(typeResult.type.details.paramSpec, argType)) {
7296
7322
  unpackedDictionaryArgType = types_1.AnyType.create();
7297
- validateArgTypeParams.push({
7298
- paramCategory: 2 /* KwargsDict */,
7299
- paramType: typeResult.type.details.paramSpec,
7300
- requiresTypeVarMatching: false,
7301
- argument: argList[argIndex],
7302
- argType: (0, types_1.isParamSpec)(argType) ? undefined : types_1.AnyType.create(),
7303
- errorNode: argList[argIndex].valueExpression || errorNode,
7304
- });
7323
+ if (!paramSpecArgList) {
7324
+ validateArgTypeParams.push({
7325
+ paramCategory: 2 /* KwargsDict */,
7326
+ paramType: typeResult.type.details.paramSpec,
7327
+ requiresTypeVarMatching: false,
7328
+ argument: argList[argIndex],
7329
+ argType: (0, types_1.isParamSpec)(argType) ? undefined : types_1.AnyType.create(),
7330
+ errorNode: argList[argIndex].valueExpression || errorNode,
7331
+ });
7332
+ }
7305
7333
  }
7306
7334
  else {
7307
7335
  const strObjType = getBuiltInObject(errorNode, 'str');
@@ -8112,13 +8140,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8112
8140
  return { argumentErrors: paramSpecArgResult.argumentErrors, typeVarContexts };
8113
8141
  }
8114
8142
  function validateFunctionArgumentsForParamSpecSignature(errorNode, argList, paramSpec, typeVarContext, signatureTracker) {
8115
- var _a;
8116
- const paramSpecType = typeVarContext.getParamSpecType(paramSpec);
8143
+ let paramSpecType = typeVarContext.getParamSpecType(paramSpec);
8117
8144
  if (!paramSpecType) {
8118
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotBound().format({ type: printType(paramSpec) }), ((_a = argList[0]) === null || _a === void 0 ? void 0 : _a.valueExpression) || errorNode);
8119
- return { argumentErrors: true, typeVarContexts: [undefined] };
8145
+ paramSpecType = (0, typeUtils_1.convertTypeToParamSpecValue)(paramSpec);
8120
8146
  }
8121
8147
  const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, { type: paramSpecType }, 0);
8148
+ const functionType = matchResults.overload;
8122
8149
  const srcTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(paramSpecType));
8123
8150
  if (matchResults.argumentErrors) {
8124
8151
  // Evaluate types of all args. This will ensure that referenced symbols are
@@ -8130,6 +8157,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8130
8157
  });
8131
8158
  return { argumentErrors: true, typeVarContexts: [srcTypeVarContext] };
8132
8159
  }
8160
+ // Handle the recursive case where we're passing (*args: P.args, **kwargs: P.args)
8161
+ // a remaining function of type (*P).
8162
+ if (functionType.details.paramSpec &&
8163
+ functionType.details.parameters.length === 0 &&
8164
+ (0, types_1.isTypeSame)(functionType.details.paramSpec, paramSpec)) {
8165
+ // TODO - need to perform additional validation here.
8166
+ return { argumentErrors: false, typeVarContexts: [srcTypeVarContext] };
8167
+ }
8133
8168
  const result = validateFunctionArgumentTypes(errorNode, matchResults, srcTypeVarContext, signatureTracker);
8134
8169
  return { argumentErrors: !!result.argumentErrors, typeVarContexts: [srcTypeVarContext] };
8135
8170
  }
@@ -8435,7 +8470,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8435
8470
  else {
8436
8471
  addError(localize_1.Localizer.Diagnostic.typeVarFirstArg(), firstArg.valueExpression || errorNode);
8437
8472
  }
8438
- const typeVar = types_1.TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false);
8473
+ const typeVar = types_1.TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false, classType);
8439
8474
  // Parse the remaining parameters.
8440
8475
  const paramNameMap = new Map();
8441
8476
  for (let i = 1; i < argList.length; i++) {
@@ -8451,7 +8486,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8451
8486
  }
8452
8487
  else {
8453
8488
  const argType = (_b = (_a = argList[i].typeResult) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : getTypeOfExpressionExpectingType(argList[i].valueExpression).type;
8454
- if ((0, typeUtils_1.requiresSpecialization)(argType, /* ignorePseudoGeneric */ true)) {
8489
+ if ((0, typeUtils_1.requiresSpecialization)(argType, { ignorePseudoGeneric: true, ignoreImplicitTypeArgs: true })) {
8455
8490
  addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), argList[i].valueExpression || errorNode);
8456
8491
  }
8457
8492
  typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(argType);
@@ -8514,7 +8549,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8514
8549
  }
8515
8550
  else {
8516
8551
  const argType = (_g = (_f = argList[i].typeResult) === null || _f === void 0 ? void 0 : _f.type) !== null && _g !== void 0 ? _g : getTypeOfExpressionExpectingType(argList[i].valueExpression).type;
8517
- if ((0, typeUtils_1.requiresSpecialization)(argType, /* ignorePseudoGeneric */ true)) {
8552
+ if ((0, typeUtils_1.requiresSpecialization)(argType, { ignorePseudoGeneric: true })) {
8518
8553
  addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), argList[i].valueExpression || errorNode);
8519
8554
  }
8520
8555
  types_1.TypeVarType.addConstraint(typeVar, (0, typeUtils_1.convertToInstance)(argType));
@@ -8561,7 +8596,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8561
8596
  else {
8562
8597
  addError(localize_1.Localizer.Diagnostic.typeVarFirstArg(), firstArg.valueExpression || errorNode);
8563
8598
  }
8564
- const typeVar = types_1.TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false);
8599
+ const typeVar = types_1.TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false, classType);
8565
8600
  typeVar.details.isVariadic = true;
8566
8601
  // Parse the remaining parameters.
8567
8602
  for (let i = 1; i < argList.length; i++) {
@@ -8613,7 +8648,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8613
8648
  else {
8614
8649
  addError(localize_1.Localizer.Diagnostic.paramSpecFirstArg(), firstArg.valueExpression || errorNode);
8615
8650
  }
8616
- const paramSpec = types_1.TypeVarType.createInstantiable(paramSpecName, /* isParamSpec */ true);
8651
+ const paramSpec = types_1.TypeVarType.createInstantiable(paramSpecName, /* isParamSpec */ true, classType);
8617
8652
  // Parse the remaining parameters.
8618
8653
  for (let i = 1; i < argList.length; i++) {
8619
8654
  const paramNameNode = argList[i].name;
@@ -9598,12 +9633,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9598
9633
  return { type: returnedType };
9599
9634
  }
9600
9635
  function getTypeOfLambda(node, inferenceContext) {
9601
- let isIncomplete = !!(inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete);
9602
- const functionType = types_1.FunctionType.createInstance('', '', '', 131072 /* PartiallyEvaluated */);
9603
- functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
9604
- // Pre-cache the incomplete function type in case the evaluation of the
9605
- // lambda depends on itself.
9606
- writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* None */);
9607
9636
  let expectedFunctionTypes = [];
9608
9637
  if (inferenceContext) {
9609
9638
  (0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (subtype) => {
@@ -9618,25 +9647,34 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9618
9647
  }
9619
9648
  return undefined;
9620
9649
  });
9621
- // Determine the minimum number of parameters that are required to
9622
- // satisfy the lambda.
9623
- const minLambdaParamCount = node.parameters.filter((param) => param.category === 0 /* Simple */ && !!param.name && param.defaultValue === undefined).length;
9624
- const maxLambdaParamCount = node.parameters.filter((param) => param.category === 0 /* Simple */ && !!param.name).length;
9625
- // Remove any expected subtypes that don't satisfy the minimum
9626
- // parameter count requirement.
9627
- expectedFunctionTypes = expectedFunctionTypes.filter((functionType) => {
9628
- const functionParamCount = functionType.details.parameters.filter((param) => !!param.name && !param.hasDefault).length;
9629
- const hasVarArgs = functionType.details.parameters.some((param) => !!param.name && param.category !== 0 /* Simple */);
9630
- const hasParamSpec = !!functionType.details.paramSpec;
9631
- return (hasVarArgs ||
9632
- hasParamSpec ||
9633
- (functionParamCount >= minLambdaParamCount && functionParamCount <= maxLambdaParamCount));
9634
- });
9635
9650
  }
9636
- // For now, use only the first expected type.
9637
- const expectedFunctionType = expectedFunctionTypes.length > 0 ? expectedFunctionTypes[0] : undefined;
9651
+ if (expectedFunctionTypes.length <= 1) {
9652
+ return getTypeOfLambdaWithExpectedType(node, expectedFunctionTypes.length > 0 ? expectedFunctionTypes[0] : undefined, inferenceContext,
9653
+ /* forceSpeculative */ false);
9654
+ }
9655
+ // Sort the expected types for deterministic results.
9656
+ expectedFunctionTypes = (0, typeUtils_1.sortTypes)(expectedFunctionTypes);
9657
+ // If there's more than one type, try each in turn until we find one that works.
9658
+ for (const expectedFunctionType of expectedFunctionTypes) {
9659
+ const result = getTypeOfLambdaWithExpectedType(node, expectedFunctionType, inferenceContext,
9660
+ /* forceSpeculative */ true);
9661
+ if (!result.typeErrors) {
9662
+ return getTypeOfLambdaWithExpectedType(node, expectedFunctionType, inferenceContext,
9663
+ /* forceSpeculative */ false);
9664
+ }
9665
+ }
9666
+ return getTypeOfLambdaWithExpectedType(node, expectedFunctionTypes[0], inferenceContext,
9667
+ /* forceSpeculative */ true);
9668
+ }
9669
+ function getTypeOfLambdaWithExpectedType(node, expectedType, inferenceContext, forceSpeculative) {
9670
+ let isIncomplete = !!(inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete);
9638
9671
  let paramsArePositionOnly = true;
9639
- const expectedParamDetails = expectedFunctionType ? (0, parameterUtils_1.getParameterListDetails)(expectedFunctionType) : undefined;
9672
+ const expectedParamDetails = expectedType ? (0, parameterUtils_1.getParameterListDetails)(expectedType) : undefined;
9673
+ const functionType = types_1.FunctionType.createInstance('', '', '', 131072 /* PartiallyEvaluated */);
9674
+ functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
9675
+ // Pre-cache the incomplete function type in case the evaluation of the
9676
+ // lambda depends on itself.
9677
+ writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* None */);
9640
9678
  node.parameters.forEach((param, index) => {
9641
9679
  let paramType;
9642
9680
  if (expectedParamDetails) {
@@ -9701,9 +9739,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9701
9739
  type: types_1.UnknownType.create(),
9702
9740
  });
9703
9741
  }
9704
- const expectedReturnType = expectedFunctionType
9705
- ? getFunctionEffectiveReturnType(expectedFunctionType)
9706
- : undefined;
9742
+ const expectedReturnType = expectedType ? getFunctionEffectiveReturnType(expectedType) : undefined;
9743
+ let typeErrors = false;
9707
9744
  // If we're speculatively evaluating the lambda, create another speculative
9708
9745
  // evaluation scope for the return expression and do not allow retention
9709
9746
  // of the cached types.
@@ -9711,19 +9748,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9711
9748
  // cache the type of the lambda return expression because it depends on
9712
9749
  // the parameter types that we set above, and the speculative type cache
9713
9750
  // doesn't know about that context.
9714
- useSpeculativeMode(isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete) ? node.expression : undefined, () => {
9751
+ useSpeculativeMode(forceSpeculative || isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete)
9752
+ ? node.expression
9753
+ : undefined, () => {
9715
9754
  const returnTypeResult = getTypeOfExpression(node.expression,
9716
9755
  /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedReturnType));
9717
9756
  functionType.inferredReturnType = returnTypeResult.type;
9718
9757
  if (returnTypeResult.isIncomplete) {
9719
9758
  isIncomplete = true;
9720
9759
  }
9760
+ if (returnTypeResult.typeErrors) {
9761
+ typeErrors = true;
9762
+ }
9721
9763
  }, {
9722
- dependentType: inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType,
9764
+ dependentType: expectedType,
9723
9765
  });
9724
9766
  // Mark the function type as no longer being evaluated.
9725
9767
  functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
9726
- return { type: functionType, isIncomplete };
9768
+ // Is the resulting function compatible with the expected type?
9769
+ if (expectedType && !assignType(expectedType, functionType)) {
9770
+ typeErrors = true;
9771
+ }
9772
+ return { type: functionType, isIncomplete, typeErrors };
9727
9773
  }
9728
9774
  function getTypeOfListComprehension(node, inferenceContext) {
9729
9775
  var _a;
@@ -10221,7 +10267,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10221
10267
  const type = typeArgs[0].type;
10222
10268
  // A ClassVar should not allow TypeVars or generic types parameterized
10223
10269
  // by TypeVars.
10224
- if ((0, typeUtils_1.requiresSpecialization)(type, /* ignorePseudoGeneric */ true, /* ignoreSelf */ true)) {
10270
+ if ((0, typeUtils_1.requiresSpecialization)(type, { ignorePseudoGeneric: true, ignoreSelf: true })) {
10225
10271
  const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
10226
10272
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classVarWithTypeVar(), (_a = typeArgs[0].node) !== null && _a !== void 0 ? _a : errorNode);
10227
10273
  }
@@ -10341,8 +10387,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10341
10387
  isRequired = classType.details.name === 'Required';
10342
10388
  isNotRequired = classType.details.name === 'NotRequired';
10343
10389
  }
10344
- isRequired = classType.details.name === 'Required';
10345
- isNotRequired = classType.details.name === 'NotRequired';
10346
10390
  if (!isUsageLegal) {
10347
10391
  addError(classType.details.name === 'ReadOnly'
10348
10392
  ? localize_1.Localizer.Diagnostic.readOnlyNotInTypedDict()
@@ -10780,12 +10824,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10780
10824
  ['LiteralString', { alias: '', module: 'builtins' }],
10781
10825
  ['ReadOnly', { alias: '', module: 'builtins' }],
10782
10826
  ]);
10783
- let aliasMapEntry = specialTypes.get(assignedName);
10784
- // Support ReadOnly only as an experimental feature.
10785
- if (assignedName === 'ReadOnly' &&
10786
- !AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures) {
10787
- aliasMapEntry = undefined;
10788
- }
10827
+ const aliasMapEntry = specialTypes.get(assignedName);
10789
10828
  if (aliasMapEntry) {
10790
10829
  const cachedType = readTypeCache(node, 0 /* None */);
10791
10830
  if (cachedType) {
@@ -11315,8 +11354,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11315
11354
  metaclassNode = arg.valueExpression;
11316
11355
  }
11317
11356
  }
11318
- else if (types_1.ClassType.isTypedDictClass(classType) &&
11319
- (arg.name.value === 'total' || arg.name.value === 'readonly')) {
11357
+ else if (types_1.ClassType.isTypedDictClass(classType) && arg.name.value === 'total') {
11320
11358
  // The "total" and "readonly" parameters apply only for TypedDict classes.
11321
11359
  // PEP 589 specifies that the parameter must be either True or False.
11322
11360
  const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
@@ -11326,9 +11364,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11326
11364
  else if (arg.name.value === 'total' && !constArgValue) {
11327
11365
  classType.details.flags |= 256 /* CanOmitDictValues */;
11328
11366
  }
11329
- else if (arg.name.value === 'readonly' && constArgValue) {
11330
- classType.details.flags |= 512 /* DictValuesReadOnly */;
11331
- }
11332
11367
  }
11333
11368
  else {
11334
11369
  // Collect arguments that will be passed to the `__init_subclass__`
@@ -11464,7 +11499,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11464
11499
  if (metaclassNode) {
11465
11500
  const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type;
11466
11501
  if ((0, types_1.isInstantiableClass)(metaclassType) || (0, types_1.isUnknown)(metaclassType)) {
11467
- if ((0, typeUtils_1.requiresSpecialization)(metaclassType, /* ignorePseudoGeneric */ true)) {
11502
+ if ((0, typeUtils_1.requiresSpecialization)(metaclassType, { ignorePseudoGeneric: true })) {
11468
11503
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
11469
11504
  }
11470
11505
  classType.details.declaredMetaclass = metaclassType;
@@ -11738,7 +11773,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11738
11773
  }
11739
11774
  else if (!(0, typeUtils_1.derivesFromClassRecursive)(effectiveMetaclass, baseClassMeta, /* ignoreUnknown */ false)) {
11740
11775
  if (!reportedMetaclassConflict) {
11741
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassConflict(), errorNode);
11776
+ const diag = new diagnostic_1.DiagnosticAddendum();
11777
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.metaclassConflict().format({
11778
+ metaclass1: printType((0, typeUtils_1.convertToInstance)(effectiveMetaclass)),
11779
+ metaclass2: printType((0, typeUtils_1.convertToInstance)(baseClassMeta)),
11780
+ }));
11781
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassConflict() + diag.getString(), errorNode);
11742
11782
  // Don't report more than once.
11743
11783
  reportedMetaclassConflict = true;
11744
11784
  }
@@ -14216,6 +14256,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14216
14256
  .getDeclarations()
14217
14257
  .find((decl) => decl.type === 2 /* Parameter */);
14218
14258
  }
14259
+ const parameterDetails = (0, parameterUtils_1.getParameterListDetails)(type);
14260
+ if (parameterDetails.unpackedKwargsTypedDictType) {
14261
+ const lookupResults = (0, typeUtils_1.lookUpClassMember)(parameterDetails.unpackedKwargsTypedDictType, paramName);
14262
+ if (lookupResults) {
14263
+ return lookupResults.symbol
14264
+ .getDeclarations()
14265
+ .find((decl) => decl.type === 1 /* Variable */);
14266
+ }
14267
+ }
14219
14268
  }
14220
14269
  }
14221
14270
  }
@@ -14556,13 +14605,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14556
14605
  if (cachedTypeVarType && (0, types_1.isTypeVar)(cachedTypeVarType)) {
14557
14606
  return cachedTypeVarType;
14558
14607
  }
14559
- let typeVar = types_1.TypeVarType.createInstantiable(node.name.value);
14560
- typeVar.details.isTypeParamSyntax = true;
14608
+ let runtimeClassName = 'TypeVar';
14561
14609
  if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
14562
- typeVar.details.isVariadic = true;
14610
+ runtimeClassName = 'TypeVarTuple';
14563
14611
  }
14564
14612
  else if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
14565
- typeVar.details.isParamSpec = true;
14613
+ runtimeClassName = 'ParamSpec';
14614
+ }
14615
+ const runtimeType = getTypingType(node, runtimeClassName);
14616
+ const runtimeClass = runtimeType && (0, types_1.isInstantiableClass)(runtimeType) ? runtimeType : undefined;
14617
+ let typeVar = types_1.TypeVarType.createInstantiable(node.name.value, node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec, runtimeClass);
14618
+ typeVar.details.isTypeParamSyntax = true;
14619
+ if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
14620
+ typeVar.details.isVariadic = true;
14566
14621
  }
14567
14622
  // Cache the value before we evaluate the bound or the default type in
14568
14623
  // case it refers to itself in a circular manner.
@@ -14572,7 +14627,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14572
14627
  if (node.boundExpression.nodeType === 52 /* Tuple */) {
14573
14628
  const constraints = node.boundExpression.expressions.map((constraint) => {
14574
14629
  const constraintType = getTypeOfExpressionExpectingType(constraint).type;
14575
- if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
14630
+ if ((0, typeUtils_1.requiresSpecialization)(constraintType, {
14631
+ ignorePseudoGeneric: true,
14632
+ ignoreImplicitTypeArgs: true,
14633
+ })) {
14576
14634
  addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), constraint);
14577
14635
  }
14578
14636
  return (0, typeUtils_1.convertToInstance)(constraintType);
@@ -14586,7 +14644,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14586
14644
  }
14587
14645
  else {
14588
14646
  const boundType = getTypeOfExpressionExpectingType(node.boundExpression).type;
14589
- if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
14647
+ if ((0, typeUtils_1.requiresSpecialization)(boundType, { ignorePseudoGeneric: true })) {
14590
14648
  addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), node.boundExpression);
14591
14649
  }
14592
14650
  if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
@@ -14888,7 +14946,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14888
14946
  return getEffectiveTypeOfSymbolForUsage(symbol).type;
14889
14947
  }
14890
14948
  function getEffectiveTypeOfSymbolForUsage(symbol, usageNode, useLastDecl = false) {
14891
- var _a, _b;
14892
14949
  let declaredTypeInfo;
14893
14950
  // If there's a declared type, it takes precedence over inferred types.
14894
14951
  if (symbol.hasTypedDeclarations()) {
@@ -14921,13 +14978,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14921
14978
  let cacheEntries = effectiveTypeCache.get(symbol.id);
14922
14979
  const usageNodeId = usageNode ? usageNode.id : undefined;
14923
14980
  const effectiveTypeCacheKey = `${usageNodeId === undefined ? '.' : usageNodeId.toString()}${useLastDecl ? '*' : ''}`;
14924
- if (cacheEntries) {
14925
- const result = cacheEntries.get(effectiveTypeCacheKey);
14926
- if (result) {
14927
- if (!result.isIncomplete) {
14928
- return result;
14929
- }
14930
- }
14981
+ const cacheEntry = cacheEntries === null || cacheEntries === void 0 ? void 0 : cacheEntries.get(effectiveTypeCacheKey);
14982
+ if (cacheEntry && !cacheEntry.isIncomplete) {
14983
+ return cacheEntry;
14931
14984
  }
14932
14985
  // Infer the type.
14933
14986
  const decls = symbol.getDeclarations();
@@ -15016,8 +15069,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15016
15069
  }
15017
15070
  declsToConsider.push(resolvedDecl);
15018
15071
  });
15019
- const evaluationAttempts = ((_b = (_a = cacheEntries === null || cacheEntries === void 0 ? void 0 : cacheEntries.get(effectiveTypeCacheKey)) === null || _a === void 0 ? void 0 : _a.evaluationAttempts) !== null && _b !== void 0 ? _b : 0) + 1;
15020
- const result = getTypeOfSymbolForDecls(symbol, declsToConsider, evaluationAttempts);
15072
+ const result = getTypeOfSymbolForDecls(symbol, declsToConsider, effectiveTypeCacheKey);
15021
15073
  // Add the result to the effective type cache if it doesn't include speculative results.
15022
15074
  if (!result.includesSpeculativeResult) {
15023
15075
  addToEffectiveTypeCache(result);
@@ -15033,7 +15085,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15033
15085
  }
15034
15086
  }
15035
15087
  // Returns the type of a symbol based on a subset of its declarations.
15036
- function getTypeOfSymbolForDecls(symbol, decls, evaluationAttempts) {
15088
+ function getTypeOfSymbolForDecls(symbol, decls, typeCacheKey) {
15089
+ var _a, _b;
15037
15090
  const typesToCombine = [];
15038
15091
  let isIncomplete = false;
15039
15092
  let sawPendingEvaluation = false;
@@ -15101,6 +15154,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15101
15154
  sawPendingEvaluation = true;
15102
15155
  }
15103
15156
  });
15157
+ // How many times have we already attempted to evaluate this declaration already?
15158
+ const cacheEntries = effectiveTypeCache.get(symbol.id);
15159
+ const evaluationAttempts = ((_b = (_a = cacheEntries === null || cacheEntries === void 0 ? void 0 : cacheEntries.get(typeCacheKey)) === null || _a === void 0 ? void 0 : _a.evaluationAttempts) !== null && _b !== void 0 ? _b : 0) + 1;
15104
15160
  let type;
15105
15161
  if (typesToCombine.length > 0) {
15106
15162
  // Ignore the pending evaluation flag if we've already attempted the
@@ -16917,31 +16973,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16917
16973
  }
16918
16974
  let specializedSrcType = srcType;
16919
16975
  let specializedDestType = destType;
16920
- let reverseMatchingFailed = false;
16976
+ let doSpecializationStep = false;
16921
16977
  if ((flags & 2 /* ReverseTypeVarMatching */) === 0) {
16922
16978
  specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
16923
- if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
16924
- reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16925
- /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
16926
- specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext);
16927
- }
16979
+ doSpecializationStep = (0, typeUtils_1.requiresSpecialization)(specializedDestType);
16928
16980
  }
16929
16981
  else {
16930
16982
  specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
16931
- if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
16932
- reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16933
- /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
16934
- specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext);
16983
+ doSpecializationStep = (0, typeUtils_1.requiresSpecialization)(specializedSrcType);
16984
+ }
16985
+ // Is an additional specialization step required?
16986
+ if (doSpecializationStep) {
16987
+ assignType(specializedSrcType, specializedDestType,
16988
+ /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
16989
+ if ((flags & 2 /* ReverseTypeVarMatching */) === 0) {
16990
+ specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext);
16935
16991
  }
16936
- if (reverseMatchingFailed) {
16937
- if (diag && paramIndex !== undefined) {
16938
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.paramAssignment().format({
16939
- index: paramIndex + 1,
16940
- sourceType: printType(destType),
16941
- destType: printType(srcType),
16942
- }));
16943
- }
16944
- return false;
16992
+ else {
16993
+ specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext);
16945
16994
  }
16946
16995
  }
16947
16996
  // Handle the special case where the source is a Self type and the
@@ -17481,13 +17530,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17481
17530
  return undefined;
17482
17531
  }
17483
17532
  recursionCount++;
17484
- // If this is a tuple with defined tuple type arguments, don't overwrite them.
17485
- if (assignedType.tupleTypeArguments) {
17486
- return undefined;
17487
- }
17488
17533
  if (assignedType.details.typeParameters.length > 0 &&
17489
17534
  assignedType.typeArguments &&
17490
- assignedType.typeArguments.length <= assignedType.details.typeParameters.length) {
17535
+ assignedType.typeArguments.length <= assignedType.details.typeParameters.length &&
17536
+ !assignedType.tupleTypeArguments) {
17491
17537
  const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(assignedType));
17492
17538
  (0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneForSpecialization(assignedType,
17493
17539
  /* typeArguments */ undefined,
@@ -18104,13 +18150,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18104
18150
  });
18105
18151
  return methodList;
18106
18152
  }
18153
+ function bindFunctionToClassOrObjectWithErrors(baseType, memberType, memberClass, errorNode, treatConstructorAsClassMember = false, firstParamType) {
18154
+ const diag = errorNode ? new diagnostic_1.DiagnosticAddendum() : undefined;
18155
+ const result = bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMember, firstParamType, diag);
18156
+ if (!result && errorNode && diag) {
18157
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, diag.getString(), errorNode);
18158
+ }
18159
+ return result;
18160
+ }
18107
18161
  // If the memberType is an instance or class method, creates a new
18108
18162
  // version of the function that has the "self" or "cls" parameter bound
18109
18163
  // to it. If treatAsClassMethod is true, the function is treated like a
18110
18164
  // class method even if it's not marked as such. That's needed to
18111
18165
  // special-case the __new__ magic method when it's invoked as a
18112
18166
  // constructor (as opposed to by name).
18113
- function bindFunctionToClassOrObject(baseType, memberType, memberClass, errorNode, recursionCount = 0, treatConstructorAsClassMember = false, firstParamType) {
18167
+ function bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMember = false, firstParamType, diag, recursionCount = 0) {
18114
18168
  if ((0, types_1.isFunction)(memberType)) {
18115
18169
  // If the caller specified no base type, always strip the
18116
18170
  // first parameter. This is used in cases like constructors.
@@ -18125,7 +18179,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18125
18179
  const baseObj = (0, types_1.isClassInstance)(baseType)
18126
18180
  ? baseType
18127
18181
  : types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType));
18128
- return partiallySpecializeFunctionForBoundClassOrObject(baseType, memberType, memberClass || types_1.ClassType.cloneAsInstantiable(baseObj), errorNode, recursionCount, firstParamType || baseObj,
18182
+ return partiallySpecializeFunctionForBoundClassOrObject(baseType, memberType, memberClass || types_1.ClassType.cloneAsInstantiable(baseObj), diag, recursionCount, firstParamType || baseObj,
18129
18183
  /* stripFirstParam */ (0, types_1.isClassInstance)(baseType));
18130
18184
  }
18131
18185
  if (types_1.FunctionType.isClassMethod(memberType) ||
@@ -18138,12 +18192,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18138
18192
  ? firstParamType
18139
18193
  : (0, typeUtils_1.convertToInstantiable)(firstParamType)
18140
18194
  : baseClass;
18141
- return partiallySpecializeFunctionForBoundClassOrObject(types_1.TypeBase.isInstance(baseType) ? types_1.ClassType.cloneAsInstantiable(baseType) : baseType, memberType, memberClass || baseClass, errorNode, recursionCount, effectiveFirstParamType,
18195
+ return partiallySpecializeFunctionForBoundClassOrObject(types_1.TypeBase.isInstance(baseType) ? types_1.ClassType.cloneAsInstantiable(baseType) : baseType, memberType, memberClass || baseClass, diag, recursionCount, effectiveFirstParamType,
18142
18196
  /* stripFirstParam */ true);
18143
18197
  }
18144
18198
  if (types_1.FunctionType.isStaticMethod(memberType)) {
18145
18199
  const baseClass = (0, types_1.isInstantiableClass)(baseType) ? baseType : types_1.ClassType.cloneAsInstantiable(baseType);
18146
- return partiallySpecializeFunctionForBoundClassOrObject(types_1.TypeBase.isInstance(baseType) ? types_1.ClassType.cloneAsInstantiable(baseType) : baseType, memberType, memberClass || baseClass, errorNode, recursionCount,
18200
+ return partiallySpecializeFunctionForBoundClassOrObject(types_1.TypeBase.isInstance(baseType) ? types_1.ClassType.cloneAsInstantiable(baseType) : baseType, memberType, memberClass || baseClass, diag, recursionCount,
18147
18201
  /* effectiveFirstParamType */ undefined,
18148
18202
  /* stripFirstParam */ false);
18149
18203
  }
@@ -18152,24 +18206,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18152
18206
  const newOverloadType = types_1.OverloadedFunctionType.create([]);
18153
18207
  // Don't bother binding the implementation.
18154
18208
  types_1.OverloadedFunctionType.getOverloads(memberType).forEach((overload) => {
18155
- const boundMethod = bindFunctionToClassOrObject(baseType, overload, memberClass,
18156
- /* errorNode */ undefined, recursionCount, treatConstructorAsClassMember, firstParamType);
18209
+ const boundMethod = bindFunctionToClassOrObject(baseType, overload, memberClass, treatConstructorAsClassMember, firstParamType,
18210
+ /* diag */ undefined, recursionCount);
18157
18211
  if (boundMethod) {
18158
18212
  types_1.OverloadedFunctionType.addOverload(newOverloadType, boundMethod);
18159
18213
  }
18160
18214
  });
18161
- if (types_1.OverloadedFunctionType.getOverloads(newOverloadType).length === 0) {
18162
- // No overloads matched, so rebind with the errorNode
18215
+ const newOverloads = types_1.OverloadedFunctionType.getOverloads(newOverloadType);
18216
+ if (newOverloads.length === 0) {
18217
+ // No overloads matched, so rebind with the diag
18163
18218
  // to report the error(s) to the user.
18164
- if (errorNode) {
18219
+ if (diag) {
18165
18220
  memberType.overloads.forEach((overload) => {
18166
- bindFunctionToClassOrObject(baseType, overload, memberClass, errorNode, recursionCount, treatConstructorAsClassMember, firstParamType);
18221
+ bindFunctionToClassOrObject(baseType, overload, memberClass, treatConstructorAsClassMember, firstParamType, diag, recursionCount);
18167
18222
  });
18168
18223
  }
18169
18224
  return undefined;
18170
18225
  }
18171
- else if (newOverloadType.overloads.length === 1) {
18172
- return newOverloadType.overloads[0];
18226
+ if (newOverloads.length === 1) {
18227
+ return newOverloads[0];
18173
18228
  }
18174
18229
  return newOverloadType;
18175
18230
  }
@@ -18181,14 +18236,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18181
18236
  // is the type used to reference the member, and the memberClass
18182
18237
  // is the class that provided the member (could be an ancestor of
18183
18238
  // the baseType's class).
18184
- function partiallySpecializeFunctionForBoundClassOrObject(baseType, memberType, memberClass, errorNode, recursionCount, firstParamType, stripFirstParam = true) {
18239
+ function partiallySpecializeFunctionForBoundClassOrObject(baseType, memberType, memberClass, diag, recursionCount, firstParamType, stripFirstParam = true) {
18185
18240
  const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(memberClass));
18186
18241
  if (firstParamType && memberType.details.parameters.length > 0) {
18187
18242
  const memberTypeFirstParam = memberType.details.parameters[0];
18188
18243
  const memberTypeFirstParamType = types_1.FunctionType.getEffectiveParameterType(memberType, 0);
18189
18244
  // Fill out the typeVarContext for the "self" or "cls" parameter.
18190
18245
  typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(memberType));
18191
- const diag = errorNode ? new diagnostic_1.DiagnosticAddendum() : undefined;
18192
18246
  if ((0, types_1.isTypeVar)(memberTypeFirstParamType) &&
18193
18247
  memberTypeFirstParamType.details.boundType &&
18194
18248
  (0, types_1.isClassInstance)(memberTypeFirstParamType.details.boundType) &&
@@ -18203,25 +18257,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18203
18257
  : firstParamType);
18204
18258
  }
18205
18259
  }
18206
- else if (!assignType(memberTypeFirstParamType, firstParamType, diag, typeVarContext,
18260
+ else if (!assignType(memberTypeFirstParamType, firstParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), typeVarContext,
18207
18261
  /* srcTypeVarContext */ undefined, 2048 /* AllowUnspecifiedTypeArguments */, recursionCount)) {
18208
18262
  if (memberTypeFirstParam.name &&
18209
18263
  !memberTypeFirstParam.isNameSynthesized &&
18210
18264
  memberTypeFirstParam.hasDeclaredType) {
18211
- if (errorNode) {
18212
- const methodName = memberType.details.name || '(unnamed)';
18213
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.bindTypeMismatch().format({
18265
+ if (diag) {
18266
+ diag.addMessage(localize_1.Localizer.Diagnostic.bindTypeMismatch().format({
18214
18267
  type: printType(baseType),
18215
- methodName: methodName,
18268
+ methodName: memberType.details.name || '<anonymous>',
18216
18269
  paramName: memberTypeFirstParam.name,
18217
- }) + (diag === null || diag === void 0 ? void 0 : diag.getString()), errorNode);
18218
- }
18219
- else {
18220
- // If there was no errorNode, we couldn't report the error,
18221
- // so we will instead return undefined and let the caller
18222
- // deal with the error.
18223
- return undefined;
18270
+ }));
18224
18271
  }
18272
+ return undefined;
18225
18273
  }
18226
18274
  }
18227
18275
  }