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

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 (185) hide show
  1. package/dist/analyzer/analyzerFileInfo.d.ts +1 -0
  2. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  3. package/dist/analyzer/checker.js +99 -105
  4. package/dist/analyzer/checker.js.map +1 -1
  5. package/dist/analyzer/codeFlowEngine.js +12 -33
  6. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  7. package/dist/analyzer/codeFlowUtils.js +4 -2
  8. package/dist/analyzer/codeFlowUtils.js.map +1 -1
  9. package/dist/analyzer/constraintSolver.js +21 -23
  10. package/dist/analyzer/constraintSolver.js.map +1 -1
  11. package/dist/analyzer/constructorTransform.js +4 -6
  12. package/dist/analyzer/constructorTransform.js.map +1 -1
  13. package/dist/analyzer/constructors.d.ts +6 -3
  14. package/dist/analyzer/constructors.js +66 -41
  15. package/dist/analyzer/constructors.js.map +1 -1
  16. package/dist/analyzer/dataClasses.js +13 -18
  17. package/dist/analyzer/dataClasses.js.map +1 -1
  18. package/dist/analyzer/declarationUtils.js +1 -1
  19. package/dist/analyzer/declarationUtils.js.map +1 -1
  20. package/dist/analyzer/decorators.js +1 -1
  21. package/dist/analyzer/decorators.js.map +1 -1
  22. package/dist/analyzer/enums.d.ts +2 -5
  23. package/dist/analyzer/enums.js +5 -3
  24. package/dist/analyzer/enums.js.map +1 -1
  25. package/dist/analyzer/functionTransform.js +1 -1
  26. package/dist/analyzer/functionTransform.js.map +1 -1
  27. package/dist/analyzer/importResolver.d.ts +4 -2
  28. package/dist/analyzer/importResolver.js +30 -10
  29. package/dist/analyzer/importResolver.js.map +1 -1
  30. package/dist/analyzer/importStatementUtils.d.ts +1 -1
  31. package/dist/analyzer/importStatementUtils.js +33 -5
  32. package/dist/analyzer/importStatementUtils.js.map +1 -1
  33. package/dist/analyzer/namedTuples.js +3 -2
  34. package/dist/analyzer/namedTuples.js.map +1 -1
  35. package/dist/analyzer/operations.js +34 -31
  36. package/dist/analyzer/operations.js.map +1 -1
  37. package/dist/analyzer/packageTypeVerifier.js +28 -26
  38. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  39. package/dist/analyzer/parseTreeUtils.d.ts +1 -0
  40. package/dist/analyzer/parseTreeUtils.js +17 -2
  41. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  42. package/dist/analyzer/patternMatching.js +6 -6
  43. package/dist/analyzer/patternMatching.js.map +1 -1
  44. package/dist/analyzer/program.d.ts +1 -1
  45. package/dist/analyzer/program.js +34 -21
  46. package/dist/analyzer/program.js.map +1 -1
  47. package/dist/analyzer/properties.js +25 -28
  48. package/dist/analyzer/properties.js.map +1 -1
  49. package/dist/analyzer/protocols.d.ts +1 -1
  50. package/dist/analyzer/protocols.js +15 -19
  51. package/dist/analyzer/protocols.js.map +1 -1
  52. package/dist/analyzer/service.js +12 -6
  53. package/dist/analyzer/service.js.map +1 -1
  54. package/dist/analyzer/sourceFile.d.ts +1 -0
  55. package/dist/analyzer/sourceFile.js +36 -2
  56. package/dist/analyzer/sourceFile.js.map +1 -1
  57. package/dist/analyzer/sourceFileInfoUtils.d.ts +1 -1
  58. package/dist/analyzer/sourceFileInfoUtils.js +9 -3
  59. package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
  60. package/dist/analyzer/tracePrinter.js +11 -13
  61. package/dist/analyzer/tracePrinter.js.map +1 -1
  62. package/dist/analyzer/typeDocStringUtils.js +3 -3
  63. package/dist/analyzer/typeDocStringUtils.js.map +1 -1
  64. package/dist/analyzer/typeEvaluator.d.ts +3 -1
  65. package/dist/analyzer/typeEvaluator.js +1184 -1270
  66. package/dist/analyzer/typeEvaluator.js.map +1 -1
  67. package/dist/analyzer/typeEvaluatorTypes.d.ts +13 -26
  68. package/dist/analyzer/typeEvaluatorTypes.js +1 -36
  69. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  70. package/dist/analyzer/typeGuards.js +37 -32
  71. package/dist/analyzer/typeGuards.js.map +1 -1
  72. package/dist/analyzer/typePrinter.js +19 -18
  73. package/dist/analyzer/typePrinter.js.map +1 -1
  74. package/dist/analyzer/typeUtils.d.ts +17 -8
  75. package/dist/analyzer/typeUtils.js +149 -94
  76. package/dist/analyzer/typeUtils.js.map +1 -1
  77. package/dist/analyzer/typeVarContext.js +6 -7
  78. package/dist/analyzer/typeVarContext.js.map +1 -1
  79. package/dist/analyzer/typeWalker.d.ts +1 -2
  80. package/dist/analyzer/typeWalker.js +7 -13
  81. package/dist/analyzer/typeWalker.js.map +1 -1
  82. package/dist/analyzer/typedDicts.js +10 -10
  83. package/dist/analyzer/typedDicts.js.map +1 -1
  84. package/dist/analyzer/types.d.ts +11 -20
  85. package/dist/analyzer/types.js +45 -77
  86. package/dist/analyzer/types.js.map +1 -1
  87. package/dist/commands/dumpFileDebugInfoCommand.js +7 -9
  88. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  89. package/dist/common/commandLineOptions.d.ts +2 -1
  90. package/dist/common/commandLineOptions.js +1 -1
  91. package/dist/common/commandLineOptions.js.map +1 -1
  92. package/dist/common/configOptions.d.ts +3 -2
  93. package/dist/common/configOptions.js +40 -25
  94. package/dist/common/configOptions.js.map +1 -1
  95. package/dist/common/extensibility.d.ts +3 -0
  96. package/dist/common/pathUtils.d.ts +1 -1
  97. package/dist/common/pathUtils.js +11 -10
  98. package/dist/common/pathUtils.js.map +1 -1
  99. package/dist/common/realFileSystem.js +4 -6
  100. package/dist/common/realFileSystem.js.map +1 -1
  101. package/dist/common/serviceProviderExtensions.d.ts +2 -1
  102. package/dist/common/serviceProviderExtensions.js +1 -0
  103. package/dist/common/serviceProviderExtensions.js.map +1 -1
  104. package/dist/common/textEditTracker.js +2 -2
  105. package/dist/common/textEditTracker.js.map +1 -1
  106. package/dist/languageServerBase.d.ts +3 -3
  107. package/dist/languageServerBase.js +18 -15
  108. package/dist/languageServerBase.js.map +1 -1
  109. package/dist/languageService/analyzerServiceExecutor.js +1 -1
  110. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  111. package/dist/languageService/callHierarchyProvider.js +3 -3
  112. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  113. package/dist/languageService/completionProvider.d.ts +2 -1
  114. package/dist/languageService/completionProvider.js +12 -10
  115. package/dist/languageService/completionProvider.js.map +1 -1
  116. package/dist/languageService/completionProviderUtils.js +1 -1
  117. package/dist/languageService/definitionProvider.js +1 -1
  118. package/dist/languageService/documentSymbolCollector.js +1 -1
  119. package/dist/languageService/hoverProvider.js +1 -1
  120. package/dist/languageService/signatureHelpProvider.js +0 -14
  121. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  122. package/dist/languageService/tooltipUtils.js +4 -4
  123. package/dist/languageService/tooltipUtils.js.map +1 -1
  124. package/dist/localization/localize.d.ts +16 -0
  125. package/dist/localization/localize.js +6 -0
  126. package/dist/localization/localize.js.map +1 -1
  127. package/dist/localization/package.nls.cs.json +4 -1
  128. package/dist/localization/package.nls.de.json +4 -1
  129. package/dist/localization/package.nls.en-us.json +7 -1
  130. package/dist/localization/package.nls.es.json +4 -1
  131. package/dist/localization/package.nls.fr.json +4 -1
  132. package/dist/localization/package.nls.it.json +4 -1
  133. package/dist/localization/package.nls.ja.json +4 -1
  134. package/dist/localization/package.nls.ko.json +4 -1
  135. package/dist/localization/package.nls.pl.json +4 -1
  136. package/dist/localization/package.nls.pt-br.json +4 -1
  137. package/dist/localization/package.nls.qps-ploc.json +3 -0
  138. package/dist/localization/package.nls.ru.json +4 -1
  139. package/dist/localization/package.nls.tr.json +4 -1
  140. package/dist/localization/package.nls.zh-cn.json +4 -1
  141. package/dist/localization/package.nls.zh-tw.json +4 -1
  142. package/dist/pyright.js +3 -6
  143. package/dist/pyright.js.map +1 -1
  144. package/dist/server.d.ts +1 -0
  145. package/dist/server.js +10 -1
  146. package/dist/server.js.map +1 -1
  147. package/dist/tests/diagnosticOverrides.test.js +4 -2
  148. package/dist/tests/diagnosticOverrides.test.js.map +1 -1
  149. package/dist/tests/fourslash/{completions.importInterimFile.fourslash.js → completions.importInterimFile.fourslash.disabled.js} +2 -2
  150. package/dist/tests/fourslash/completions.importInterimFile.fourslash.disabled.js.map +1 -0
  151. package/dist/tests/fourslash/fourslash.d.ts +1 -1
  152. package/dist/tests/fourslash/signature.complicated.fourslash.js +6 -6
  153. package/dist/tests/fourslash/signature.complicated.fourslash.js.map +1 -1
  154. package/dist/tests/fourslash/signature.dunderNew.fourslash.js +1 -1
  155. package/dist/tests/fourslash/signature.dunderNew.fourslash.js.map +1 -1
  156. package/dist/tests/harness/fourslash/testState.d.ts +1 -1
  157. package/dist/tests/harness/fourslash/testState.js +4 -4
  158. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  159. package/dist/tests/harness/vfs/filesystem.js +1 -1
  160. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  161. package/dist/tests/logger.test.js +0 -1
  162. package/dist/tests/logger.test.js.map +1 -1
  163. package/dist/tests/parseTreeUtils.test.js +15 -0
  164. package/dist/tests/parseTreeUtils.test.js.map +1 -1
  165. package/dist/tests/pathUtils.test.js +30 -1
  166. package/dist/tests/pathUtils.test.js.map +1 -1
  167. package/dist/tests/testUtils.js +2 -1
  168. package/dist/tests/testUtils.js.map +1 -1
  169. package/dist/tests/textEditUtil.test.js +25 -0
  170. package/dist/tests/textEditUtil.test.js.map +1 -1
  171. package/dist/tests/typeEvaluator1.test.js +7 -3
  172. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  173. package/dist/tests/typeEvaluator2.test.js +5 -1
  174. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  175. package/dist/tests/typeEvaluator3.test.js +10 -4
  176. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  177. package/dist/tests/typeEvaluator4.test.js +11 -7
  178. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  179. package/dist/tests/typePrinter.test.js +12 -16
  180. package/dist/tests/typePrinter.test.js.map +1 -1
  181. package/dist/tests/zipfs.test.js +2 -0
  182. package/dist/tests/zipfs.test.js.map +1 -1
  183. package/package.json +1 -1
  184. package/dist/tests/fourslash/completions.importInterimFile.fourslash.js.map +0 -1
  185. /package/dist/tests/fourslash/{completions.importInterimFile.fourslash.d.ts → completions.importInterimFile.fourslash.disabled.d.ts} +0 -0
@@ -178,6 +178,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
178
178
  let deferredClassCompletions = [];
179
179
  let cancellationToken;
180
180
  let isBasicTypesInitialized = false;
181
+ let noneClassType;
181
182
  let noneType;
182
183
  let objectType;
183
184
  let typeClassType;
@@ -374,6 +375,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
374
375
  // type of surrounding statements to be evaluated.
375
376
  function getType(node) {
376
377
  var _a, _b;
378
+ initializedBasicTypes(node);
377
379
  let type = (_a = evaluateTypeForSubnode(node, () => {
378
380
  evaluateTypesForExpressionInContext(node);
379
381
  })) === null || _a === void 0 ? void 0 : _a.type;
@@ -447,6 +449,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
447
449
  return undefined;
448
450
  }
449
451
  function initializedBasicTypes(node) {
452
+ var _a;
450
453
  if (!isBasicTypesInitialized) {
451
454
  // Some of these types have cyclical dependencies on each other,
452
455
  // so don't re-enter this block once we start executing it.
@@ -457,7 +460,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
457
460
  // Initialize and cache "Collection" to break a cyclical dependency
458
461
  // that occurs when resolving tuple below.
459
462
  getTypingType(node, 'Collection');
460
- noneType = getTypeshedType(node, 'NoneType') || types_1.AnyType.create();
463
+ noneClassType = (_a = getTypeshedType(node, 'NoneType')) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
464
+ noneType = (0, types_1.isInstantiableClass)(noneClassType)
465
+ ? types_1.ClassType.cloneAsInstance(noneClassType)
466
+ : types_1.UnknownType.create();
461
467
  tupleClassType = getBuiltInType(node, 'tuple');
462
468
  boolClassType = getBuiltInType(node, 'bool');
463
469
  intClassType = getBuiltInType(node, 'int');
@@ -1079,20 +1085,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1079
1085
  case 0 /* Unbound */:
1080
1086
  case 1 /* Unknown */:
1081
1087
  case 2 /* Any */:
1082
- case 4 /* Never */:
1083
- case 3 /* None */: {
1088
+ case 3 /* Never */: {
1084
1089
  return true;
1085
1090
  }
1086
- case 9 /* Union */: {
1091
+ case 8 /* Union */: {
1087
1092
  return (0, types_1.findSubtype)(type, (subtype) => canBeFalsy(subtype, recursionCount)) !== undefined;
1088
1093
  }
1089
- case 5 /* Function */:
1090
- case 6 /* OverloadedFunction */:
1091
- case 8 /* Module */:
1092
- case 10 /* TypeVar */: {
1094
+ case 4 /* Function */:
1095
+ case 5 /* OverloadedFunction */:
1096
+ case 7 /* Module */:
1097
+ case 9 /* TypeVar */: {
1093
1098
  return false;
1094
1099
  }
1095
- case 7 /* Class */: {
1100
+ case 6 /* Class */: {
1096
1101
  if (types_1.TypeBase.isInstantiable(type)) {
1097
1102
  return false;
1098
1103
  }
@@ -1133,7 +1138,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1133
1138
  }
1134
1139
  return true;
1135
1140
  }
1136
- return false;
1141
+ // If the class is not final, it's possible that it could be overridden
1142
+ // such that it is falsy. To be fully correct, we'd need to do the
1143
+ // following:
1144
+ // return !ClassType.isFinal(type);
1145
+ // However, pragmatically if the class is not an `object`, it's typically
1146
+ // OK to assume that it will not be overridden in this manner.
1147
+ return types_1.ClassType.isBuiltIn(type, 'object');
1137
1148
  }
1138
1149
  }
1139
1150
  }
@@ -1145,25 +1156,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1145
1156
  recursionCount++;
1146
1157
  switch (type.category) {
1147
1158
  case 1 /* Unknown */:
1148
- case 5 /* Function */:
1149
- case 6 /* OverloadedFunction */:
1150
- case 8 /* Module */:
1151
- case 10 /* TypeVar */:
1152
- case 4 /* Never */:
1159
+ case 4 /* Function */:
1160
+ case 5 /* OverloadedFunction */:
1161
+ case 7 /* Module */:
1162
+ case 9 /* TypeVar */:
1163
+ case 3 /* Never */:
1153
1164
  case 2 /* Any */: {
1154
1165
  return true;
1155
1166
  }
1156
- case 9 /* Union */: {
1167
+ case 8 /* Union */: {
1157
1168
  return (0, types_1.findSubtype)(type, (subtype) => canBeTruthy(subtype, recursionCount)) !== undefined;
1158
1169
  }
1159
- case 0 /* Unbound */:
1160
- case 3 /* None */: {
1170
+ case 0 /* Unbound */: {
1161
1171
  return false;
1162
1172
  }
1163
- case 7 /* Class */: {
1173
+ case 6 /* Class */: {
1164
1174
  if (types_1.TypeBase.isInstantiable(type)) {
1165
1175
  return true;
1166
1176
  }
1177
+ if ((0, typeUtils_1.isNoneInstance)(type)) {
1178
+ return false;
1179
+ }
1167
1180
  // Check for Tuple[()] (an empty tuple).
1168
1181
  if ((0, typeUtils_1.isTupleClass)(type)) {
1169
1182
  if (type.tupleTypeArguments && type.tupleTypeArguments.length === 0) {
@@ -1255,6 +1268,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1255
1268
  if (types_1.ClassType.isBuiltIn(concreteSubtype, 'bool')) {
1256
1269
  return types_1.ClassType.cloneWithLiteral(concreteSubtype, /* value */ true);
1257
1270
  }
1271
+ // If the object is a "None" instance, we can eliminate it.
1272
+ if ((0, typeUtils_1.isNoneInstance)(concreteSubtype)) {
1273
+ return undefined;
1274
+ }
1275
+ // If this is an instance of a class that cannot be subclassed,
1276
+ // we cannot say definitively that it's not falsy because a subclass
1277
+ // could override `__bool__`. For this reason, the code should not
1278
+ // remove any classes that are not final.
1279
+ // if (!ClassType.isFinal(concreteSubtype)) {
1280
+ // return subtype;
1281
+ // }
1282
+ // However, we're going to pragmatically assume that any classes
1283
+ // other than `object` will not be overridden in this manner.
1284
+ if (types_1.ClassType.isBuiltIn(concreteSubtype, 'object')) {
1285
+ return subtype;
1286
+ }
1258
1287
  }
1259
1288
  // If it's possible for the type to be truthy, include it.
1260
1289
  if (canBeTruthy(subtype)) {
@@ -1263,113 +1292,109 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1263
1292
  return undefined;
1264
1293
  });
1265
1294
  }
1266
- // Gets a member type from an object and if it's a function binds
1267
- // it to the object. If bindToClass is undefined, the binding is done
1295
+ // Gets a member type from an object or class. If it's a function, binds
1296
+ // it to the object or class. If selfType is undefined, the binding is done
1268
1297
  // using the objectType parameter. Callers can specify these separately
1269
1298
  // to handle the case where we're fetching the object member from a
1270
1299
  // metaclass but binding to the class.
1271
- function getTypeOfObjectMember(errorNode, objectType, memberName, usage = { method: 'get' }, diag = undefined, memberAccessFlags = 0 /* None */, bindToType) {
1272
- let memberInfo = getTypeOfClassMemberName(errorNode, types_1.ClassType.cloneAsInstantiable(objectType),
1273
- /* isAccessedThroughObject */ true, memberName, usage, diag, memberAccessFlags | 16 /* DisallowClassVarWrites */, bindToType);
1274
- if (!memberInfo) {
1275
- const metaclass = objectType.details.effectiveMetaclass;
1276
- if (metaclass &&
1277
- (0, types_1.isInstantiableClass)(metaclass) &&
1278
- !types_1.ClassType.isBuiltIn(metaclass, 'type') &&
1279
- !types_1.ClassType.isSameGenericClass(metaclass, objectType)) {
1280
- memberInfo = getTypeOfClassMemberName(errorNode, metaclass,
1281
- /* isAccessedThroughObject */ false, memberName, usage,
1282
- /* diag */ undefined, memberAccessFlags |
1283
- 2 /* AccessInstanceMembersOnly */ |
1284
- 128 /* SkipAttributeAccessOverride */, types_1.ClassType.cloneAsInstantiable(objectType));
1285
- }
1286
- }
1287
- if (memberInfo && !memberInfo.isSetTypeError) {
1288
- return {
1289
- type: memberInfo.type,
1290
- classType: memberInfo.classType,
1291
- isIncomplete: !!memberInfo.isTypeIncomplete,
1292
- isAsymmetricAccessor: memberInfo.isAsymmetricAccessor,
1293
- memberAccessDeprecationInfo: memberInfo.memberAccessDeprecationInfo,
1294
- };
1295
- }
1296
- return undefined;
1297
- }
1298
- // Gets a member type from a class and if it's a function binds
1299
- // it to the class.
1300
- function getTypeOfClassMember(errorNode, classType, memberName, usage = { method: 'get' }, diag = undefined, memberAccessFlags = 0 /* None */, bindToType) {
1301
- let memberInfo;
1302
- const classDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1303
- const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1304
- let considerMetaclassOnly = (memberAccessFlags & 64 /* ConsiderMetaclassOnly */) !== 0;
1305
- if (types_1.ClassType.isPartiallyEvaluated(classType)) {
1306
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: classType.details.name }), errorNode);
1300
+ function getTypeOfBoundMember(errorNode, objectType, memberName, usage = { method: 'get' }, diag = undefined, flags = 0 /* Default */, selfType, recursionCount = 0) {
1301
+ if (types_1.ClassType.isPartiallyEvaluated(objectType)) {
1302
+ if (errorNode) {
1303
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: objectType.details.name }), errorNode);
1304
+ }
1307
1305
  return { type: types_1.UnknownType.create() };
1308
1306
  }
1309
- const metaclass = classType.details.effectiveMetaclass;
1307
+ // Determine the class that was used to instantiate the objectType.
1308
+ // If the objectType is a class itself, then the class used to instantiate
1309
+ // it is the metaclass.
1310
+ const objectTypeIsInstantiable = types_1.TypeBase.isInstantiable(objectType);
1311
+ const metaclass = objectType.details.effectiveMetaclass;
1312
+ let memberInfo;
1313
+ // If the object type is an instantiable (i.e. it derives from "type") and
1314
+ // we've been asked not to consider instance members, don't look in the class.
1315
+ // Consider only the metaclass class variables in this case.
1316
+ let skipObjectTypeLookup = objectTypeIsInstantiable && (flags & 16 /* SkipInstanceMembers */) !== 0;
1310
1317
  // Look up the attribute in the metaclass first. If the member is a descriptor
1311
- // (an object with a __get__ method) and the access is a 'get', the Python runtime
1312
- // uses this metaclass descriptor to satisfy the lookup. Skip this costly lookup
1313
- // in the common case where the metaclass is 'type' since we know that `type` doesn't
1314
- // have any attributes that are descriptors.
1318
+ // (an object with a __get__ and __set__ method) and the access is a 'get',
1319
+ // the Python runtime uses this descriptor to satisfy the lookup. Skip this
1320
+ // costly lookup in the common case where the metaclass is 'type' since we know
1321
+ // that `type` doesn't have any attributes that are descriptors.
1315
1322
  if (usage.method === 'get' &&
1323
+ objectTypeIsInstantiable &&
1316
1324
  metaclass &&
1317
1325
  (0, types_1.isInstantiableClass)(metaclass) &&
1318
1326
  !types_1.ClassType.isBuiltIn(metaclass, 'type') &&
1319
- !types_1.ClassType.isSameGenericClass(metaclass, classType)) {
1320
- const metaclassMemberInfo = getTypeOfClassMemberName(errorNode, metaclass,
1321
- /* isAccessedThroughObject */ false, memberName, usage, metaclassDiag, memberAccessFlags | 128 /* SkipAttributeAccessOverride */, classType);
1322
- if (metaclassMemberInfo && (0, typeUtils_1.isDescriptorInstance)(metaclassMemberInfo.type)) {
1323
- considerMetaclassOnly = true;
1327
+ !types_1.ClassType.isSameGenericClass(metaclass, objectType)) {
1328
+ const descMemberInfo = getTypeOfClassMemberName(errorNode, metaclass, memberName, usage,
1329
+ /* diag */ undefined, flags | 512 /* SkipAttributeAccessOverride */, objectType);
1330
+ if (descMemberInfo) {
1331
+ const isProperty = (0, types_1.isClassInstance)(descMemberInfo.type) && types_1.ClassType.isPropertyClass(descMemberInfo.type);
1332
+ if ((0, typeUtils_1.isDescriptorInstance)(descMemberInfo.type, /* requireSetter */ true) || isProperty) {
1333
+ skipObjectTypeLookup = true;
1334
+ }
1324
1335
  }
1325
1336
  }
1326
- // Look up the attribute in the class object.
1327
- if (!memberInfo && !considerMetaclassOnly) {
1328
- memberInfo = getTypeOfClassMemberName(errorNode, classType,
1329
- /* isAccessedThroughObject */ false, memberName, usage, classDiag, memberAccessFlags | 1 /* AccessClassMembersOnly */, bindToType);
1330
- }
1331
- const isMemberPresentOnClass = (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.classType) !== undefined;
1332
- // If it wasn't found on the class, see if it's part of the metaclass.
1333
- if (!memberInfo) {
1334
- const metaclass = classType.details.effectiveMetaclass;
1335
- if (metaclass && (0, types_1.isInstantiableClass)(metaclass) && !types_1.ClassType.isSameGenericClass(metaclass, classType)) {
1336
- memberInfo = getTypeOfClassMemberName(errorNode, metaclass,
1337
- /* isAccessedThroughObject */ true, memberName, usage, metaclassDiag, memberAccessFlags, classType);
1337
+ let subDiag;
1338
+ if (!skipObjectTypeLookup) {
1339
+ let effectiveFlags = flags;
1340
+ if (objectTypeIsInstantiable) {
1341
+ effectiveFlags |= 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */;
1342
+ effectiveFlags &= ~32 /* SkipClassMembers */;
1338
1343
  }
1339
- }
1340
- if (memberInfo && !memberInfo.isSetTypeError) {
1344
+ else {
1345
+ effectiveFlags |= 128 /* DisallowClassVarWrites */;
1346
+ }
1347
+ subDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1348
+ // See if the member is present in the object itself.
1349
+ memberInfo = getTypeOfClassMemberName(errorNode, objectType, memberName, usage, subDiag, effectiveFlags, selfType);
1350
+ }
1351
+ // If it wasn't found on the object, see if it's part of the metaclass.
1352
+ if (!memberInfo && metaclass && (0, types_1.isInstantiableClass)(metaclass)) {
1353
+ let effectiveFlags = flags;
1354
+ // Class members cannot be accessed on a class's metaclass through
1355
+ // an instance of a class. Limit access to metaclass instance members
1356
+ // in this case.
1357
+ if (!objectTypeIsInstantiable) {
1358
+ effectiveFlags |= 32 /* SkipClassMembers */ | 512 /* SkipAttributeAccessOverride */;
1359
+ effectiveFlags &= ~16 /* SkipInstanceMembers */;
1360
+ }
1361
+ const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1362
+ memberInfo = getTypeOfClassMemberName(errorNode, types_1.ClassType.cloneAsInstance(metaclass), memberName, usage, metaclassDiag, effectiveFlags, objectTypeIsInstantiable ? objectType : types_1.ClassType.cloneAsInstantiable(objectType), recursionCount);
1363
+ // If there was a descriptor error (as opposed to an error where the members
1364
+ // was simply not found), use this diagnostic message.
1365
+ if (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isDescriptorError) {
1366
+ subDiag = metaclassDiag;
1367
+ }
1368
+ }
1369
+ if (memberInfo && !memberInfo.isDescriptorError) {
1341
1370
  return {
1342
1371
  type: memberInfo.type,
1372
+ classType: memberInfo.classType,
1343
1373
  isIncomplete: !!memberInfo.isTypeIncomplete,
1344
1374
  isAsymmetricAccessor: memberInfo.isAsymmetricAccessor,
1345
1375
  memberAccessDeprecationInfo: memberInfo.memberAccessDeprecationInfo,
1346
1376
  };
1347
1377
  }
1348
- // Determine whether to use the class or metaclass diagnostic addendum.
1349
- const subDiag = isMemberPresentOnClass ? classDiag : metaclassDiag;
1350
1378
  if (diag && subDiag) {
1351
1379
  diag.addAddendum(subDiag);
1352
1380
  }
1353
1381
  return undefined;
1354
1382
  }
1355
- function getBoundMethod(classType, memberName, recursionCount = 0, treatConstructorAsClassMember = false) {
1356
- const memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, 8 /* SkipInstanceVariables */);
1357
- if (memberInfo) {
1358
- const unboundMethodType = getTypeOfMember(memberInfo);
1359
- if ((0, types_1.isFunction)(unboundMethodType) || (0, types_1.isOverloadedFunction)(unboundMethodType)) {
1360
- const boundMethod = bindFunctionToClassOrObject(types_1.ClassType.cloneAsInstance(classType), unboundMethodType,
1361
- /* memberClass */ undefined, treatConstructorAsClassMember,
1362
- /* firstParamType */ undefined,
1363
- /* diag */ undefined, recursionCount);
1364
- if (boundMethod) {
1365
- return boundMethod;
1366
- }
1367
- }
1368
- else if ((0, types_1.isAnyOrUnknown)(unboundMethodType)) {
1369
- const unknownFunction = types_1.FunctionType.createSynthesizedInstance('', 32768 /* SkipArgsKwargsCompatibilityCheck */);
1370
- types_1.FunctionType.addDefaultParameters(unknownFunction);
1371
- return unknownFunction;
1372
- }
1383
+ function getBoundMagicMethod(classType, memberName, selfType, recursionCount = 0) {
1384
+ const boundMethodResult = getTypeOfBoundMember(
1385
+ /* errorNode */ undefined, classType, memberName,
1386
+ /* usage */ undefined,
1387
+ /* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */, selfType, recursionCount);
1388
+ if (!boundMethodResult || boundMethodResult.typeErrors) {
1389
+ return undefined;
1390
+ }
1391
+ if ((0, types_1.isFunction)(boundMethodResult.type) || (0, types_1.isOverloadedFunction)(boundMethodResult.type)) {
1392
+ return boundMethodResult.type;
1393
+ }
1394
+ if ((0, types_1.isAnyOrUnknown)(boundMethodResult.type)) {
1395
+ const unknownFunction = types_1.FunctionType.createSynthesizedInstance('', 32768 /* SkipArgsKwargsCompatibilityCheck */);
1396
+ types_1.FunctionType.addDefaultParameters(unknownFunction);
1397
+ return unknownFunction;
1373
1398
  }
1374
1399
  return undefined;
1375
1400
  }
@@ -1379,7 +1404,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1379
1404
  function getCallSignatureInfo(callNode, activeIndex, activeOrFake) {
1380
1405
  const exprNode = callNode.leftExpression;
1381
1406
  const callType = getType(exprNode);
1382
- if (callType === undefined) {
1407
+ if (!callType) {
1383
1408
  return undefined;
1384
1409
  }
1385
1410
  const argList = [];
@@ -1424,7 +1449,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1424
1449
  /* skipUnknownArgCheck */ true);
1425
1450
  });
1426
1451
  signatures.push({
1427
- type,
1452
+ type: expandTypedKwargs(type),
1428
1453
  activeParam: callResult === null || callResult === void 0 ? void 0 : callResult.activeParam,
1429
1454
  });
1430
1455
  }
@@ -1440,44 +1465,46 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1440
1465
  }
1441
1466
  (0, typeUtils_1.doForEachSubtype)(callType, (subtype) => {
1442
1467
  switch (subtype.category) {
1443
- case 5 /* Function */:
1444
- case 6 /* OverloadedFunction */: {
1468
+ case 4 /* Function */:
1469
+ case 5 /* OverloadedFunction */: {
1445
1470
  addFunctionToSignature(subtype);
1446
1471
  break;
1447
1472
  }
1448
- case 7 /* Class */: {
1473
+ case 6 /* Class */: {
1449
1474
  if (types_1.TypeBase.isInstantiable(subtype)) {
1450
- let methodType;
1475
+ let constructorType;
1451
1476
  // Try to get the `__init__` method first because it typically has more
1452
1477
  // type information than `__new__`.
1453
- methodType = getBoundMethod(subtype, '__init__');
1454
- // Is this the __init__ method provided by the object class?
1455
- const isObjectInit = !!methodType &&
1456
- (0, types_1.isFunction)(methodType) &&
1457
- methodType.details.fullName === 'builtins.object.__init__';
1458
- const isDefaultParams = methodType && (0, types_1.isFunction)(methodType) && types_1.FunctionType.hasDefaultParameters(methodType);
1478
+ const initMethodResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, callNode, types_1.ClassType.cloneAsInstance(subtype),
1479
+ /* skipObjectBase */ false);
1480
+ if (initMethodResult && !initMethodResult.typeErrors && (0, types_1.isFunction)(initMethodResult.type)) {
1481
+ constructorType = initMethodResult.type;
1482
+ }
1483
+ const isObjectInit = constructorType &&
1484
+ (0, types_1.isFunction)(constructorType) &&
1485
+ constructorType.details.fullName === 'builtins.object.__init__';
1486
+ const isDefaultParams = constructorType &&
1487
+ (0, types_1.isFunction)(constructorType) &&
1488
+ types_1.FunctionType.hasDefaultParameters(constructorType);
1459
1489
  // If there was no `__init__` or the only `__init__` that was found was from
1460
1490
  // the `object` class or accepts only default parameters(* args, ** kwargs),
1461
1491
  // see if we can find a better signature from the `__new__` method.
1462
- if (!methodType || isObjectInit || isDefaultParams) {
1463
- const constructorType = getBoundMethod(subtype, '__new__',
1464
- /* recursionCount */ undefined,
1465
- /* treatConstructorAsClassMember */ true);
1466
- if (constructorType) {
1467
- // Is this the __new__ method provided by the object class?
1468
- const isObjectNew = (0, types_1.isFunction)(constructorType) &&
1469
- constructorType.details.fullName === 'builtins.object.__new__';
1470
- if (!isObjectNew) {
1471
- methodType = constructorType;
1472
- }
1492
+ if (!constructorType || isObjectInit || isDefaultParams) {
1493
+ const newMethodResult = (0, constructors_1.getBoundNewMethod)(evaluatorInterface, callNode, subtype,
1494
+ /* skipObjectBase */ false);
1495
+ if (newMethodResult &&
1496
+ !newMethodResult.typeErrors &&
1497
+ (0, types_1.isFunction)(newMethodResult.type) &&
1498
+ newMethodResult.type.details.fullName !== 'builtins.object.__new__') {
1499
+ constructorType = newMethodResult.type;
1473
1500
  }
1474
1501
  }
1475
- if (methodType) {
1476
- addFunctionToSignature(methodType);
1502
+ if (constructorType) {
1503
+ addFunctionToSignature(constructorType);
1477
1504
  }
1478
1505
  }
1479
1506
  else {
1480
- const methodType = getBoundMethod(subtype, '__call__');
1507
+ const methodType = getBoundMagicMethod(subtype, '__call__');
1481
1508
  if (methodType) {
1482
1509
  addFunctionToSignature(methodType);
1483
1510
  }
@@ -1494,6 +1521,48 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1494
1521
  signatures,
1495
1522
  };
1496
1523
  }
1524
+ // If the function includes a `**kwargs: Unpack[TypedDict]` parameter, the
1525
+ // parameter is expanded to include individual keyword args.
1526
+ function expandTypedKwargs(functionType) {
1527
+ var _a;
1528
+ const kwargsIndex = functionType.details.parameters.findIndex((param) => param.category === 2 /* KwargsDict */);
1529
+ if (kwargsIndex < 0) {
1530
+ return functionType;
1531
+ }
1532
+ (0, debug_1.assert)(kwargsIndex === functionType.details.parameters.length - 1);
1533
+ const kwargsType = types_1.FunctionType.getEffectiveParameterType(functionType, kwargsIndex);
1534
+ if (!(0, types_1.isClassInstance)(kwargsType) || !types_1.ClassType.isTypedDictClass(kwargsType) || !kwargsType.isUnpacked) {
1535
+ return functionType;
1536
+ }
1537
+ const tdEntries = (_a = kwargsType.typedDictNarrowedEntries) !== null && _a !== void 0 ? _a : kwargsType.details.typedDictEntries;
1538
+ if (!tdEntries) {
1539
+ return functionType;
1540
+ }
1541
+ const newFunction = types_1.FunctionType.clone(functionType);
1542
+ newFunction.details.parameters.splice(kwargsIndex);
1543
+ if (newFunction.specializedTypes) {
1544
+ newFunction.specializedTypes.parameterTypes.splice(kwargsIndex);
1545
+ }
1546
+ const kwSeparatorIndex = functionType.details.parameters.findIndex((param) => param.category === 1 /* ArgsList */);
1547
+ // Add a keyword separator if necessary.
1548
+ if (kwSeparatorIndex < 0) {
1549
+ types_1.FunctionType.addParameter(newFunction, {
1550
+ category: 1 /* ArgsList */,
1551
+ type: types_1.AnyType.create(),
1552
+ });
1553
+ }
1554
+ tdEntries.forEach((tdEntry, name) => {
1555
+ types_1.FunctionType.addParameter(newFunction, {
1556
+ category: 0 /* Simple */,
1557
+ name,
1558
+ hasDeclaredType: true,
1559
+ type: tdEntry.valueType,
1560
+ hasDefault: !tdEntry.isRequired,
1561
+ defaultType: tdEntry.valueType,
1562
+ });
1563
+ });
1564
+ return newFunction;
1565
+ }
1497
1566
  // Determines whether the specified expression is an explicit TypeAlias declaration.
1498
1567
  function isDeclaredTypeAlias(expression) {
1499
1568
  if (expression.nodeType === 54 /* TypeAnnotation */) {
@@ -1530,8 +1599,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1530
1599
  if (enclosingClass && enclosingClass.nodeType === 10 /* Class */) {
1531
1600
  const classTypeInfo = getTypeOfClass(enclosingClass);
1532
1601
  if (classTypeInfo) {
1533
- const classMemberInfo = (0, typeUtils_1.lookUpClassMember)(classTypeInfo.classType, expression.value, 8 /* SkipInstanceVariables */ |
1534
- 32 /* DeclaredTypesOnly */);
1602
+ const classMemberInfo = (0, typeUtils_1.lookUpClassMember)(classTypeInfo.classType, expression.value, 16 /* SkipInstanceMembers */ | 64 /* DeclaredTypesOnly */);
1535
1603
  if (classMemberInfo) {
1536
1604
  symbol = classMemberInfo.symbol;
1537
1605
  }
@@ -1548,7 +1616,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1548
1616
  const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.leftExpression, 16777218 /* MemberAccessBaseDefaults */).type);
1549
1617
  let classMemberInfo;
1550
1618
  if ((0, types_1.isClassInstance)(baseType)) {
1551
- classMemberInfo = (0, typeUtils_1.lookUpObjectMember)(baseType, expression.memberName.value, 32 /* DeclaredTypesOnly */);
1619
+ classMemberInfo = (0, typeUtils_1.lookUpObjectMember)(baseType, expression.memberName.value, 64 /* DeclaredTypesOnly */);
1552
1620
  classOrObjectBase = baseType;
1553
1621
  memberAccessClass = classMemberInfo === null || classMemberInfo === void 0 ? void 0 : classMemberInfo.classType;
1554
1622
  // If this is an instance member (e.g. a dataclass field), don't
@@ -1559,7 +1627,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1559
1627
  useDescriptorSetterType = true;
1560
1628
  }
1561
1629
  else if ((0, types_1.isInstantiableClass)(baseType)) {
1562
- classMemberInfo = (0, typeUtils_1.lookUpClassMember)(baseType, expression.memberName.value, 8 /* SkipInstanceVariables */ | 32 /* DeclaredTypesOnly */);
1630
+ classMemberInfo = (0, typeUtils_1.lookUpClassMember)(baseType, expression.memberName.value, 16 /* SkipInstanceMembers */ | 64 /* DeclaredTypesOnly */);
1563
1631
  classOrObjectBase = baseType;
1564
1632
  memberAccessClass = classMemberInfo === null || classMemberInfo === void 0 ? void 0 : classMemberInfo.classType;
1565
1633
  }
@@ -1571,20 +1639,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1571
1639
  case 24 /* Index */: {
1572
1640
  const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.baseExpression, 2 /* IndexBaseDefaults */).type);
1573
1641
  if (baseType && (0, types_1.isClassInstance)(baseType)) {
1574
- const setItemMember = (0, typeUtils_1.lookUpClassMember)(baseType, '__setitem__');
1575
- if (setItemMember) {
1576
- const setItemType = getTypeOfMember(setItemMember);
1577
- if ((0, types_1.isFunction)(setItemType)) {
1578
- const boundFunction = bindFunctionToClassOrObjectWithErrors(baseType, setItemType, (0, types_1.isInstantiableClass)(setItemMember.classType) ? setItemMember.classType : undefined, expression,
1579
- /* treatConstructorAsClassMember */ false);
1580
- if (boundFunction && (0, types_1.isFunction)(boundFunction)) {
1581
- if (boundFunction.details.parameters.length >= 2) {
1582
- const paramType = types_1.FunctionType.getEffectiveParameterType(boundFunction, 1);
1583
- if (!(0, types_1.isAnyOrUnknown)(paramType)) {
1584
- return paramType;
1585
- }
1586
- }
1587
- }
1642
+ const setItemType = getBoundMagicMethod(baseType, '__setitem__');
1643
+ if (setItemType && (0, types_1.isFunction)(setItemType) && setItemType.details.parameters.length >= 2) {
1644
+ const paramType = types_1.FunctionType.getEffectiveParameterType(setItemType, 1);
1645
+ if (!(0, types_1.isAnyOrUnknown)(paramType)) {
1646
+ return paramType;
1588
1647
  }
1589
1648
  }
1590
1649
  else if (types_1.ClassType.isTypedDictClass(baseType)) {
@@ -1602,14 +1661,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1602
1661
  if (declaredType) {
1603
1662
  // If it's a descriptor, we need to get the setter type.
1604
1663
  if (useDescriptorSetterType && (0, types_1.isClassInstance)(declaredType)) {
1605
- const setterInfo = (0, typeUtils_1.lookUpClassMember)(declaredType, '__set__');
1606
- const setter = setterInfo ? getTypeOfMember(setterInfo) : undefined;
1607
- if (setterInfo && setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 3) {
1608
- declaredType = setter.details.parameters[2].type;
1609
- if ((0, types_1.isClass)(setterInfo.classType)) {
1610
- const typeVarMap = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(setterInfo.classType);
1611
- declaredType = (0, typeUtils_1.applySolvedTypeVars)(declaredType, typeVarMap);
1612
- }
1664
+ const setter = getBoundMagicMethod(declaredType, '__set__');
1665
+ if (setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 2) {
1666
+ declaredType = setter.details.parameters[1].type;
1613
1667
  if ((0, types_1.isAnyOrUnknown)(declaredType)) {
1614
1668
  return undefined;
1615
1669
  }
@@ -1621,8 +1675,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1621
1675
  }
1622
1676
  if ((0, types_1.isFunction)(declaredType) || (0, types_1.isOverloadedFunction)(declaredType)) {
1623
1677
  if (bindFunction) {
1624
- declaredType = bindFunctionToClassOrObjectWithErrors(classOrObjectBase, declaredType,
1625
- /* memberAccessClass */ undefined, expression);
1678
+ declaredType = bindFunctionToClassOrObject(classOrObjectBase, declaredType);
1626
1679
  }
1627
1680
  }
1628
1681
  }
@@ -1668,17 +1721,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1668
1721
  }
1669
1722
  // Validates that the type is an iterator and returns the iterated type
1670
1723
  // (i.e. the type returned from the '__next__' or '__anext__' method).
1671
- function getTypeOfIterator(typeResult, isAsync, errorNode) {
1724
+ function getTypeOfIterator(typeResult, isAsync, errorNode, emitNotIterableError = true) {
1672
1725
  const iterMethodName = isAsync ? '__aiter__' : '__iter__';
1673
1726
  const nextMethodName = isAsync ? '__anext__' : '__next__';
1674
1727
  let isValidIterator = true;
1675
1728
  let type = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(typeResult.type);
1676
1729
  type = makeTopLevelTypeVarsConcrete(type);
1677
1730
  if ((0, typeUtils_1.isOptionalType)(type)) {
1678
- if (errorNode && !typeResult.isIncomplete) {
1731
+ if (!typeResult.isIncomplete && emitNotIterableError) {
1679
1732
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalIterable, diagnosticRules_1.DiagnosticRule.reportOptionalIterable, localize_1.Localizer.Diagnostic.noneNotIterable(), errorNode);
1680
1733
  }
1681
- type = (0, types_1.removeNoneFromUnion)(type);
1734
+ type = (0, typeUtils_1.removeNoneFromUnion)(type);
1682
1735
  }
1683
1736
  const iterableType = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
1684
1737
  subtype = makeTopLevelTypeVarsConcrete(subtype);
@@ -1687,33 +1740,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1687
1740
  }
1688
1741
  const diag = new diagnostic_1.DiagnosticAddendum();
1689
1742
  if ((0, types_1.isClass)(subtype)) {
1690
- let iterReturnType;
1691
- if (types_1.TypeBase.isInstance(subtype)) {
1692
- // Handle an empty tuple specially.
1693
- if ((0, typeUtils_1.isTupleClass)(subtype) &&
1694
- subtype.tupleTypeArguments &&
1695
- subtype.tupleTypeArguments.length === 0) {
1696
- return types_1.NeverType.createNever();
1697
- }
1698
- iterReturnType = getSpecializedReturnType(subtype, iterMethodName, [], errorNode);
1699
- }
1700
- else if (types_1.TypeBase.isInstantiable(subtype) &&
1701
- subtype.details.effectiveMetaclass &&
1702
- (0, types_1.isInstantiableClass)(subtype.details.effectiveMetaclass)) {
1703
- iterReturnType = getSpecializedReturnType(types_1.ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), iterMethodName, [], errorNode, subtype);
1704
- }
1743
+ // Handle an empty tuple specially.
1744
+ if (types_1.TypeBase.isInstance(subtype) &&
1745
+ (0, typeUtils_1.isTupleClass)(subtype) &&
1746
+ subtype.tupleTypeArguments &&
1747
+ subtype.tupleTypeArguments.length === 0) {
1748
+ return types_1.NeverType.createNever();
1749
+ }
1750
+ const iterReturnType = getTypeOfMagicMethodCall(subtype, iterMethodName, [], errorNode);
1705
1751
  if (!iterReturnType) {
1706
1752
  // There was no __iter__. See if we can fall back to
1707
1753
  // the __getitem__ method instead.
1708
1754
  if (!isAsync && (0, types_1.isClassInstance)(subtype)) {
1709
- const getItemReturnType = getSpecializedReturnType(subtype, '__getitem__', [
1755
+ const getItemReturnType = getTypeOfMagicMethodCall(subtype, '__getitem__', [
1710
1756
  {
1711
- argumentCategory: 0 /* Simple */,
1712
- typeResult: {
1713
- type: intClassType && (0, types_1.isInstantiableClass)(intClassType)
1714
- ? types_1.ClassType.cloneAsInstance(intClassType)
1715
- : types_1.UnknownType.create(),
1716
- },
1757
+ type: intClassType && (0, types_1.isInstantiableClass)(intClassType)
1758
+ ? types_1.ClassType.cloneAsInstance(intClassType)
1759
+ : types_1.UnknownType.create(),
1717
1760
  },
1718
1761
  ], errorNode);
1719
1762
  if (getItemReturnType) {
@@ -1730,7 +1773,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1730
1773
  return subtype;
1731
1774
  }
1732
1775
  if ((0, types_1.isClassInstance)(subtype)) {
1733
- let nextReturnType = getSpecializedReturnType(subtype, nextMethodName, [], errorNode);
1776
+ let nextReturnType = getTypeOfMagicMethodCall(subtype, nextMethodName, [], errorNode);
1734
1777
  if (!nextReturnType) {
1735
1778
  iterReturnTypeDiag.addMessage(localize_1.Localizer.Diagnostic.methodNotDefinedOnType().format({
1736
1779
  name: nextMethodName,
@@ -1765,7 +1808,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1765
1808
  diag.addAddendum(iterReturnTypeDiag);
1766
1809
  }
1767
1810
  }
1768
- if (errorNode && !typeResult.isIncomplete) {
1811
+ if (!typeResult.isIncomplete && emitNotIterableError) {
1769
1812
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIterable().format({ type: printType(subtype) }) + diag.getString(), errorNode);
1770
1813
  }
1771
1814
  isValidIterator = false;
@@ -1774,35 +1817,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1774
1817
  return isValidIterator ? { type: iterableType, isIncomplete: typeResult.isIncomplete } : undefined;
1775
1818
  }
1776
1819
  // Validates that the type is an iterable and returns the iterable type argument.
1777
- function getTypeOfIterable(typeResult, isAsync, errorNode) {
1820
+ function getTypeOfIterable(typeResult, isAsync, errorNode, emitNotIterableError = true) {
1778
1821
  const iterMethodName = isAsync ? '__aiter__' : '__iter__';
1779
1822
  let isValidIterable = true;
1780
1823
  let type = makeTopLevelTypeVarsConcrete(typeResult.type);
1781
1824
  if ((0, typeUtils_1.isOptionalType)(type)) {
1782
- if (errorNode && !typeResult.isIncomplete) {
1825
+ if (!typeResult.isIncomplete && emitNotIterableError) {
1783
1826
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalIterable, diagnosticRules_1.DiagnosticRule.reportOptionalIterable, localize_1.Localizer.Diagnostic.noneNotIterable(), errorNode);
1784
1827
  }
1785
- type = (0, types_1.removeNoneFromUnion)(type);
1828
+ type = (0, typeUtils_1.removeNoneFromUnion)(type);
1786
1829
  }
1787
1830
  const iterableType = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
1788
1831
  if ((0, types_1.isAnyOrUnknown)(subtype)) {
1789
1832
  return subtype;
1790
1833
  }
1791
1834
  if ((0, types_1.isClass)(subtype)) {
1792
- let iterReturnType;
1793
- if (types_1.TypeBase.isInstance(subtype)) {
1794
- iterReturnType = getSpecializedReturnType(subtype, iterMethodName, [], errorNode);
1795
- }
1796
- else if (types_1.TypeBase.isInstantiable(subtype) &&
1797
- subtype.details.effectiveMetaclass &&
1798
- (0, types_1.isInstantiableClass)(subtype.details.effectiveMetaclass)) {
1799
- iterReturnType = getSpecializedReturnType(types_1.ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), iterMethodName, [], errorNode, subtype);
1800
- }
1835
+ const iterReturnType = getTypeOfMagicMethodCall(subtype, iterMethodName, [], errorNode);
1801
1836
  if (iterReturnType) {
1802
1837
  return makeTopLevelTypeVarsConcrete(iterReturnType);
1803
1838
  }
1804
1839
  }
1805
- if (errorNode) {
1840
+ if (emitNotIterableError) {
1806
1841
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIterable().format({ type: printType(subtype) }), errorNode);
1807
1842
  }
1808
1843
  isValidIterable = false;
@@ -1828,7 +1863,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1828
1863
  // Handle the case where the type is synthesized (used for
1829
1864
  // dataclasses).
1830
1865
  if (synthesizedType) {
1831
- isObjectHashable = !(0, types_1.isNoneInstance)(synthesizedType);
1866
+ isObjectHashable = !(0, typeUtils_1.isNoneInstance)(synthesizedType);
1832
1867
  }
1833
1868
  else {
1834
1869
  // Assume that if '__hash__' is declared as a variable, it is
@@ -1851,13 +1886,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1851
1886
  return isTypeHashable;
1852
1887
  }
1853
1888
  function getTypedDictClassType() {
1854
- return typedDictPrivateClassType;
1889
+ return typedDictPrivateClassType && (0, types_1.isInstantiableClass)(typedDictPrivateClassType)
1890
+ ? typedDictPrivateClassType
1891
+ : undefined;
1855
1892
  }
1856
1893
  function getTupleClassType() {
1857
- return tupleClassType;
1894
+ return tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType) ? tupleClassType : undefined;
1858
1895
  }
1859
1896
  function getObjectType() {
1860
- return objectType;
1897
+ return objectType !== null && objectType !== void 0 ? objectType : types_1.UnknownType.create();
1898
+ }
1899
+ function getNoneType() {
1900
+ return noneType !== null && noneType !== void 0 ? noneType : types_1.UnknownType.create();
1861
1901
  }
1862
1902
  function getTypingType(node, symbolName) {
1863
1903
  var _a;
@@ -2192,7 +2232,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2192
2232
  }
2193
2233
  const classTypeInfo = getTypeOfClass(classDef);
2194
2234
  if (classTypeInfo && (0, types_1.isInstantiableClass)(classTypeInfo.classType)) {
2195
- let memberInfo = (0, typeUtils_1.lookUpClassMember)(classTypeInfo.classType, memberName, isInstanceMember ? 0 /* Default */ : 8 /* SkipInstanceVariables */);
2235
+ let memberInfo = (0, typeUtils_1.lookUpClassMember)(classTypeInfo.classType, memberName, isInstanceMember ? 0 /* Default */ : 16 /* SkipInstanceMembers */);
2196
2236
  const memberFields = classTypeInfo.classType.details.fields;
2197
2237
  if (memberInfo) {
2198
2238
  // Are we accessing an existing member on this class, or is
@@ -2210,7 +2250,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2210
2250
  // Determine whether the assignment corresponds to a descriptor
2211
2251
  // that was assigned as a class variable. If so, then slots will not
2212
2252
  // apply in this case.
2213
- const classMemberDetails = (0, typeUtils_1.lookUpClassMember)(memberClass, memberName, 8 /* SkipInstanceVariables */);
2253
+ const classMemberDetails = (0, typeUtils_1.lookUpClassMember)(memberClass, memberName, 16 /* SkipInstanceMembers */);
2214
2254
  let isPotentiallyDescriptor = false;
2215
2255
  if (classMemberDetails) {
2216
2256
  const classMemberSymbolType = getEffectiveTypeOfSymbol(classMemberDetails.symbol);
@@ -2257,7 +2297,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2257
2297
  }
2258
2298
  }
2259
2299
  // Look up the member info again, now that we've potentially updated it.
2260
- memberInfo = (0, typeUtils_1.lookUpClassMember)(classTypeInfo.classType, memberName, 32 /* DeclaredTypesOnly */);
2300
+ memberInfo = (0, typeUtils_1.lookUpClassMember)(classTypeInfo.classType, memberName, 64 /* DeclaredTypesOnly */);
2261
2301
  if (!memberInfo && srcExprNode && !isTypeIncomplete) {
2262
2302
  reportPossibleUnknownAssignment(fileInfo.diagnosticRuleSet.reportUnknownMemberType, diagnosticRules_1.DiagnosticRule.reportUnknownMemberType, node.memberName, srcType, node,
2263
2303
  /* ignoreEmptyContainers */ true);
@@ -2388,6 +2428,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2388
2428
  // TypeVar, only the conditions that match the filter will be included.
2389
2429
  function makeTopLevelTypeVarsConcrete(type, makeParamSpecsConcrete = false, conditionFilter) {
2390
2430
  return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
2431
+ var _a, _b;
2391
2432
  if ((0, types_1.isParamSpec)(subtype)) {
2392
2433
  if (subtype.paramSpecAccess === 'args') {
2393
2434
  if (tupleClassType &&
@@ -2443,22 +2484,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2443
2484
  }
2444
2485
  }
2445
2486
  if ((0, types_1.isTypeVar)(subtype) && !subtype.details.recursiveTypeAliasName) {
2446
- if (subtype.details.boundType) {
2447
- const boundType = types_1.TypeBase.isInstantiable(subtype)
2448
- ? (0, typeUtils_1.convertToInstantiable)(subtype.details.boundType)
2449
- : subtype.details.boundType;
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
- }
2462
2487
  // If this is a recursive type alias placeholder
2463
2488
  // that hasn't yet been resolved, return it as is.
2464
2489
  if (subtype.details.recursiveTypeAliasName) {
@@ -2494,32 +2519,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2494
2519
  if (subtype.details.isExemptFromBoundCheck) {
2495
2520
  return types_1.AnyType.create();
2496
2521
  }
2497
- // Convert to an "object" or "type" instance depending on whether
2498
- // it's instantiable.
2499
- if (types_1.TypeBase.isInstantiable(subtype)) {
2500
- if (typeClassType && (0, types_1.isInstantiableClass)(typeClassType)) {
2501
- return subtype.details.isSynthesized
2502
- ? typeClassType
2503
- : (0, typeUtils_1.addConditionToType)(types_1.ClassType.cloneAsInstance(typeClassType), [
2504
- {
2505
- typeVarName: types_1.TypeVarType.getNameWithScope(subtype),
2506
- constraintIndex: 0,
2507
- isConstrainedTypeVar: false,
2508
- },
2509
- ]);
2510
- }
2511
- }
2512
- else if (objectType) {
2513
- return subtype.details.isSynthesized
2514
- ? objectType
2515
- : (0, typeUtils_1.addConditionToType)(objectType, [
2516
- {
2517
- typeVarName: types_1.TypeVarType.getNameWithScope(subtype),
2518
- constraintIndex: 0,
2519
- isConstrainedTypeVar: false,
2520
- },
2521
- ]);
2522
+ // Fall back to a bound of "object" if no bound is provided.
2523
+ let boundType = (_b = (_a = subtype.details.boundType) !== null && _a !== void 0 ? _a : objectType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
2524
+ boundType = types_1.TypeBase.isInstantiable(subtype) ? (0, typeUtils_1.convertToInstantiable)(boundType) : boundType;
2525
+ // Handle Self and type[Self] specially.
2526
+ if (subtype.details.isSynthesizedSelf && (0, types_1.isClass)(boundType)) {
2527
+ return types_1.ClassType.cloneIncludeSubclasses(boundType);
2522
2528
  }
2529
+ return (0, typeUtils_1.addConditionToType)(boundType, [
2530
+ {
2531
+ typeVarName: types_1.TypeVarType.getNameWithScope(subtype),
2532
+ constraintIndex: 0,
2533
+ isConstrainedTypeVar: false,
2534
+ },
2535
+ ]);
2523
2536
  return types_1.AnyType.create();
2524
2537
  }
2525
2538
  return subtype;
@@ -2531,7 +2544,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2531
2544
  // its bound type and a constrained TypeVar is expanded to its individual
2532
2545
  // constrained types). If conditionFilter is specified, conditions that
2533
2546
  // do not match will be ignored.
2534
- function mapSubtypesExpandTypeVars(type, conditionFilter, callback, recursionCount = 0) {
2547
+ function mapSubtypesExpandTypeVars(type, conditionFilter, callback, sortSubtypes = false, recursionCount = 0) {
2535
2548
  const newSubtypes = [];
2536
2549
  let typeChanged = false;
2537
2550
  function expandSubtype(unexpandedType, isLastSubtype) {
@@ -2559,10 +2572,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2559
2572
  newSubtypes.push(transformedType);
2560
2573
  }
2561
2574
  return undefined;
2562
- });
2575
+ }, sortSubtypes);
2563
2576
  }
2564
2577
  if ((0, types_1.isUnion)(type)) {
2565
- type.subtypes.forEach((subtype, index) => {
2578
+ const subtypes = sortSubtypes ? (0, typeUtils_1.sortTypes)(type.subtypes) : type.subtypes;
2579
+ subtypes.forEach((subtype, index) => {
2566
2580
  expandSubtype(subtype, index === type.subtypes.length - 1);
2567
2581
  });
2568
2582
  }
@@ -2574,7 +2588,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2574
2588
  }
2575
2589
  const newType = (0, types_1.combineTypes)(newSubtypes);
2576
2590
  // Do our best to retain type aliases.
2577
- if (newType.category === 9 /* Union */) {
2591
+ if (newType.category === 8 /* Union */) {
2578
2592
  types_1.UnionType.addTypeAliasSource(newType, type);
2579
2593
  }
2580
2594
  return newType;
@@ -2604,7 +2618,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2604
2618
  }
2605
2619
  const filteredTypeArg = mapSubtypesExpandTypeVars(typeArg, conditionFilter, (expandedSubtype) => {
2606
2620
  return expandedSubtype;
2607
- }, recursionCount);
2621
+ },
2622
+ /* sortSubtypes */ undefined, recursionCount);
2608
2623
  if (filteredTypeArg !== typeArg) {
2609
2624
  typeWasTransformed = true;
2610
2625
  }
@@ -2835,39 +2850,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2835
2850
  fileInfo.accessedSymbolSet.add(symbol.id);
2836
2851
  }
2837
2852
  }
2838
- function getSpecializedReturnType(objType, memberName, argList, errorNode, bindToClass) {
2839
- const classMember = (0, typeUtils_1.lookUpObjectMember)(objType, memberName, 8 /* SkipInstanceVariables */);
2840
- if (!classMember) {
2841
- return undefined;
2842
- }
2843
- const memberTypeResult = getTypeOfMemberInternal(classMember, objType);
2844
- if (!memberTypeResult) {
2845
- return undefined;
2846
- }
2847
- const memberType = memberTypeResult.type;
2848
- if ((0, types_1.isAnyOrUnknown)(memberType)) {
2849
- return memberType;
2850
- }
2851
- if ((0, types_1.isFunction)(memberType) || (0, types_1.isOverloadedFunction)(memberType)) {
2852
- const methodType = bindFunctionToClassOrObjectWithErrors(bindToClass || objType, memberType, classMember && (0, types_1.isInstantiableClass)(classMember.classType) ? classMember.classType : undefined, errorNode,
2853
- /* treatConstructorAsClassMember */ false,
2854
- /* firstParamType */ bindToClass);
2855
- if (methodType) {
2856
- if ((0, types_1.isOverloadedFunction)(methodType)) {
2857
- if (errorNode) {
2858
- const bestOverload = getBestOverloadForArguments(errorNode, { type: methodType, isIncomplete: memberTypeResult.isIncomplete }, argList);
2859
- if (bestOverload) {
2860
- return getFunctionEffectiveReturnType(bestOverload);
2861
- }
2862
- }
2863
- }
2864
- else {
2865
- return getFunctionEffectiveReturnType(methodType);
2866
- }
2867
- }
2868
- }
2869
- return undefined;
2870
- }
2871
2853
  function getTypeOfName(node, flags) {
2872
2854
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2873
2855
  const name = node.value;
@@ -3330,7 +3312,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3330
3312
  }
3331
3313
  if (typeParametersForScope) {
3332
3314
  const match = typeParametersForScope.find((typeVar) => typeVar.details.name === type.details.name);
3333
- if (match === null || match === void 0 ? void 0 : match.scopeId) {
3315
+ if ((match === null || match === void 0 ? void 0 : match.scopeId) !== undefined && match.scopeName !== undefined && match.scopeType !== undefined) {
3334
3316
  // Use the scoped version of the TypeVar rather than the (unscoped) original type.
3335
3317
  type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
3336
3318
  return {
@@ -3393,6 +3375,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3393
3375
  return { type, isRescoped: false, foundInterveningClass: false };
3394
3376
  }
3395
3377
  function getTypeOfMemberAccess(node, flags) {
3378
+ var _a;
3396
3379
  // Compute flags specifically for evaluating the left expression.
3397
3380
  let leftExprFlags = 16777218 /* MemberAccessBaseDefaults */;
3398
3381
  leftExprFlags |=
@@ -3458,12 +3441,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3458
3441
  if (baseTypeResult.isIncomplete) {
3459
3442
  typeResult.isIncomplete = true;
3460
3443
  }
3444
+ // See if we need to log an "unknown member access" diagnostic.
3445
+ let skipPartialUnknownCheck = typeResult.isIncomplete;
3446
+ // Don't report an error if the type is a partially-specialized
3447
+ // class being passed as an argument. This comes up frequently in
3448
+ // cases where a type is passed as an argument (e.g. "defaultdict(list)").
3449
+ // It can also come up in cases like "isinstance(x, (list, dict))".
3450
+ if ((0, types_1.isInstantiableClass)(typeResult.type)) {
3451
+ const argNode = ParseTreeUtils.getParentNodeOfType(node, 1 /* Argument */);
3452
+ if (argNode && ((_a = argNode === null || argNode === void 0 ? void 0 : argNode.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 9 /* Call */) {
3453
+ skipPartialUnknownCheck = true;
3454
+ }
3455
+ }
3456
+ if (!skipPartialUnknownCheck) {
3457
+ reportPossibleUnknownAssignment(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportUnknownMemberType, diagnosticRules_1.DiagnosticRule.reportUnknownMemberType, node.memberName, typeResult.type, node,
3458
+ /* ignoreEmptyContainers */ false);
3459
+ }
3461
3460
  // Cache the type information in the member name node.
3462
3461
  writeTypeCache(node.memberName, typeResult, flags);
3463
3462
  return typeResult;
3464
3463
  }
3465
3464
  function getTypeOfMemberAccessWithBaseType(node, baseTypeResult, usage, flags) {
3466
- var _a, _b, _c;
3465
+ var _a, _b;
3467
3466
  let baseType = baseTypeResult.type;
3468
3467
  const memberName = node.memberName.value;
3469
3468
  let diag = new diagnostic_1.DiagnosticAddendum();
@@ -3486,113 +3485,90 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3486
3485
  baseType = objectType;
3487
3486
  }
3488
3487
  }
3489
- function getTypeOfNoneBase(subtype) {
3490
- if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
3491
- if (types_1.TypeBase.isInstance(subtype)) {
3492
- return getTypeOfObjectMember(node.memberName, types_1.ClassType.cloneAsInstance(noneType), memberName, usage, diag);
3493
- }
3494
- else {
3495
- return getTypeOfClassMember(node.memberName, noneType, memberName, usage, diag);
3496
- }
3497
- }
3498
- return undefined;
3499
- }
3500
3488
  if ((0, types_1.isParamSpec)(baseType) && baseType.paramSpecAccess) {
3501
3489
  baseType = makeTopLevelTypeVarsConcrete(baseType);
3502
3490
  }
3503
3491
  switch (baseType.category) {
3504
3492
  case 2 /* Any */:
3505
3493
  case 1 /* Unknown */:
3506
- case 4 /* Never */: {
3494
+ case 3 /* Never */: {
3507
3495
  type = baseType;
3508
3496
  break;
3509
3497
  }
3510
- case 10 /* TypeVar */: {
3498
+ case 0 /* Unbound */: {
3499
+ break;
3500
+ }
3501
+ case 9 /* TypeVar */: {
3511
3502
  if (baseType.details.isParamSpec) {
3512
- if (memberName === 'args') {
3513
- const paramNode = ParseTreeUtils.getEnclosingParameter(node);
3514
- if (!paramNode || paramNode.category !== 1 /* ArgsList */) {
3515
- addError(localize_1.Localizer.Diagnostic.paramSpecArgsUsage(), node);
3516
- return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
3517
- }
3518
- return { type: types_1.TypeVarType.cloneForParamSpecAccess(baseType, 'args'), isIncomplete };
3519
- }
3520
- if (memberName === 'kwargs') {
3503
+ // Handle special cases for "P.args" and "P.kwargs".
3504
+ if (memberName === 'args' || memberName === 'kwargs') {
3505
+ const isArgs = memberName === 'args';
3521
3506
  const paramNode = ParseTreeUtils.getEnclosingParameter(node);
3522
- if (!paramNode || paramNode.category !== 2 /* KwargsDict */) {
3523
- addError(localize_1.Localizer.Diagnostic.paramSpecKwargsUsage(), node);
3524
- return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
3507
+ const expectedCategory = isArgs ? 1 /* ArgsList */ : 2 /* KwargsDict */;
3508
+ if (!paramNode || paramNode.category !== expectedCategory) {
3509
+ const errorMessage = isArgs
3510
+ ? localize_1.Localizer.Diagnostic.paramSpecArgsUsage()
3511
+ : localize_1.Localizer.Diagnostic.paramSpecKwargsUsage();
3512
+ addError(errorMessage, node);
3513
+ type = types_1.UnknownType.create(isIncomplete);
3514
+ break;
3525
3515
  }
3526
- return { type: types_1.TypeVarType.cloneForParamSpecAccess(baseType, 'kwargs'), isIncomplete };
3516
+ type = types_1.TypeVarType.cloneForParamSpecAccess(baseType, memberName);
3517
+ break;
3527
3518
  }
3528
3519
  if (!isIncomplete) {
3529
3520
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecUnknownMember().format({ name: memberName }), node);
3530
3521
  }
3531
- return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
3522
+ type = types_1.UnknownType.create(isIncomplete);
3523
+ break;
3532
3524
  }
3525
+ // It's illegal to reference a member from a type variable.
3533
3526
  if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
3534
3527
  if (!isIncomplete) {
3535
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
3528
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
3536
3529
  type: printType(baseType),
3537
3530
  name: memberName,
3538
3531
  }), node.leftExpression);
3539
3532
  }
3540
- return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
3533
+ type = types_1.UnknownType.create(isIncomplete);
3534
+ break;
3541
3535
  }
3542
3536
  if (baseType.details.recursiveTypeAliasName) {
3543
- return { type: types_1.UnknownType.create(/* isIncomplete */ true), isIncomplete: true };
3537
+ type = types_1.UnknownType.create(/* isIncomplete */ true);
3538
+ isIncomplete = true;
3539
+ break;
3544
3540
  }
3545
- if (!baseType.details.isVariadic) {
3546
- return getTypeOfMemberAccessWithBaseType(node, {
3547
- type: makeTopLevelTypeVarsConcrete(baseType),
3548
- bindToType: baseType,
3549
- isIncomplete,
3550
- }, usage, 0 /* None */);
3541
+ if (baseType.details.isVariadic) {
3542
+ break;
3551
3543
  }
3552
- break;
3544
+ return getTypeOfMemberAccessWithBaseType(node, {
3545
+ type: makeTopLevelTypeVarsConcrete(baseType),
3546
+ bindToSelfType: types_1.TypeBase.isInstantiable(baseType) ? (0, typeUtils_1.convertToInstance)(baseType) : baseType,
3547
+ isIncomplete,
3548
+ }, usage, 0 /* None */);
3553
3549
  }
3554
- case 7 /* Class */: {
3555
- if (types_1.TypeBase.isInstantiable(baseType)) {
3556
- const typeResult = getTypeOfClassMember(node.memberName, baseType, memberName, usage, diag, 0 /* None */, baseTypeResult.bindToType);
3557
- type = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type;
3558
- if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete) {
3559
- isIncomplete = true;
3560
- }
3561
- if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.isAsymmetricAccessor) {
3562
- isAsymmetricAccessor = true;
3563
- }
3564
- if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.memberAccessDeprecationInfo) {
3565
- memberAccessDeprecationInfo = typeResult.memberAccessDeprecationInfo;
3566
- }
3550
+ case 6 /* Class */: {
3551
+ const typeResult = (_a = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete)) !== null && _a !== void 0 ? _a : getTypeOfBoundMember(node.memberName, baseType, memberName, usage, diag,
3552
+ /* memberAccessFlags */ undefined, baseTypeResult.bindToSelfType);
3553
+ if (typeResult) {
3554
+ type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
3567
3555
  }
3568
- else {
3569
- // Handle the special case of 'name' and 'value' members within an enum.
3570
- const enumMemberResult = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete);
3571
- if (enumMemberResult) {
3572
- return enumMemberResult;
3573
- }
3574
- const typeResult = getTypeOfObjectMember(node.memberName, baseType, memberName, usage, diag,
3575
- /* memberAccessFlags */ undefined, baseTypeResult.bindToType);
3576
- if (typeResult) {
3577
- type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
3578
- }
3579
- if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete) {
3580
- isIncomplete = true;
3581
- }
3582
- if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.isAsymmetricAccessor) {
3583
- isAsymmetricAccessor = true;
3584
- }
3585
- if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.memberAccessDeprecationInfo) {
3586
- memberAccessDeprecationInfo = typeResult.memberAccessDeprecationInfo;
3587
- }
3556
+ if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete) {
3557
+ isIncomplete = true;
3558
+ }
3559
+ if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.isAsymmetricAccessor) {
3560
+ isAsymmetricAccessor = true;
3561
+ }
3562
+ if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.memberAccessDeprecationInfo) {
3563
+ memberAccessDeprecationInfo = typeResult.memberAccessDeprecationInfo;
3588
3564
  }
3589
3565
  break;
3590
3566
  }
3591
- case 8 /* Module */: {
3567
+ case 7 /* Module */: {
3592
3568
  const symbol = types_1.ModuleType.getField(baseType, memberName);
3593
3569
  if (symbol && !symbol.isExternallyHidden()) {
3594
3570
  if (usage.method === 'get') {
3595
- setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(node), symbol, node.memberName);
3571
+ setSymbolAccessed(fileInfo, symbol, node.memberName);
3596
3572
  }
3597
3573
  type = getEffectiveTypeOfSymbolForUsage(symbol,
3598
3574
  /* usageNode */ undefined,
@@ -3608,12 +3584,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3608
3584
  type = types_1.UnknownType.create(/* isIncomplete */ true);
3609
3585
  }
3610
3586
  if (symbol.isPrivateMember()) {
3611
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportPrivateUsage, diagnosticRules_1.DiagnosticRule.reportPrivateUsage, localize_1.Localizer.Diagnostic.privateUsedOutsideOfModule().format({
3587
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportPrivateUsage, diagnosticRules_1.DiagnosticRule.reportPrivateUsage, localize_1.Localizer.Diagnostic.privateUsedOutsideOfModule().format({
3612
3588
  name: memberName,
3613
3589
  }), node.memberName);
3614
3590
  }
3615
3591
  if (symbol.isPrivatePyTypedImport()) {
3616
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportPrivateImportUsage, diagnosticRules_1.DiagnosticRule.reportPrivateImportUsage, localize_1.Localizer.Diagnostic.privateImportFromPyTypedModule().format({
3592
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportPrivateImportUsage, diagnosticRules_1.DiagnosticRule.reportPrivateImportUsage, localize_1.Localizer.Diagnostic.privateImportFromPyTypedModule().format({
3617
3593
  name: memberName,
3618
3594
  module: baseType.moduleName,
3619
3595
  }), node.memberName);
@@ -3656,10 +3632,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3656
3632
  }
3657
3633
  break;
3658
3634
  }
3659
- case 9 /* Union */: {
3635
+ case 8 /* Union */: {
3660
3636
  type = (0, typeUtils_1.mapSubtypes)(baseType, (subtype) => {
3661
- if ((0, types_1.isNoneInstance)(subtype)) {
3662
- const typeResult = getTypeOfNoneBase(subtype);
3637
+ if ((0, types_1.isUnbound)(subtype)) {
3638
+ // Don't do anything if it's unbound. The error will already
3639
+ // be reported elsewhere.
3640
+ return undefined;
3641
+ }
3642
+ if ((0, typeUtils_1.isNoneInstance)(subtype) && noneType && (0, types_1.isClassInstance)(noneType)) {
3643
+ const typeResult = getTypeOfBoundMember(node.memberName, noneType, memberName, usage, diag);
3663
3644
  if (typeResult) {
3664
3645
  type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
3665
3646
  if (typeResult.isIncomplete) {
@@ -3667,42 +3648,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3667
3648
  }
3668
3649
  return type;
3669
3650
  }
3670
- else {
3671
- if (!isIncomplete) {
3672
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalMemberAccess, diagnosticRules_1.DiagnosticRule.reportOptionalMemberAccess, localize_1.Localizer.Diagnostic.noneUnknownMember().format({ name: memberName }), node.memberName);
3673
- }
3674
- return undefined;
3651
+ if (!isIncomplete) {
3652
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportOptionalMemberAccess, diagnosticRules_1.DiagnosticRule.reportOptionalMemberAccess, localize_1.Localizer.Diagnostic.noneUnknownMember().format({ name: memberName }), node.memberName);
3675
3653
  }
3676
- }
3677
- else if ((0, types_1.isUnbound)(subtype)) {
3678
- // Don't do anything if it's unbound. The error will already
3679
- // be reported elsewhere.
3680
3654
  return undefined;
3681
3655
  }
3682
- else {
3683
- const typeResult = getTypeOfMemberAccessWithBaseType(node, {
3684
- type: subtype,
3685
- isIncomplete: baseTypeResult.isIncomplete,
3686
- }, usage, 0 /* None */);
3687
- if (typeResult.isIncomplete) {
3688
- isIncomplete = true;
3689
- }
3690
- if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.memberAccessDeprecationInfo) {
3691
- memberAccessDeprecationInfo = typeResult.memberAccessDeprecationInfo;
3692
- }
3693
- return typeResult.type;
3656
+ const typeResult = getTypeOfMemberAccessWithBaseType(node, {
3657
+ type: subtype,
3658
+ isIncomplete: baseTypeResult.isIncomplete,
3659
+ }, usage, 0 /* None */);
3660
+ if (typeResult.isIncomplete) {
3661
+ isIncomplete = true;
3694
3662
  }
3663
+ if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.memberAccessDeprecationInfo) {
3664
+ memberAccessDeprecationInfo = typeResult.memberAccessDeprecationInfo;
3665
+ }
3666
+ return typeResult.type;
3695
3667
  });
3696
3668
  break;
3697
3669
  }
3698
- case 5 /* Function */:
3699
- case 6 /* OverloadedFunction */: {
3700
- if (memberName === '__defaults__') {
3701
- // The "__defaults__" member is not currently defined in the "function"
3702
- // class, so we'll special-case it here.
3703
- type = types_1.AnyType.create();
3704
- }
3705
- else if (memberName === '__self__') {
3670
+ case 4 /* Function */:
3671
+ case 5 /* OverloadedFunction */: {
3672
+ if (memberName === '__self__') {
3706
3673
  // The "__self__" member is not currently defined in the "function"
3707
3674
  // class, so we'll special-case it here.
3708
3675
  const functionType = (0, types_1.isFunction)(baseType) ? baseType : baseType.overloads[0];
@@ -3712,29 +3679,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3712
3679
  }
3713
3680
  }
3714
3681
  else {
3715
- if (!functionObj) {
3716
- type = types_1.AnyType.create();
3717
- }
3718
- else {
3719
- type = getTypeOfMemberAccessWithBaseType(node, { type: functionObj }, usage, flags).type;
3720
- }
3721
- }
3722
- break;
3723
- }
3724
- case 3 /* None */: {
3725
- const typeResult = getTypeOfNoneBase(baseType);
3726
- if (typeResult) {
3727
- type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
3728
- if (typeResult.isIncomplete) {
3729
- isIncomplete = true;
3730
- }
3682
+ type = getTypeOfMemberAccessWithBaseType(node, { type: functionObj !== null && functionObj !== void 0 ? functionObj : types_1.AnyType.create() }, usage, flags).type;
3731
3683
  }
3732
3684
  break;
3733
3685
  }
3734
3686
  default:
3735
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeUnsupported().format({ type: printType(baseType) }));
3736
- break;
3687
+ (0, debug_1.assertNever)(baseType);
3737
3688
  }
3689
+ // If type is undefined, emit a general error message indicating that the
3690
+ // member could not be accessed.
3738
3691
  if (!type) {
3739
3692
  const isFunctionRule = (0, types_1.isFunction)(baseType) ||
3740
3693
  (0, types_1.isOverloadedFunction)(baseType) ||
@@ -3756,7 +3709,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3756
3709
  const [ruleSet, rule] = isFunctionRule
3757
3710
  ? [fileInfo.diagnosticRuleSet.reportFunctionMemberAccess, diagnosticRules_1.DiagnosticRule.reportFunctionMemberAccess]
3758
3711
  : [fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues];
3759
- addDiagnostic(ruleSet, rule, diagMessage.format({ name: memberName, type: printType(baseType) }) + diag.getString(), node.memberName, (_a = diag.getEffectiveTextRange()) !== null && _a !== void 0 ? _a : node.memberName);
3712
+ addDiagnostic(ruleSet, rule, diagMessage.format({ name: memberName, type: printType(baseType) }) + diag.getString(), node.memberName, (_b = diag.getEffectiveTextRange()) !== null && _b !== void 0 ? _b : node.memberName);
3760
3713
  }
3761
3714
  // If this is member access on a function, use "Any" so if the
3762
3715
  // reportFunctionMemberAccess rule is disabled, we don't trigger
@@ -3766,540 +3719,423 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3766
3719
  if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
3767
3720
  reportUseOfTypeCheckOnly(type, node.memberName);
3768
3721
  }
3769
- // Should we specialize the class?
3770
- if ((flags & 2 /* DoNotSpecialize */) === 0) {
3771
- if ((0, types_1.isInstantiableClass)(type) && !type.typeArguments) {
3772
- type = (_b = createSpecializedClassType(type, /* typeArgs */ undefined, flags, node)) === null || _b === void 0 ? void 0 : _b.type;
3773
- }
3774
- }
3775
- if (usage.method === 'get') {
3776
- let skipPartialUnknownCheck = isIncomplete;
3777
- // Don't report an error if the type is a partially-specialized
3778
- // class being passed as an argument. This comes up frequently in
3779
- // cases where a type is passed as an argument (e.g. "defaultdict(list)").
3780
- // It can also come up in cases like "isinstance(x, (list, dict))".
3781
- if ((0, types_1.isInstantiableClass)(type)) {
3782
- const argNode = ParseTreeUtils.getParentNodeOfType(node, 1 /* Argument */);
3783
- if (argNode && ((_c = argNode === null || argNode === void 0 ? void 0 : argNode.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 9 /* Call */) {
3784
- skipPartialUnknownCheck = true;
3785
- }
3786
- }
3787
- if (!skipPartialUnknownCheck) {
3788
- reportPossibleUnknownAssignment(fileInfo.diagnosticRuleSet.reportUnknownMemberType, diagnosticRules_1.DiagnosticRule.reportUnknownMemberType, node.memberName, type, node,
3789
- /* ignoreEmptyContainers */ false);
3790
- }
3791
- }
3792
3722
  return { type, isIncomplete, isAsymmetricAccessor, isRequired, isNotRequired, memberAccessDeprecationInfo };
3793
3723
  }
3794
- function getTypeOfClassMemberName(errorNode, classType, isAccessedThroughObject, memberName, usage, diag, flags, bindToType) {
3795
- var _a, _b;
3796
- let classLookupFlags = 0 /* Default */;
3797
- if (flags & 1 /* AccessClassMembersOnly */) {
3798
- classLookupFlags |= 8 /* SkipInstanceVariables */;
3799
- }
3800
- if (flags & 2 /* AccessInstanceMembersOnly */) {
3801
- classLookupFlags |= 16 /* SkipClassVariables */;
3802
- }
3803
- if (flags & 4 /* SkipBaseClasses */) {
3804
- classLookupFlags |= 2 /* SkipBaseClasses */;
3805
- }
3806
- if (flags & 8 /* SkipObjectBaseClass */) {
3807
- classLookupFlags |= 4 /* SkipObjectBaseClass */;
3808
- }
3809
- if (flags & 512 /* SkipTypeBaseClass */) {
3810
- classLookupFlags |= 64 /* SkipTypeBaseClass */;
3811
- }
3812
- if (flags & 256 /* SkipOriginalClass */) {
3813
- classLookupFlags |= 1 /* SkipOriginalClass */;
3814
- }
3724
+ function getTypeOfClassMemberName(errorNode, classType, memberName, usage, diag, flags, selfType, recursionCount = 0) {
3725
+ var _a, _b, _c;
3726
+ const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
3815
3727
  // Always look for a member with a declared type first.
3816
- let memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, classLookupFlags | 32 /* DeclaredTypesOnly */);
3728
+ let memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, flags | 64 /* DeclaredTypesOnly */);
3817
3729
  // If we couldn't find a symbol with a declared type, use
3818
3730
  // a symbol with an inferred type.
3819
3731
  if (!memberInfo) {
3820
- memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, classLookupFlags);
3732
+ memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, flags);
3821
3733
  }
3822
- if (memberInfo) {
3823
- let type;
3824
- let isTypeIncomplete = false;
3825
- if (memberInfo.symbol.isInitVar()) {
3826
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsInitVar().format({ name: memberName }));
3827
- return undefined;
3828
- }
3829
- if (usage.method !== 'get') {
3830
- // If the usage indicates a 'set' or 'delete' and the access is within the
3831
- // class definition itself, use only the declared type to avoid circular
3832
- // type evaluation.
3833
- const containingClass = ParseTreeUtils.getEnclosingClass(errorNode);
3834
- if (containingClass) {
3835
- const containingClassType = (_a = getTypeOfClass(containingClass)) === null || _a === void 0 ? void 0 : _a.classType;
3836
- if (containingClassType &&
3837
- (0, types_1.isInstantiableClass)(containingClassType) &&
3838
- types_1.ClassType.isSameGenericClass(containingClassType, classType)) {
3839
- type = (_b = getDeclaredTypeOfSymbol(memberInfo.symbol)) === null || _b === void 0 ? void 0 : _b.type;
3840
- if (type && (0, types_1.isInstantiableClass)(memberInfo.classType)) {
3841
- type = (0, typeUtils_1.partiallySpecializeType)(type, memberInfo.classType);
3842
- }
3843
- // If we're setting a class variable via a write through an object,
3844
- // this is normally considered a type violation. But it is allowed
3845
- // if the class variable is a descriptor object. In this case, we will
3846
- // clear the flag that causes an error to be generated.
3847
- if (usage.method === 'set' && memberInfo.symbol.isClassVar() && isAccessedThroughObject) {
3848
- const selfClass = bindToType || memberName === '__new__' ? undefined : classType;
3849
- const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3850
- if (typeResult) {
3851
- if ((0, typeUtils_1.isDescriptorInstance)(typeResult.type, /* requireSetter */ true)) {
3852
- type = typeResult.type;
3853
- flags &= 16 /* DisallowClassVarWrites */;
3854
- }
3855
- }
3856
- }
3857
- if (!type) {
3858
- type = types_1.UnknownType.create();
3859
- }
3860
- }
3861
- }
3862
- }
3863
- if (!type) {
3864
- let selfClass = classType;
3865
- // Determine whether to replace Self variables with a specific
3866
- // class. Avoid doing this if there's a "bindToType" specified
3867
- // because that case is used for super() calls where we want
3868
- // to leave the Self type generic (not specialized). We'll also
3869
- // skip this for __new__ methods because they are not bound
3870
- // to the class but rather assume the type of the cls argument.
3871
- if (bindToType) {
3872
- if ((0, types_1.isTypeVar)(bindToType) && bindToType.details.isSynthesizedSelf) {
3873
- selfClass = bindToType;
3874
- }
3875
- else {
3876
- selfClass = undefined;
3877
- }
3878
- }
3879
- else if (memberName === '__new__') {
3880
- selfClass = undefined;
3881
- }
3882
- const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3883
- if (typeResult) {
3884
- type = typeResult.type;
3885
- if (typeResult.isIncomplete) {
3886
- isTypeIncomplete = true;
3887
- }
3888
- }
3889
- else {
3890
- type = types_1.UnknownType.create();
3891
- }
3892
- }
3893
- // Don't include variables within typed dict classes.
3894
- if ((0, types_1.isClass)(memberInfo.classType) && types_1.ClassType.isTypedDictClass(memberInfo.classType)) {
3895
- const typedDecls = memberInfo.symbol.getTypedDeclarations();
3896
- if (typedDecls.length > 0 && typedDecls[0].type === 1 /* Variable */) {
3897
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberUnknown().format({ name: memberName }));
3898
- return undefined;
3899
- }
3900
- }
3901
- if (usage.method === 'get') {
3902
- // Mark the member accessed if it's not coming from a parent class.
3903
- if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3904
- types_1.ClassType.isSameGenericClass(memberInfo.classType, classType)) {
3905
- setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
3906
- }
3907
- // Special-case `__init_subclass` and `__class_getitem__` because
3908
- // these are always treated as class methods even if they're not
3909
- // decorated as such.
3910
- if (memberName === '__init_subclass__' || memberName === '__class_getitem__') {
3911
- if ((0, types_1.isFunction)(type) && !types_1.FunctionType.isClassMethod(type)) {
3912
- type = types_1.FunctionType.cloneWithNewFlags(type, type.details.flags | 2 /* ClassMethod */);
3913
- }
3914
- }
3915
- }
3916
- const descriptorResult = applyDescriptorAccessMethod(type, memberInfo, classType, bindToType, isAccessedThroughObject, flags, errorNode, memberName, usage, diag);
3917
- if (!descriptorResult) {
3918
- return undefined;
3919
- }
3920
- type = descriptorResult.type;
3921
- let isSetTypeError = false;
3922
- if (usage.method === 'set' && usage.setType) {
3923
- // Verify that the assigned type is compatible.
3924
- if (!assignType(type, usage.setType.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum())) {
3925
- if (!usage.setType.isIncomplete) {
3926
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberAssignment().format({
3927
- type: printType(usage.setType.type),
3928
- name: memberName,
3929
- classType: printObjectTypeForClass(classType),
3930
- }));
3931
- }
3932
- isSetTypeError = true;
3933
- }
3934
- if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3935
- types_1.ClassType.isFrozenDataClass(memberInfo.classType) &&
3936
- isAccessedThroughObject) {
3937
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.dataClassFrozen().format({
3938
- name: printType(types_1.ClassType.cloneAsInstance(memberInfo.classType)),
3939
- }));
3940
- isSetTypeError = true;
3734
+ if (!memberInfo) {
3735
+ // No attribute of that name was found. If this is a member access
3736
+ // through an object, see if there's an attribute access override
3737
+ // method ("__getattr__", etc.).
3738
+ if ((flags & 512 /* SkipAttributeAccessOverride */) === 0 && errorNode) {
3739
+ const generalAttrType = applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType);
3740
+ if (generalAttrType) {
3741
+ return {
3742
+ symbol: undefined,
3743
+ type: generalAttrType.type,
3744
+ isTypeIncomplete: false,
3745
+ isDescriptorError: false,
3746
+ isClassMember: false,
3747
+ isClassVar: false,
3748
+ isAsymmetricAccessor: !!generalAttrType.isAsymmetricAccessor,
3749
+ };
3941
3750
  }
3942
3751
  }
3943
- return {
3944
- symbol: memberInfo.symbol,
3945
- type,
3946
- isTypeIncomplete,
3947
- isSetTypeError,
3948
- isClassMember: !memberInfo.isInstanceMember,
3949
- isClassVar: memberInfo.isClassVar,
3950
- classType: memberInfo.classType,
3951
- isAsymmetricAccessor: descriptorResult.isAsymmetricAccessor,
3952
- memberAccessDeprecationInfo: descriptorResult === null || descriptorResult === void 0 ? void 0 : descriptorResult.memberAccessDeprecationInfo,
3953
- };
3752
+ // Report that the member could not be accessed.
3753
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberUnknown().format({ name: memberName }));
3754
+ return undefined;
3954
3755
  }
3955
- // No attribute of that name was found. If this is a member access
3956
- // through an object, see if there's an attribute access override
3957
- // method ("__getattr__", etc.).
3958
- if ((flags & (1 /* AccessClassMembersOnly */ | 128 /* SkipAttributeAccessOverride */)) ===
3959
- 0) {
3960
- const generalAttrType = applyAttributeAccessOverride(classType, errorNode, usage, memberName);
3961
- if (generalAttrType) {
3962
- return {
3963
- symbol: undefined,
3964
- type: generalAttrType.type,
3965
- isTypeIncomplete: false,
3966
- isSetTypeError: false,
3967
- isClassMember: false,
3968
- isClassVar: false,
3969
- isAsymmetricAccessor: generalAttrType.isAsymmetricAccessor,
3970
- };
3971
- }
3756
+ let type;
3757
+ let isTypeIncomplete = false;
3758
+ if (memberInfo.symbol.isInitVar()) {
3759
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsInitVar().format({ name: memberName }));
3760
+ return undefined;
3972
3761
  }
3973
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberUnknown().format({ name: memberName }));
3974
- return undefined;
3975
- }
3976
- // Applies descriptor access methods "__get__", "__set__", or "__delete__"
3977
- // if they apply. Also binds methods to the class/object through which it
3978
- // is accessed.
3979
- function applyDescriptorAccessMethod(type, memberInfo, baseTypeClass, bindToType, isAccessedThroughObject, flags, errorNode, memberName, usage, diag) {
3980
- const treatConstructorAsClassMember = (flags & 32 /* TreatConstructorAsClassMethod */) !== 0;
3981
- let isTypeValid = true;
3982
- let isAsymmetricAccessor = false;
3983
- let memberAccessDeprecationInfo;
3984
- type = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
3985
- var _a, _b, _c;
3986
- const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
3987
- const isClassMember = !memberInfo || memberInfo.isClassMember;
3988
- if ((0, types_1.isClass)(concreteSubtype) && isClassMember) {
3989
- // If it's an object, use its class to lookup the descriptor. If it's a class,
3990
- // use its metaclass instead.
3991
- let lookupClass = concreteSubtype;
3992
- let isAccessedThroughMetaclass = false;
3993
- if (types_1.TypeBase.isInstantiable(concreteSubtype)) {
3994
- if (concreteSubtype.details.effectiveMetaclass &&
3995
- (0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass)) {
3996
- // When accessing a class member that is a class whose metaclass implements
3997
- // a descriptor protocol, only 'get' operations are allowed. If it's accessed
3998
- // through the object, all access methods are supported.
3999
- if (isAccessedThroughObject || usage.method === 'get') {
4000
- lookupClass = types_1.ClassType.cloneAsInstance(concreteSubtype.details.effectiveMetaclass);
4001
- isAccessedThroughMetaclass = true;
4002
- }
4003
- else {
4004
- lookupClass = undefined;
4005
- }
4006
- }
4007
- else {
4008
- lookupClass = undefined;
4009
- }
4010
- }
4011
- if (lookupClass) {
4012
- let accessMethodName;
4013
- if (usage.method === 'get') {
4014
- accessMethodName = '__get__';
4015
- }
4016
- else if (usage.method === 'set') {
4017
- accessMethodName = '__set__';
4018
- }
4019
- else {
4020
- accessMethodName = '__delete__';
4021
- }
4022
- const accessMethod = (0, typeUtils_1.lookUpClassMember)(lookupClass, accessMethodName, 8 /* SkipInstanceVariables */);
4023
- // Handle properties specially.
4024
- if (types_1.ClassType.isPropertyClass(lookupClass)) {
4025
- if (usage.method === 'set') {
4026
- if (!accessMethod) {
4027
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMissingSetter().format({
4028
- name: memberName,
4029
- }));
4030
- isTypeValid = false;
4031
- return undefined;
4032
- }
4033
- }
4034
- else if (usage.method === 'del') {
4035
- if (!accessMethod) {
4036
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMissingDeleter().format({
4037
- name: memberName,
4038
- }));
4039
- isTypeValid = false;
4040
- return undefined;
3762
+ if (usage.method !== 'get' && errorNode) {
3763
+ // If the usage indicates a 'set' or 'delete' and the access is within the
3764
+ // class definition itself, use only the declared type to avoid circular
3765
+ // type evaluation.
3766
+ const containingClass = ParseTreeUtils.getEnclosingClass(errorNode);
3767
+ if (containingClass) {
3768
+ const containingClassType = (_a = getTypeOfClass(containingClass)) === null || _a === void 0 ? void 0 : _a.classType;
3769
+ if (containingClassType &&
3770
+ (0, types_1.isInstantiableClass)(containingClassType) &&
3771
+ types_1.ClassType.isSameGenericClass(containingClassType, classType)) {
3772
+ type = (_b = getDeclaredTypeOfSymbol(memberInfo.symbol)) === null || _b === void 0 ? void 0 : _b.type;
3773
+ if (type && (0, types_1.isInstantiableClass)(memberInfo.classType)) {
3774
+ type = (0, typeUtils_1.partiallySpecializeType)(type, memberInfo.classType);
3775
+ }
3776
+ // If we're setting a class variable via a write through an object,
3777
+ // this is normally considered a type violation. But it is allowed
3778
+ // if the class variable is a descriptor object. In this case, we will
3779
+ // clear the flag that causes an error to be generated.
3780
+ if (usage.method === 'set' && memberInfo.symbol.isClassVar() && isAccessedThroughObject) {
3781
+ const selfClass = (selfType !== null && selfType !== void 0 ? selfType : memberName === '__new__') ? undefined : classType;
3782
+ const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3783
+ if (typeResult) {
3784
+ if ((0, typeUtils_1.isDescriptorInstance)(typeResult.type, /* requireSetter */ true)) {
3785
+ type = typeResult.type;
3786
+ flags &= 128 /* DisallowClassVarWrites */;
4041
3787
  }
4042
3788
  }
4043
3789
  }
4044
- if (accessMethod) {
4045
- let accessMethodType = getTypeOfMember(accessMethod);
4046
- const argList = [
4047
- {
4048
- // Provide "obj" argument.
4049
- argumentCategory: 0 /* Simple */,
4050
- typeResult: {
4051
- type: types_1.ClassType.isClassProperty(lookupClass)
4052
- ? baseTypeClass
4053
- : isAccessedThroughObject
4054
- ? bindToType !== null && bindToType !== void 0 ? bindToType : types_1.ClassType.cloneAsInstance(baseTypeClass)
4055
- : types_1.NoneType.createInstance(),
4056
- },
4057
- },
4058
- ];
4059
- if (usage.method === 'get') {
4060
- // Provide "owner" argument.
4061
- argList.push({
4062
- argumentCategory: 0 /* Simple */,
4063
- typeResult: {
4064
- type: baseTypeClass,
4065
- },
4066
- });
4067
- }
4068
- else if (usage.method === 'set') {
4069
- // Provide "value" argument.
4070
- argList.push({
4071
- argumentCategory: 0 /* Simple */,
4072
- typeResult: {
4073
- type: (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(),
4074
- isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
4075
- },
4076
- });
4077
- }
4078
- if (types_1.ClassType.isPropertyClass(lookupClass) &&
4079
- memberInfo &&
4080
- (0, types_1.isInstantiableClass)(memberInfo.classType)) {
4081
- // This specialization is required specifically for properties, which should be
4082
- // generic but are not defined that way. Because of this, we use type variables
4083
- // in the synthesized methods (e.g. __get__) for the property class that are
4084
- // defined in the class that declares the fget method.
4085
- // Infer return types before specializing. Otherwise a generic inferred
4086
- // return type won't be properly specialized.
4087
- inferReturnTypeIfNecessary(accessMethodType);
4088
- accessMethodType = (0, typeUtils_1.partiallySpecializeType)(accessMethodType, memberInfo.classType);
4089
- // If the property is being accessed from a protocol class (not an instance),
4090
- // flag this as an error because a property within a protocol is meant to be
4091
- // interpreted as a read-only attribute rather than a protocol, so accessing
4092
- // it directly from the class has an ambiguous meaning.
4093
- if ((flags & 1 /* AccessClassMembersOnly */) !== 0 &&
4094
- types_1.ClassType.isProtocolClass(baseTypeClass)) {
4095
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass());
4096
- isTypeValid = false;
4097
- }
4098
- }
4099
- if (accessMethodType &&
4100
- ((0, types_1.isFunction)(accessMethodType) || (0, types_1.isOverloadedFunction)(accessMethodType))) {
4101
- const methodType = accessMethodType;
4102
- // Don't emit separate diagnostics for these method calls because
4103
- // they will be redundant.
4104
- const returnType = suppressDiagnostics(errorNode, () => {
4105
- var _a;
4106
- // Bind the accessor to the base object type.
4107
- let bindToClass;
4108
- // The "bind-to" class depends on whether the descriptor is defined
4109
- // on the metaclass or the class. We handle properties specially here
4110
- // because of the way we model the __get__ logic in the property class.
4111
- if (types_1.ClassType.isPropertyClass(concreteSubtype) && !isAccessedThroughMetaclass) {
4112
- if (memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType)) {
4113
- bindToClass = memberInfo.classType;
4114
- }
4115
- }
4116
- else {
4117
- if ((0, types_1.isInstantiableClass)(accessMethod.classType)) {
4118
- bindToClass = accessMethod.classType;
4119
- }
4120
- }
4121
- let boundMethodType = bindFunctionToClassOrObjectWithErrors(lookupClass, methodType, bindToClass, errorNode,
4122
- /* treatConstructorAsClassMember */ undefined, isAccessedThroughMetaclass ? concreteSubtype : undefined);
4123
- // The synthesized access method for the property may contain
4124
- // type variables associated with the "bindToClass", so we need
4125
- // to specialize those here.
4126
- if (boundMethodType &&
4127
- ((0, types_1.isFunction)(boundMethodType) || (0, types_1.isOverloadedFunction)(boundMethodType))) {
4128
- const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(boundMethodType));
4129
- if (bindToClass) {
4130
- const specializedBoundType = (0, typeUtils_1.partiallySpecializeType)(boundMethodType, bindToClass, baseTypeClass);
4131
- if (specializedBoundType) {
4132
- if ((0, types_1.isFunction)(specializedBoundType) ||
4133
- (0, types_1.isOverloadedFunction)(specializedBoundType)) {
4134
- boundMethodType = specializedBoundType;
4135
- }
4136
- }
4137
- }
4138
- const callResult = validateCallArguments(errorNode, argList, { type: boundMethodType }, typeVarContext,
4139
- /* skipUnknownArgCheck */ true);
4140
- if (callResult.overloadsUsedForCall &&
4141
- callResult.overloadsUsedForCall.length >= 1) {
4142
- const overloadUsed = callResult.overloadsUsedForCall[0];
4143
- if (overloadUsed.details.deprecatedMessage) {
4144
- memberAccessDeprecationInfo = {
4145
- deprecationMessage: overloadUsed.details.deprecatedMessage,
4146
- accessType: lookupClass && types_1.ClassType.isPropertyClass(lookupClass)
4147
- ? 'property'
4148
- : 'descriptor',
4149
- accessMethod: usage.method,
4150
- };
4151
- }
4152
- }
4153
- if (callResult.argumentErrors) {
4154
- if (usage.method === 'set') {
4155
- if (usage.setType &&
4156
- (0, types_1.isFunction)(boundMethodType) &&
4157
- boundMethodType.details.parameters.length >= 2 &&
4158
- !usage.setType.isIncomplete) {
4159
- const setterType = types_1.FunctionType.getEffectiveParameterType(boundMethodType, 1);
4160
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeIncompatible().format({
4161
- destType: printType(setterType),
4162
- sourceType: printType(usage.setType.type),
4163
- }));
4164
- }
4165
- else if ((0, types_1.isOverloadedFunction)(boundMethodType)) {
4166
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.noOverload().format({ name: accessMethodName }));
4167
- }
4168
- }
4169
- isTypeValid = false;
4170
- return types_1.AnyType.create();
4171
- }
4172
- // For set or delete, always return Any.
4173
- return usage.method === 'get'
4174
- ? (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create()
4175
- : types_1.AnyType.create();
4176
- }
4177
- return undefined;
4178
- });
4179
- // Determine if we're calling __set__ on an asymmetric descriptor or property.
4180
- if (usage.method === 'set' && (0, types_1.isClass)(accessMethod.classType)) {
4181
- if (isAsymmetricDescriptorClass(accessMethod.classType)) {
4182
- isAsymmetricAccessor = true;
4183
- }
4184
- }
4185
- if (returnType) {
4186
- return returnType;
4187
- }
4188
- }
3790
+ if (!type) {
3791
+ type = types_1.UnknownType.create();
4189
3792
  }
4190
3793
  }
4191
3794
  }
4192
- else if ((0, types_1.isFunction)(concreteSubtype) || (0, types_1.isOverloadedFunction)(concreteSubtype)) {
4193
- // Check for an attempt to overwrite a final method.
4194
- if (usage.method === 'set') {
4195
- let isFinal = false;
4196
- if ((0, types_1.isFunction)(concreteSubtype)) {
4197
- isFinal = types_1.FunctionType.isFinal(concreteSubtype);
4198
- }
4199
- else {
4200
- const impl = types_1.OverloadedFunctionType.getImplementation(concreteSubtype);
4201
- if (impl) {
4202
- isFinal = types_1.FunctionType.isFinal(impl);
4203
- }
4204
- }
4205
- if (isFinal && memberInfo && (0, types_1.isClass)(memberInfo.classType)) {
4206
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
4207
- name: memberName,
4208
- className: memberInfo.classType.details.name,
4209
- }));
4210
- isTypeValid = false;
4211
- return undefined;
4212
- }
3795
+ }
3796
+ if (!type) {
3797
+ let selfClass;
3798
+ if (selfType) {
3799
+ selfClass = (0, typeUtils_1.convertToInstantiable)(selfType);
3800
+ }
3801
+ else {
3802
+ // Skip this for __new__ methods because they are not bound
3803
+ // to the class but rather assume the type of the cls argument.
3804
+ if (memberName !== '__new__') {
3805
+ selfClass = classType;
4213
3806
  }
4214
- // If this function is an instance member (e.g. a lambda that was
4215
- // assigned to an instance variable), don't perform any binding.
4216
- if (!isAccessedThroughObject || (memberInfo && !memberInfo.isInstanceMember)) {
4217
- let effectiveBindToType = bindToType;
4218
- if (bindToType && !(0, typeUtils_1.isInstantiableMetaclass)(baseTypeClass)) {
4219
- // If bindToType is an instantiable class or TypeVar but we're targeting
4220
- // an instance method (in a non-metaclass), we need to convert
4221
- // the bindToType to an instance.
4222
- const targetMethod = (0, types_1.isFunction)(concreteSubtype)
4223
- ? concreteSubtype
4224
- : concreteSubtype.overloads[0];
4225
- if (types_1.FunctionType.isInstanceMethod(targetMethod) && !types_1.TypeBase.isInstance(bindToType)) {
4226
- effectiveBindToType = (0, typeUtils_1.convertToInstance)(bindToType);
4227
- }
4228
- }
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);
3807
+ }
3808
+ const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3809
+ type = (_c = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
3810
+ if (typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete) {
3811
+ isTypeIncomplete = true;
3812
+ }
3813
+ }
3814
+ // Don't include variables within typed dict classes.
3815
+ if ((0, types_1.isClass)(memberInfo.classType) && types_1.ClassType.isTypedDictClass(memberInfo.classType)) {
3816
+ const typedDecls = memberInfo.symbol.getTypedDeclarations();
3817
+ if (typedDecls.length > 0 && typedDecls[0].type === 1 /* Variable */) {
3818
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberUnknown().format({ name: memberName }));
3819
+ return undefined;
3820
+ }
3821
+ }
3822
+ if (usage.method === 'get') {
3823
+ // Mark the member accessed if it's not coming from a parent class.
3824
+ if (errorNode &&
3825
+ (0, types_1.isInstantiableClass)(memberInfo.classType) &&
3826
+ types_1.ClassType.isSameGenericClass(memberInfo.classType, classType)) {
3827
+ setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
3828
+ }
3829
+ // Special-case `__init_subclass` and `__class_getitem__` because
3830
+ // these are always treated as class methods even if they're not
3831
+ // decorated as such.
3832
+ if (memberName === '__init_subclass__' || memberName === '__class_getitem__') {
3833
+ if ((0, types_1.isFunction)(type) && !types_1.FunctionType.isClassMethod(type)) {
3834
+ type = types_1.FunctionType.cloneWithNewFlags(type, type.details.flags | 2 /* ClassMethod */);
4235
3835
  }
4236
3836
  }
4237
- if (usage.method === 'set') {
4238
- if (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.isClassVar()) {
4239
- if (flags & 16 /* DisallowClassVarWrites */) {
4240
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberSetClassVar().format({ name: memberName }));
4241
- isTypeValid = false;
4242
- return undefined;
4243
- }
3837
+ }
3838
+ // If the member is a descriptor object, apply the descriptor protocol
3839
+ // now. If the member is an instance or class method, bind the method.
3840
+ let isDescriptorError = false;
3841
+ let isAsymmetricAccessor = false;
3842
+ let isDescriptorApplied = false;
3843
+ let memberAccessDeprecationInfo;
3844
+ type = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
3845
+ const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
3846
+ const isClassMember = !memberInfo || memberInfo.isClassMember;
3847
+ let resultType;
3848
+ if ((0, types_1.isClass)(concreteSubtype) && isClassMember && errorNode) {
3849
+ const descResult = applyDescriptorAccessMethod(subtype, concreteSubtype, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag);
3850
+ if (descResult.isAsymmetricAccessor) {
3851
+ isAsymmetricAccessor = true;
4244
3852
  }
4245
- // Check for an attempt to overwrite a final member variable.
4246
- const finalVarTypeDecl = memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.getDeclarations().find((decl) => isFinalVariableDeclaration(decl));
4247
- if (finalVarTypeDecl && !ParseTreeUtils.isNodeContainedWithin(errorNode, finalVarTypeDecl.node)) {
4248
- // If a Final instance variable is declared in the class body but is
4249
- // being assigned within an __init__ method, it's allowed.
4250
- const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(errorNode);
4251
- if (!enclosingFunctionNode || enclosingFunctionNode.name.value !== '__init__') {
4252
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalReassigned().format({ name: memberName }));
4253
- isTypeValid = false;
4254
- return undefined;
4255
- }
3853
+ if (descResult.memberAccessDeprecationInfo) {
3854
+ memberAccessDeprecationInfo = descResult.memberAccessDeprecationInfo;
4256
3855
  }
4257
- // Check for an attempt to overwrite an instance variable that is
4258
- // read-only (e.g. in a named tuple).
4259
- if ((memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isInstanceMember) &&
4260
- (0, types_1.isClass)(memberInfo.classType) &&
4261
- types_1.ClassType.isReadOnlyInstanceVariables(memberInfo.classType)) {
4262
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.readOnlyAttribute().format({ name: memberName }));
4263
- isTypeValid = false;
4264
- return undefined;
3856
+ if (descResult.typeErrors) {
3857
+ isDescriptorError = true;
4265
3858
  }
4266
- let enforceTargetType = false;
4267
- if (memberInfo && memberInfo.symbol.hasTypedDeclarations()) {
4268
- // If the member has a declared type, we will enforce it.
4269
- enforceTargetType = true;
3859
+ if (descResult.isDescriptorApplied) {
3860
+ isDescriptorApplied = true;
4270
3861
  }
4271
- else {
4272
- // If the member has no declared type, we will enforce it
4273
- // if this assignment isn't within the enclosing class. If
4274
- // it is within the enclosing class, the assignment is used
4275
- // to infer the type of the member.
4276
- if (memberInfo && !memberInfo.symbol.getDeclarations().some((decl) => decl.node === errorNode)) {
4277
- enforceTargetType = true;
4278
- }
4279
- }
4280
- if (enforceTargetType) {
4281
- let effectiveType = subtype;
4282
- // If the code is patching a method (defined on the class)
4283
- // with an object-level function, strip the "self" parameter
4284
- // off the original type. This is sometimes done for test
4285
- // purposes to override standard behaviors of specific methods.
4286
- if (isAccessedThroughObject) {
4287
- if (!memberInfo.isInstanceMember && (0, types_1.isFunction)(concreteSubtype)) {
4288
- if (types_1.FunctionType.isClassMethod(concreteSubtype) ||
4289
- types_1.FunctionType.isInstanceMethod(concreteSubtype)) {
4290
- effectiveType = types_1.FunctionType.clone(concreteSubtype, /* stripFirstParam */ true);
4291
- }
4292
- }
4293
- }
4294
- return effectiveType;
3862
+ resultType = descResult.type;
3863
+ }
3864
+ else if ((0, types_1.isFunction)(concreteSubtype) || (0, types_1.isOverloadedFunction)(concreteSubtype)) {
3865
+ const typeResult = bindMethodForMemberAccess(subtype, concreteSubtype, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount);
3866
+ resultType = typeResult.type;
3867
+ if (typeResult.typeErrors) {
3868
+ isDescriptorError = true;
4295
3869
  }
4296
3870
  }
4297
- return subtype;
3871
+ else {
3872
+ resultType = subtype;
3873
+ }
3874
+ // If this is a "set" operation, we have a bit more work to do.
3875
+ if (usage.method !== 'set') {
3876
+ return resultType;
3877
+ }
3878
+ // Check for an attempt to overwrite a ClassVar member from an instance.
3879
+ if (!isDescriptorApplied &&
3880
+ (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.isClassVar()) &&
3881
+ (flags & 128 /* DisallowClassVarWrites */) !== 0) {
3882
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberSetClassVar().format({ name: memberName }));
3883
+ isDescriptorError = true;
3884
+ }
3885
+ // Check for an attempt to overwrite a final member variable.
3886
+ const finalVarTypeDecl = memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.getDeclarations().find((decl) => isFinalVariableDeclaration(decl));
3887
+ if (finalVarTypeDecl &&
3888
+ errorNode &&
3889
+ !ParseTreeUtils.isNodeContainedWithin(errorNode, finalVarTypeDecl.node)) {
3890
+ // If a Final instance variable is declared in the class body but is
3891
+ // being assigned within an __init__ method, it's allowed.
3892
+ const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(errorNode);
3893
+ if (!enclosingFunctionNode || enclosingFunctionNode.name.value !== '__init__') {
3894
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalReassigned().format({ name: memberName }));
3895
+ isDescriptorError = true;
3896
+ }
3897
+ }
3898
+ // Check for an attempt to overwrite an instance variable that is
3899
+ // read-only (e.g. in a named tuple).
3900
+ if ((memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isInstanceMember) &&
3901
+ (0, types_1.isClass)(memberInfo.classType) &&
3902
+ types_1.ClassType.isReadOnlyInstanceVariables(memberInfo.classType)) {
3903
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.readOnlyAttribute().format({ name: memberName }));
3904
+ isDescriptorError = true;
3905
+ }
3906
+ return resultType;
4298
3907
  });
4299
- if (!isTypeValid) {
4300
- return undefined;
3908
+ if (!isDescriptorError && usage.method === 'set' && usage.setType) {
3909
+ // Verify that the assigned type is compatible.
3910
+ if (!assignType(type, usage.setType.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum())) {
3911
+ if (!usage.setType.isIncomplete) {
3912
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberAssignment().format({
3913
+ type: printType(usage.setType.type),
3914
+ name: memberName,
3915
+ classType: printObjectTypeForClass(classType),
3916
+ }));
3917
+ }
3918
+ isDescriptorError = true;
3919
+ }
3920
+ if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3921
+ types_1.ClassType.isFrozenDataClass(memberInfo.classType) &&
3922
+ isAccessedThroughObject) {
3923
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.dataClassFrozen().format({
3924
+ name: printType(types_1.ClassType.cloneAsInstance(memberInfo.classType)),
3925
+ }));
3926
+ isDescriptorError = true;
3927
+ }
3928
+ }
3929
+ return {
3930
+ symbol: memberInfo.symbol,
3931
+ type,
3932
+ isTypeIncomplete,
3933
+ isDescriptorError,
3934
+ isClassMember: !memberInfo.isInstanceMember,
3935
+ isClassVar: memberInfo.isClassVar,
3936
+ classType: memberInfo.classType,
3937
+ isAsymmetricAccessor,
3938
+ memberAccessDeprecationInfo,
3939
+ };
3940
+ }
3941
+ // Applies descriptor access methods "__get__", "__set__", or "__delete__"
3942
+ // if they apply.
3943
+ function applyDescriptorAccessMethod(memberType, concreteMemberType, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag) {
3944
+ var _a, _b, _c, _d;
3945
+ const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
3946
+ let accessMethodName;
3947
+ if (usage.method === 'get') {
3948
+ accessMethodName = '__get__';
3949
+ }
3950
+ else if (usage.method === 'set') {
3951
+ accessMethodName = '__set__';
3952
+ }
3953
+ else {
3954
+ accessMethodName = '__delete__';
3955
+ }
3956
+ const methodTypeResult = getTypeOfBoundMember(errorNode, concreteMemberType, accessMethodName,
3957
+ /* usage */ undefined, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */);
3958
+ if (!methodTypeResult) {
3959
+ // Provide special error messages for properties.
3960
+ if (types_1.ClassType.isPropertyClass(concreteMemberType)) {
3961
+ if (usage.method !== 'get') {
3962
+ const message = usage.method === 'set'
3963
+ ? localize_1.Localizer.DiagnosticAddendum.propertyMissingSetter()
3964
+ : localize_1.Localizer.DiagnosticAddendum.propertyMissingDeleter();
3965
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(message.format({ name: memberName }));
3966
+ return { type: types_1.AnyType.create(), typeErrors: true };
3967
+ }
3968
+ }
3969
+ return { type: memberType };
3970
+ }
3971
+ const methodClassType = methodTypeResult.classType;
3972
+ let methodType = methodTypeResult.type;
3973
+ if (methodTypeResult.typeErrors || !methodClassType) {
3974
+ return { type: types_1.UnknownType.create(), typeErrors: true };
3975
+ }
3976
+ if (!(0, types_1.isFunction)(methodType) && !(0, types_1.isOverloadedFunction)(methodType)) {
3977
+ if ((0, types_1.isAnyOrUnknown)(methodType)) {
3978
+ return { type: methodType };
3979
+ }
3980
+ // TODO - emit an error for this condition.
3981
+ return { type: memberType, typeErrors: true };
3982
+ }
3983
+ // Special-case logic for properties.
3984
+ if (types_1.ClassType.isPropertyClass(concreteMemberType) &&
3985
+ memberInfo &&
3986
+ (0, types_1.isInstantiableClass)(memberInfo.classType) &&
3987
+ methodType) {
3988
+ // If the property is being accessed from a protocol class (not an instance),
3989
+ // flag this as an error because a property within a protocol is meant to be
3990
+ // interpreted as a read-only attribute rather than a protocol, so accessing
3991
+ // it directly from the class has an ambiguous meaning.
3992
+ if ((flags & 16 /* SkipInstanceMembers */) !== 0 && types_1.ClassType.isProtocolClass(classType)) {
3993
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass());
3994
+ return { type: memberType, typeErrors: true };
3995
+ }
3996
+ // Infer return types before specializing. Otherwise a generic inferred
3997
+ // return type won't be properly specialized.
3998
+ inferReturnTypeIfNecessary(methodType);
3999
+ // This specialization is required specifically for properties, which should be
4000
+ // generic but are not defined that way. Because of this, we use type variables
4001
+ // in the synthesized methods (e.g. __get__) for the property class that are
4002
+ // defined in the class that declares the fget method.
4003
+ const specializedType = (0, typeUtils_1.partiallySpecializeType)(methodType, memberInfo.classType, selfType ? (0, typeUtils_1.convertToInstantiable)(selfType) : classType);
4004
+ if ((0, types_1.isFunction)(specializedType) || (0, types_1.isOverloadedFunction)(specializedType)) {
4005
+ methodType = specializedType;
4006
+ }
4007
+ }
4008
+ // Determine if we're calling __set__ on an asymmetric descriptor or property.
4009
+ let isAsymmetricAccessor = false;
4010
+ if (usage.method === 'set' && (0, types_1.isClass)(methodClassType)) {
4011
+ if (isAsymmetricDescriptorClass(methodClassType)) {
4012
+ isAsymmetricAccessor = true;
4013
+ }
4014
+ }
4015
+ if (!methodType) {
4016
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessBindingFailed().format({
4017
+ name: accessMethodName,
4018
+ className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
4019
+ }));
4020
+ return {
4021
+ type: types_1.UnknownType.create(),
4022
+ typeErrors: true,
4023
+ isDescriptorApplied: true,
4024
+ isAsymmetricAccessor,
4025
+ };
4026
+ }
4027
+ // Simulate a call to the access method.
4028
+ const argList = [];
4029
+ // Provide "obj" argument.
4030
+ argList.push({
4031
+ argumentCategory: 0 /* Simple */,
4032
+ typeResult: {
4033
+ type: types_1.ClassType.isClassProperty(concreteMemberType)
4034
+ ? classType
4035
+ : isAccessedThroughObject
4036
+ ? selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType)
4037
+ : getNoneType(),
4038
+ },
4039
+ });
4040
+ if (usage.method === 'get') {
4041
+ // Provide "owner" argument.
4042
+ argList.push({
4043
+ argumentCategory: 0 /* Simple */,
4044
+ typeResult: {
4045
+ type: isAccessedThroughObject ? types_1.ClassType.cloneAsInstantiable(classType) : classType,
4046
+ },
4047
+ });
4048
+ }
4049
+ else if (usage.method === 'set') {
4050
+ // Provide "value" argument.
4051
+ argList.push({
4052
+ argumentCategory: 0 /* Simple */,
4053
+ typeResult: {
4054
+ type: (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(),
4055
+ isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
4056
+ },
4057
+ });
4058
+ }
4059
+ // Suppress diagnostics for these method calls because they would be redundant.
4060
+ const callResult = suppressDiagnostics(errorNode, () => {
4061
+ return validateCallArguments(errorNode, argList, { type: methodType },
4062
+ /* typeVarContext */ undefined,
4063
+ /* skipUnknownArgCheck */ true);
4064
+ });
4065
+ // Collect deprecation information associated with the member access method.
4066
+ let deprecationInfo;
4067
+ if (callResult.overloadsUsedForCall && callResult.overloadsUsedForCall.length >= 1) {
4068
+ const overloadUsed = callResult.overloadsUsedForCall[0];
4069
+ if (overloadUsed.details.deprecatedMessage) {
4070
+ deprecationInfo = {
4071
+ deprecationMessage: overloadUsed.details.deprecatedMessage,
4072
+ accessType: types_1.ClassType.isPropertyClass(concreteMemberType) ? 'property' : 'descriptor',
4073
+ accessMethod: usage.method,
4074
+ };
4075
+ }
4076
+ }
4077
+ if (!callResult.argumentErrors) {
4078
+ return {
4079
+ // For set or delete, always return Any.
4080
+ type: usage.method === 'get' ? (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create() : types_1.AnyType.create(),
4081
+ isDescriptorApplied: true,
4082
+ isAsymmetricAccessor,
4083
+ memberAccessDeprecationInfo: deprecationInfo,
4084
+ };
4085
+ }
4086
+ // Errors were detected when evaluating the access method call.
4087
+ if (usage.method === 'set') {
4088
+ if (usage.setType &&
4089
+ (0, types_1.isFunction)(methodType) &&
4090
+ methodType.details.parameters.length >= 2 &&
4091
+ !usage.setType.isIncomplete) {
4092
+ const setterType = types_1.FunctionType.getEffectiveParameterType(methodType, 1);
4093
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeIncompatible().format({
4094
+ destType: printType(setterType),
4095
+ sourceType: printType(usage.setType.type),
4096
+ }));
4097
+ }
4098
+ else if ((0, types_1.isOverloadedFunction)(methodType)) {
4099
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.noOverload().format({ name: accessMethodName }));
4100
+ }
4101
+ }
4102
+ else {
4103
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessCallFailed().format({
4104
+ name: accessMethodName,
4105
+ className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
4106
+ }));
4107
+ }
4108
+ return {
4109
+ type: types_1.UnknownType.create(),
4110
+ typeErrors: true,
4111
+ isDescriptorApplied: true,
4112
+ isAsymmetricAccessor,
4113
+ memberAccessDeprecationInfo: deprecationInfo,
4114
+ };
4115
+ }
4116
+ function bindMethodForMemberAccess(type, concreteType, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount = 0) {
4117
+ // Check for an attempt to overwrite a final method.
4118
+ if (usage.method === 'set') {
4119
+ const impl = (0, types_1.isFunction)(concreteType)
4120
+ ? concreteType
4121
+ : types_1.OverloadedFunctionType.getImplementation(concreteType);
4122
+ if (impl && types_1.FunctionType.isFinal(impl) && memberInfo && (0, types_1.isClass)(memberInfo.classType)) {
4123
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
4124
+ name: memberName,
4125
+ className: memberInfo.classType.details.name,
4126
+ }));
4127
+ return { type: types_1.UnknownType.create(), typeErrors: true };
4128
+ }
4129
+ }
4130
+ // If this function is an instance member (e.g. a lambda that was
4131
+ // assigned to an instance variable), don't perform any binding.
4132
+ if (types_1.TypeBase.isInstance(classType)) {
4133
+ if (!memberInfo || memberInfo.isInstanceMember) {
4134
+ return { type: type };
4135
+ }
4301
4136
  }
4302
- return { type, isAsymmetricAccessor, memberAccessDeprecationInfo };
4137
+ const boundType = bindFunctionToClassOrObject(classType, concreteType, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, (flags & 256 /* TreatConstructorAsClassMethod */) !== 0, selfType && (0, types_1.isClass)(selfType) ? types_1.ClassType.cloneIncludeSubclasses(selfType) : selfType, diag, recursionCount);
4138
+ return { type: boundType !== null && boundType !== void 0 ? boundType : types_1.UnknownType.create(), typeErrors: !boundType };
4303
4139
  }
4304
4140
  function isAsymmetricDescriptorClass(classType) {
4305
4141
  var _a;
@@ -4366,14 +4202,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4366
4202
  return isAsymmetric;
4367
4203
  }
4368
4204
  // Applies the __getattr__, __setattr__ or __delattr__ method if present.
4369
- function applyAttributeAccessOverride(classType, errorNode, usage, memberName) {
4205
+ // If it's not applicable, returns undefined.
4206
+ function applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType) {
4370
4207
  var _a, _b, _c, _d, _e;
4371
4208
  const getAttributeAccessMember = (name) => {
4372
4209
  var _a;
4373
- // See if the class has a "__getattribute__" or "__getattr__" method.
4374
- // If so, arbitrary members are supported.
4375
- return (_a = getTypeOfClassMember(errorNode, classType, name, { method: 'get' },
4376
- /* diag */ undefined, 8 /* SkipObjectBaseClass */ | 128 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
4210
+ return (_a = getTypeOfBoundMember(errorNode, classType, name,
4211
+ /* usage */ undefined,
4212
+ /* diag */ undefined, 16 /* SkipInstanceMembers */ |
4213
+ 4 /* SkipObjectBaseClass */ |
4214
+ 512 /* SkipAttributeAccessOverride */, selfType)) === null || _a === void 0 ? void 0 : _a.type;
4377
4215
  };
4378
4216
  let accessMemberType;
4379
4217
  if (usage.method === 'get') {
@@ -4386,51 +4224,48 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4386
4224
  (0, debug_1.assert)(usage.method === 'del');
4387
4225
  accessMemberType = getAttributeAccessMember('__delattr__');
4388
4226
  }
4389
- if (accessMemberType) {
4390
- let nameLiteralType = types_1.AnyType.create();
4391
- if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
4392
- nameLiteralType = types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName);
4393
- }
4394
- const argList = [
4395
- {
4396
- // Provide "self" argument.
4397
- argumentCategory: 0 /* Simple */,
4398
- typeResult: { type: types_1.ClassType.cloneAsInstance(classType) },
4399
- },
4400
- {
4401
- // Provide "name" argument.
4402
- argumentCategory: 0 /* Simple */,
4403
- typeResult: { type: nameLiteralType },
4227
+ if (!accessMemberType) {
4228
+ return undefined;
4229
+ }
4230
+ const argList = [];
4231
+ // Provide "name" argument.
4232
+ argList.push({
4233
+ argumentCategory: 0 /* Simple */,
4234
+ typeResult: {
4235
+ type: strClassType && (0, types_1.isInstantiableClass)(strClassType)
4236
+ ? types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName)
4237
+ : types_1.AnyType.create(),
4238
+ },
4239
+ });
4240
+ if (usage.method === 'set') {
4241
+ // Provide "value" argument.
4242
+ argList.push({
4243
+ argumentCategory: 0 /* Simple */,
4244
+ typeResult: {
4245
+ type: (_c = (_b = usage.setType) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create(),
4246
+ isIncomplete: !!((_d = usage.setType) === null || _d === void 0 ? void 0 : _d.isIncomplete),
4404
4247
  },
4405
- ];
4406
- if (usage.method === 'set') {
4407
- argList.push({
4408
- // Provide "value" argument.
4409
- argumentCategory: 0 /* Simple */,
4410
- typeResult: {
4411
- type: (_c = (_b = usage.setType) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create(),
4412
- isIncomplete: !!((_d = usage.setType) === null || _d === void 0 ? void 0 : _d.isIncomplete),
4413
- },
4414
- });
4415
- }
4416
- if ((0, types_1.isFunction)(accessMemberType) || (0, types_1.isOverloadedFunction)(accessMemberType)) {
4417
- const boundMethodType = bindFunctionToClassOrObjectWithErrors(classType, accessMemberType, classType, errorNode);
4418
- if (boundMethodType && ((0, types_1.isFunction)(boundMethodType) || (0, types_1.isOverloadedFunction)(boundMethodType))) {
4419
- const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(boundMethodType));
4420
- const callResult = validateCallArguments(errorNode, argList, { type: boundMethodType }, typeVarContext,
4421
- /* skipUnknownArgCheck */ true);
4422
- let isAsymmetricAccessor = false;
4423
- if (usage.method === 'set') {
4424
- isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType);
4425
- }
4426
- return {
4427
- type: (_e = callResult.returnType) !== null && _e !== void 0 ? _e : types_1.UnknownType.create(),
4428
- isAsymmetricAccessor,
4429
- };
4430
- }
4248
+ });
4249
+ }
4250
+ if (!(0, types_1.isFunction)(accessMemberType) && !(0, types_1.isOverloadedFunction)(accessMemberType)) {
4251
+ if ((0, types_1.isAnyOrUnknown)(accessMemberType)) {
4252
+ return { type: accessMemberType };
4431
4253
  }
4254
+ // TODO - emit an error for this condition.
4255
+ return undefined;
4432
4256
  }
4433
- return undefined;
4257
+ const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(accessMemberType));
4258
+ const callResult = validateCallArguments(errorNode, argList, { type: accessMemberType }, typeVarContext,
4259
+ /* skipUnknownArgCheck */ true);
4260
+ let isAsymmetricAccessor = false;
4261
+ if (usage.method === 'set') {
4262
+ isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType);
4263
+ }
4264
+ return {
4265
+ type: (_e = callResult.returnType) !== null && _e !== void 0 ? _e : types_1.UnknownType.create(),
4266
+ typeErrors: callResult.argumentErrors,
4267
+ isAsymmetricAccessor,
4268
+ };
4434
4269
  }
4435
4270
  function getTypeOfIndex(node, flags = 0 /* None */) {
4436
4271
  const baseTypeResult = getTypeOfExpression(node.baseExpression, flags | 2 /* IndexBaseDefaults */);
@@ -4639,10 +4474,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4639
4474
  typeParameters.forEach((param, index) => {
4640
4475
  if (param.details.isParamSpec && index < typeArgs.length) {
4641
4476
  const typeArgType = typeArgs[index].type;
4642
- if (typeArgs[index].typeList) {
4477
+ const typeList = typeArgs[index].typeList;
4478
+ if (typeList) {
4643
4479
  const functionType = types_1.FunctionType.createSynthesizedInstance('', 65536 /* ParamSpecValue */);
4644
4480
  types_1.TypeBase.setSpecialForm(functionType);
4645
- typeArgs[index].typeList.forEach((paramType, paramIndex) => {
4481
+ typeList.forEach((paramType, paramIndex) => {
4646
4482
  types_1.FunctionType.addParameter(functionType, {
4647
4483
  category: 0 /* Simple */,
4648
4484
  name: `__p${paramIndex}`,
@@ -4757,7 +4593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4757
4593
  }
4758
4594
  if ((0, types_1.isTypeVar)(baseTypeResult.type) && (0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
4759
4595
  const typeArgTypes = getTypeArgs(node, flags).map((t) => (0, typeUtils_1.convertToInstance)(t.type));
4760
- const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeAliasIsPep695Syntax, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
4596
+ const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, !!baseTypeResult.type.details.recursiveTypeAliasIsPep695Syntax, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
4761
4597
  return { type };
4762
4598
  }
4763
4599
  let isIncomplete = baseTypeResult.isIncomplete;
@@ -4786,9 +4622,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4786
4622
  (0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass) &&
4787
4623
  !types_1.ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta']) &&
4788
4624
  (flags & 128 /* ExpectingInstantiableType */) === 0) {
4789
- const itemMethodType = getTypeOfClassMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
4790
- /* usage */ undefined,
4791
- /* diag */ undefined, 128 /* SkipAttributeAccessOverride */ | 64 /* ConsiderMetaclassOnly */);
4625
+ const itemMethodType = getBoundMagicMethod(concreteSubtype, getIndexAccessMagicMethodName(usage));
4792
4626
  if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
4793
4627
  // If the class doesn't derive from Generic, a type argument should not be allowed.
4794
4628
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
@@ -4876,6 +4710,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4876
4710
  }
4877
4711
  return result.type;
4878
4712
  }
4713
+ if ((0, typeUtils_1.isNoneInstance)(concreteSubtype)) {
4714
+ if (!isIncomplete) {
4715
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalSubscript, diagnosticRules_1.DiagnosticRule.reportOptionalSubscript, localize_1.Localizer.Diagnostic.noneNotSubscriptable(), node.baseExpression);
4716
+ }
4717
+ return types_1.UnknownType.create();
4718
+ }
4879
4719
  if ((0, types_1.isClassInstance)(concreteSubtype)) {
4880
4720
  const typeResult = getTypeOfIndexedObjectOrClass(node, concreteSubtype, usage);
4881
4721
  if (typeResult.isIncomplete) {
@@ -4886,10 +4726,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4886
4726
  if ((0, types_1.isNever)(concreteSubtype) || (0, types_1.isUnbound)(concreteSubtype)) {
4887
4727
  return types_1.NeverType.createNever();
4888
4728
  }
4889
- if ((0, types_1.isNoneInstance)(concreteSubtype) && !isIncomplete) {
4890
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalSubscript, diagnosticRules_1.DiagnosticRule.reportOptionalSubscript, localize_1.Localizer.Diagnostic.noneNotSubscriptable(), node.baseExpression);
4891
- return types_1.UnknownType.create();
4892
- }
4893
4729
  if (!isIncomplete) {
4894
4730
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
4895
4731
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSubscriptable().format({ type: printType(concreteSubtype) }), node.baseExpression);
@@ -4952,7 +4788,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4952
4788
  });
4953
4789
  }
4954
4790
  (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
4955
- if (subtype.category === 5 /* Function */) {
4791
+ if (subtype.category === 4 /* Function */) {
4956
4792
  if (subtype.specializedTypes) {
4957
4793
  subtype.specializedTypes.parameterTypes.forEach((paramType) => {
4958
4794
  updateUsageVarianceForType(paramType, 4 /* Contravariant */);
@@ -4963,7 +4799,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4963
4799
  }
4964
4800
  }
4965
4801
  }
4966
- else if (subtype.category === 7 /* Class */) {
4802
+ else if (subtype.category === 6 /* Class */) {
4967
4803
  if (subtype.typeArguments) {
4968
4804
  // If the class includes type parameters that uses auto variance,
4969
4805
  // compute the calculated variance.
@@ -5012,7 +4848,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5012
4848
  }
5013
4849
  }
5014
4850
  function getTypeOfIndexedObjectOrClass(node, baseType, usage) {
5015
- var _a, _b, _c, _d, _e, _f;
4851
+ var _a, _b, _c, _d;
5016
4852
  // Handle index operations for TypedDict classes specially.
5017
4853
  if ((0, types_1.isClassInstance)(baseType) && types_1.ClassType.isTypedDictClass(baseType)) {
5018
4854
  const typeFromTypedDict = (0, typedDicts_1.getTypeOfIndexedTypedDict)(evaluatorInterface, node, baseType, usage);
@@ -5021,13 +4857,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5021
4857
  }
5022
4858
  }
5023
4859
  const magicMethodName = getIndexAccessMagicMethodName(usage);
5024
- const itemMethodType = (0, types_1.isClassInstance)(baseType)
5025
- ? (_a = getTypeOfObjectMember(node, baseType, magicMethodName,
5026
- /* usage */ undefined,
5027
- /* diag */ undefined, 128 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type
5028
- : (_b = getTypeOfClassMember(node, baseType, magicMethodName,
5029
- /* usage */ undefined,
5030
- /* diag */ undefined, 128 /* SkipAttributeAccessOverride */ | 64 /* ConsiderMetaclassOnly */)) === null || _b === void 0 ? void 0 : _b.type;
4860
+ const itemMethodType = getBoundMagicMethod(baseType, magicMethodName);
5031
4861
  if (!itemMethodType) {
5032
4862
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
5033
4863
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.methodNotDefinedOnType().format({
@@ -5156,7 +4986,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5156
4986
  },
5157
4987
  ];
5158
4988
  if (usage.method === 'set') {
5159
- let setType = (_d = (_c = usage.setType) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : types_1.AnyType.create();
4989
+ let setType = (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.AnyType.create();
5160
4990
  // Expand constrained type variables.
5161
4991
  if ((0, types_1.isTypeVar)(setType) && setType.details.constraints.length > 0) {
5162
4992
  const conditionFilter = (0, types_1.isClassInstance)(baseType) ? baseType.condition : undefined;
@@ -5167,7 +4997,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5167
4997
  argumentCategory: 0 /* Simple */,
5168
4998
  typeResult: {
5169
4999
  type: setType,
5170
- isIncomplete: !!((_e = usage.setType) === null || _e === void 0 ? void 0 : _e.isIncomplete),
5000
+ isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
5171
5001
  },
5172
5002
  });
5173
5003
  }
@@ -5199,7 +5029,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5199
5029
  if ((0, types_1.isClassInstance)(positionalIndexType)) {
5200
5030
  const altArgList = [...argList];
5201
5031
  altArgList[0] = { ...altArgList[0] };
5202
- const indexMethod = getTypeOfObjectMember(node, positionalIndexType, '__index__');
5032
+ const indexMethod = getBoundMagicMethod(positionalIndexType, '__index__');
5203
5033
  if (indexMethod) {
5204
5034
  const intType = getBuiltInObject(node, 'int');
5205
5035
  if ((0, types_1.isClassInstance)(intType)) {
@@ -5217,7 +5047,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5217
5047
  }
5218
5048
  callResult = validateCallArguments(node, argList, { type: itemMethodType });
5219
5049
  return {
5220
- type: (_f = callResult.returnType) !== null && _f !== void 0 ? _f : types_1.UnknownType.create(),
5050
+ type: (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create(),
5221
5051
  isIncomplete: !!callResult.isTypeIncomplete,
5222
5052
  };
5223
5053
  }
@@ -5807,7 +5637,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5807
5637
  else {
5808
5638
  addInformation(localize_1.Localizer.Diagnostic.revealLocalsNone(), node);
5809
5639
  }
5810
- return types_1.NoneType.createInstance();
5640
+ return getNoneType();
5811
5641
  }
5812
5642
  function getTypeOfSuperCall(node) {
5813
5643
  var _a;
@@ -5832,6 +5662,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5832
5662
  else {
5833
5663
  if (enclosingClassType) {
5834
5664
  targetClassType = enclosingClassType !== null && enclosingClassType !== void 0 ? enclosingClassType : types_1.UnknownType.create();
5665
+ // Zero-argument forms of super are not allowed within static methods.
5666
+ // This results in a runtime exception.
5667
+ if (enclosingFunction) {
5668
+ const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, enclosingFunction,
5669
+ /* isInClass */ true);
5670
+ if (((functionInfo === null || functionInfo === void 0 ? void 0 : functionInfo.flags) & 4 /* StaticMethod */) !== 0) {
5671
+ addError(localize_1.Localizer.Diagnostic.superCallZeroArgFormStaticMethod(), node.leftExpression);
5672
+ targetClassType = types_1.UnknownType.create();
5673
+ }
5674
+ }
5835
5675
  }
5836
5676
  else {
5837
5677
  addError(localize_1.Localizer.Diagnostic.superCallZeroArgForm(), node.leftExpression);
@@ -5893,7 +5733,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5893
5733
  }
5894
5734
  }
5895
5735
  if (bindToType && implicitBindToType) {
5896
- bindToType = (0, typeUtils_1.addConditionToType)(bindToType, (0, typeUtils_1.getTypeCondition)(implicitBindToType));
5736
+ const typeCondition = (0, typeUtils_1.getTypeCondition)(implicitBindToType);
5737
+ if (typeCondition) {
5738
+ bindToType = (0, typeUtils_1.addConditionToType)(bindToType, typeCondition);
5739
+ }
5740
+ else if ((0, types_1.isClass)(implicitBindToType)) {
5741
+ bindToType = implicitBindToType;
5742
+ }
5897
5743
  }
5898
5744
  }
5899
5745
  // Determine whether super() should return an instance of the class or
@@ -5916,9 +5762,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5916
5762
  // Python docs indicate that super() isn't valid for
5917
5763
  // operations other than member accesses or attribute lookups.
5918
5764
  const parentNode = node.parent;
5919
- if (parentNode.nodeType === 35 /* MemberAccess */) {
5765
+ if ((parentNode === null || parentNode === void 0 ? void 0 : parentNode.nodeType) === 35 /* MemberAccess */) {
5920
5766
  const memberName = parentNode.memberName.value;
5921
- const effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
5767
+ let effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
5768
+ // If the bind-to type is a protocol, don't use the effective target class.
5769
+ // This pattern is used for mixins, where the mixin type is a protocol class
5770
+ // that is used to decorate the "self" or "cls" parameter.
5771
+ if (bindToType &&
5772
+ types_1.ClassType.isProtocolClass(bindToType) &&
5773
+ effectiveTargetClass &&
5774
+ !types_1.ClassType.isSameGenericClass(bindToType, effectiveTargetClass)) {
5775
+ effectiveTargetClass = undefined;
5776
+ }
5922
5777
  const lookupResults = bindToType
5923
5778
  ? (0, typeUtils_1.lookUpClassMember)(bindToType, memberName, 0 /* Default */, effectiveTargetClass)
5924
5779
  : undefined;
@@ -5927,8 +5782,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5927
5782
  type: resultIsInstance
5928
5783
  ? types_1.ClassType.cloneAsInstance(lookupResults.classType)
5929
5784
  : lookupResults.classType,
5930
- bindToType: bindToType
5931
- ? types_1.TypeBase.cloneForCondition((0, typeUtils_1.synthesizeTypeVarForSelfCls)(bindToType, !resultIsInstance), bindToType.condition)
5785
+ bindToSelfType: bindToType
5786
+ ? types_1.TypeBase.cloneForCondition((0, typeUtils_1.synthesizeTypeVarForSelfCls)(bindToType, /* isClsParam */ false), bindToType.condition)
5932
5787
  : undefined,
5933
5788
  };
5934
5789
  }
@@ -6418,7 +6273,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6418
6273
  }, {
6419
6274
  allowDiagnostics: true,
6420
6275
  });
6421
- });
6276
+ },
6277
+ /* sortSubtypes */ true);
6422
6278
  // If we ended up with a "Never" type because all code paths returned
6423
6279
  // undefined due to argument errors, transform the result into an Unknown
6424
6280
  // to avoid subsequent false positives.
@@ -6435,7 +6291,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6435
6291
  }
6436
6292
  function validateCallArgumentsForSubtype(errorNode, argList, expandedCallType, unexpandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
6437
6293
  switch (expandedCallType.category) {
6438
- case 4 /* Never */:
6294
+ case 3 /* Never */:
6439
6295
  case 1 /* Unknown */:
6440
6296
  case 2 /* Any */: {
6441
6297
  // Touch all of the args so they're marked accessed. Don't bother
@@ -6450,37 +6306,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6450
6306
  }
6451
6307
  return { returnType: expandedCallType };
6452
6308
  }
6453
- case 5 /* Function */: {
6309
+ case 4 /* Function */: {
6454
6310
  return validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
6455
6311
  }
6456
- case 6 /* OverloadedFunction */: {
6312
+ case 5 /* OverloadedFunction */: {
6457
6313
  return validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
6458
6314
  }
6459
- case 7 /* Class */: {
6315
+ case 6 /* Class */: {
6316
+ if ((0, typeUtils_1.isNoneInstance)(expandedCallType)) {
6317
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
6318
+ return { argumentErrors: true };
6319
+ }
6460
6320
  if (types_1.TypeBase.isInstantiable(expandedCallType)) {
6461
6321
  return validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext);
6462
6322
  }
6463
6323
  return validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6464
6324
  }
6465
- case 3 /* None */: {
6466
- if (types_1.TypeBase.isInstantiable(expandedCallType)) {
6467
- if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
6468
- const callResult = validateCallForInstantiableClass(errorNode, argList, noneType, noneType, skipUnknownArgCheck, inferenceContext);
6469
- return { ...callResult, returnType: types_1.NoneType.createInstance() };
6470
- }
6471
- return { returnType: types_1.NoneType.createInstance() };
6472
- }
6473
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
6474
- return { argumentErrors: true };
6475
- }
6476
6325
  // TypeVars should have been expanded in most cases,
6477
6326
  // but we still need to handle the case of Type[T] where
6478
6327
  // T is a constrained type that contains a union. We also
6479
6328
  // need to handle recursive type aliases.
6480
- case 10 /* TypeVar */: {
6329
+ case 9 /* TypeVar */: {
6481
6330
  return validateCallArguments(errorNode, argList, { type: (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedCallType), isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6482
6331
  }
6483
- case 8 /* Module */: {
6332
+ case 7 /* Module */: {
6484
6333
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
6485
6334
  return { argumentErrors: true };
6486
6335
  }
@@ -6611,7 +6460,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6611
6460
  const returnType = (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
6612
6461
  if ((0, types_1.isClassInstance)(subtype) ||
6613
6462
  ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
6614
- (0, types_1.isNoneInstance)(subtype)) {
6463
+ (0, typeUtils_1.isNoneInstance)(subtype)) {
6615
6464
  return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
6616
6465
  }
6617
6466
  else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
@@ -6655,7 +6504,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6655
6504
  const result = {
6656
6505
  returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
6657
6506
  };
6658
- const initTypeResult = getTypeOfObjectMember(errorNode, types_1.ClassType.cloneAsInstance(expandedCallType), '__init__');
6507
+ const initTypeResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, errorNode, types_1.ClassType.cloneAsInstance(expandedCallType),
6508
+ /* skipObjectBase */ false);
6659
6509
  if (initTypeResult && (0, types_1.isOverloadedFunction)(initTypeResult.type)) {
6660
6510
  validateOverloadedFunctionArguments(errorNode, argList, { type: initTypeResult.type },
6661
6511
  /* typeVarContext */ undefined, skipUnknownArgCheck,
@@ -6756,18 +6606,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6756
6606
  return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
6757
6607
  }
6758
6608
  function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
6759
- var _a, _b;
6760
- const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
6609
+ var _a;
6610
+ const callMethodResult = getTypeOfBoundMember(errorNode, expandedCallType, '__call__',
6761
6611
  /* usage */ undefined,
6762
- /* diag */ undefined, 128 /* SkipAttributeAccessOverride */ | 1 /* AccessClassMembersOnly */)) === null || _a === void 0 ? void 0 : _a.type;
6763
- if (!memberType) {
6612
+ /* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */,
6613
+ /* selfType */ undefined, recursionCount);
6614
+ const callMethodType = callMethodResult === null || callMethodResult === void 0 ? void 0 : callMethodResult.type;
6615
+ if (!callMethodType) {
6764
6616
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6765
6617
  type: printType(expandedCallType),
6766
6618
  }), errorNode);
6767
6619
  return { returnType: types_1.UnknownType.create(), argumentErrors: true };
6768
6620
  }
6769
- const callResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6770
- let returnType = (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
6621
+ const callResult = validateCallArguments(errorNode, argList, { type: callMethodType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6622
+ let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
6771
6623
  if ((0, types_1.isTypeVar)(unexpandedCallType) &&
6772
6624
  types_1.TypeBase.isInstantiable(unexpandedCallType) &&
6773
6625
  (0, types_1.isClass)(expandedCallType) &&
@@ -6847,7 +6699,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6847
6699
  // validation is left to the caller.
6848
6700
  // This logic is based on PEP 3102: https://www.python.org/dev/peps/pep-3102/
6849
6701
  function matchFunctionArgumentsToParameters(errorNode, argList, typeResult, overloadIndex) {
6850
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
6702
+ var _a, _b, _c, _d, _e, _f, _g, _h;
6851
6703
  const paramDetails = (0, parameterUtils_1.getParameterListDetails)(typeResult.type);
6852
6704
  let argIndex = 0;
6853
6705
  let matchedUnpackedListOfUnknownLength = false;
@@ -6959,9 +6811,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6959
6811
  let paramIndex = 0;
6960
6812
  while (argIndex < positionalArgCount) {
6961
6813
  if (argIndex < positionalOnlyLimitIndex && argList[argIndex].name) {
6962
- const fileInfo = AnalyzerNodeInfo.getFileInfo(argList[argIndex].name);
6963
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.argPositional(), argList[argIndex].name);
6964
- reportedArgError = true;
6814
+ const nameNode = argList[argIndex].name;
6815
+ if (nameNode) {
6816
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(nameNode);
6817
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.argPositional(), nameNode);
6818
+ reportedArgError = true;
6819
+ }
6965
6820
  }
6966
6821
  const remainingArgCount = positionalArgCount - argIndex;
6967
6822
  const remainingParamCount = positionParamLimitIndex - paramIndex - 1;
@@ -7021,8 +6876,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7021
6876
  // with a ParamSpec and a Concatenate operator. PEP 612 indicates that
7022
6877
  // all positional parameters specified in the Concatenate must be
7023
6878
  // filled explicitly.
7024
- if (typeResult.type.details.paramSpec && paramIndex < positionParamLimitIndex) {
7025
- if ((0, types_1.isTypeVar)(argTypeResult.type) && argTypeResult.type.paramSpecAccess === 'args') {
6879
+ if (paramIndex < positionParamLimitIndex) {
6880
+ if ((0, types_1.isTypeVar)(argTypeResult.type) &&
6881
+ argTypeResult.type.paramSpecAccess === 'args' &&
6882
+ paramDetails.params[paramIndex].param.category !== 1 /* ArgsList */) {
7026
6883
  if (!isDiagnosticSuppressedForNode(errorNode)) {
7027
6884
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, positionParamLimitIndex === 1
7028
6885
  ? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
@@ -7070,9 +6927,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7070
6927
  listElementType = undefined;
7071
6928
  }
7072
6929
  else {
7073
- listElementType =
7074
- (_e = (_d = getTypeOfIterator({ type: argType, isIncomplete: argTypeResult.isIncomplete },
7075
- /* isAsync */ false, argList[argIndex].valueExpression)) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : types_1.UnknownType.create();
6930
+ const valueExpr = argList[argIndex].valueExpression;
6931
+ const iteratorType = valueExpr
6932
+ ? (_d = getTypeOfIterator({ type: argType, isIncomplete: argTypeResult.isIncomplete },
6933
+ /* isAsync */ false, valueExpr)) === null || _d === void 0 ? void 0 : _d.type
6934
+ : undefined;
6935
+ listElementType = iteratorType !== null && iteratorType !== void 0 ? iteratorType : types_1.UnknownType.create();
7076
6936
  if (paramDetails.params[paramIndex].param.category !== 1 /* ArgsList */) {
7077
6937
  matchedUnpackedListOfUnknownLength = true;
7078
6938
  }
@@ -7104,7 +6964,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7104
6964
  paramType,
7105
6965
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7106
6966
  argument: funcArg,
7107
- errorNode: (_f = argList[argIndex].valueExpression) !== null && _f !== void 0 ? _f : errorNode,
6967
+ errorNode: (_e = argList[argIndex].valueExpression) !== null && _e !== void 0 ? _e : errorNode,
7108
6968
  paramName,
7109
6969
  isParamNameSynthesized: paramDetails.params[paramIndex].param.isNameSynthesized,
7110
6970
  mapsToVarArgList: isParamVariadic && remainingArgCount > remainingParamCount,
@@ -7407,7 +7267,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7407
7267
  paramType,
7408
7268
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7409
7269
  argument: argList[argIndex],
7410
- errorNode: (_g = argList[argIndex].valueExpression) !== null && _g !== void 0 ? _g : errorNode,
7270
+ errorNode: (_f = argList[argIndex].valueExpression) !== null && _f !== void 0 ? _f : errorNode,
7411
7271
  paramName: paramNameValue,
7412
7272
  });
7413
7273
  trySetActive(argList[argIndex], paramDetails.params[paramInfoIndex].param);
@@ -7423,7 +7283,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7423
7283
  paramType,
7424
7284
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7425
7285
  argument: argList[argIndex],
7426
- errorNode: (_h = argList[argIndex].valueExpression) !== null && _h !== void 0 ? _h : errorNode,
7286
+ errorNode: (_g = argList[argIndex].valueExpression) !== null && _g !== void 0 ? _g : errorNode,
7427
7287
  paramName: paramNameValue,
7428
7288
  });
7429
7289
  // Remember that this parameter has already received a value.
@@ -7472,7 +7332,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7472
7332
  requiresTypeVarMatching: false,
7473
7333
  argument: argList[argIndex],
7474
7334
  argType: (0, types_1.isParamSpec)(argType) ? undefined : types_1.AnyType.create(),
7475
- errorNode: (_j = argList[argIndex].valueExpression) !== null && _j !== void 0 ? _j : errorNode,
7335
+ errorNode: (_h = argList[argIndex].valueExpression) !== null && _h !== void 0 ? _h : errorNode,
7476
7336
  });
7477
7337
  }
7478
7338
  }
@@ -8140,6 +8000,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8140
8000
  return { argumentErrors: paramSpecArgResult.argumentErrors, typeVarContexts };
8141
8001
  }
8142
8002
  function validateFunctionArgumentsForParamSpecSignature(errorNode, argList, paramSpec, typeVarContext, signatureTracker) {
8003
+ var _a;
8143
8004
  let paramSpecType = typeVarContext.getParamSpecType(paramSpec);
8144
8005
  if (!paramSpecType) {
8145
8006
  paramSpecType = (0, typeUtils_1.convertTypeToParamSpecValue)(paramSpec);
@@ -8162,8 +8023,37 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8162
8023
  if (functionType.details.paramSpec &&
8163
8024
  functionType.details.parameters.length === 0 &&
8164
8025
  (0, types_1.isTypeSame)(functionType.details.paramSpec, paramSpec)) {
8165
- // TODO - need to perform additional validation here.
8166
- return { argumentErrors: false, typeVarContexts: [srcTypeVarContext] };
8026
+ // If there are any arguments other than *args: P.args or **kwargs: P.kwargs,
8027
+ // report an error.
8028
+ let sawArgs = false;
8029
+ let sawKwargs = false;
8030
+ let argumentErrors = false;
8031
+ let argErrorNode;
8032
+ for (const arg of argList) {
8033
+ const argType = (_a = getTypeOfArgument(arg)) === null || _a === void 0 ? void 0 : _a.type;
8034
+ const isArgTypeCompatible = argType && ((0, types_1.isTypeSame)(argType, paramSpec) || (0, types_1.isAnyOrUnknown)(argType));
8035
+ if (arg.argumentCategory === 1 /* UnpackedList */ && !sawArgs && isArgTypeCompatible) {
8036
+ sawArgs = true;
8037
+ }
8038
+ else if (arg.argumentCategory === 2 /* UnpackedDictionary */ &&
8039
+ !sawKwargs &&
8040
+ isArgTypeCompatible) {
8041
+ sawKwargs = true;
8042
+ }
8043
+ else {
8044
+ argErrorNode = argErrorNode !== null && argErrorNode !== void 0 ? argErrorNode : arg.valueExpression;
8045
+ argumentErrors = true;
8046
+ }
8047
+ }
8048
+ if (!sawArgs || !sawKwargs) {
8049
+ argumentErrors = true;
8050
+ }
8051
+ if (argumentErrors) {
8052
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecArgsMissing().format({
8053
+ type: printType(functionType.details.paramSpec),
8054
+ }), argErrorNode !== null && argErrorNode !== void 0 ? argErrorNode : errorNode);
8055
+ }
8056
+ return { argumentErrors, typeVarContexts: [srcTypeVarContext] };
8167
8057
  }
8168
8058
  const result = validateFunctionArgumentTypes(errorNode, matchResults, srcTypeVarContext, signatureTracker);
8169
8059
  return { argumentErrors: !!result.argumentErrors, typeVarContexts: [srcTypeVarContext] };
@@ -8327,7 +8217,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8327
8217
  }
8328
8218
  }
8329
8219
  if ((0, types_1.isClassInstance)(argType)) {
8330
- const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__', 8 /* SkipInstanceVariables */);
8220
+ const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__', 16 /* SkipInstanceMembers */);
8331
8221
  if (callMember) {
8332
8222
  const memberType = getTypeOfMember(callMember);
8333
8223
  if ((0, types_1.isOverloadedFunction)(memberType)) {
@@ -8891,7 +8781,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8891
8781
  type: types_1.ClassType.cloneAsInstance(baseClass),
8892
8782
  hasDeclaredType: true,
8893
8783
  });
8894
- initType.details.declaredReturnType = types_1.NoneType.createInstance();
8784
+ initType.details.declaredReturnType = getNoneType();
8895
8785
  classType.details.fields.set('__init__', symbol_1.Symbol.createWithType(4 /* ClassMember */, initType));
8896
8786
  // Synthesize a trivial __new__ method.
8897
8787
  const newType = types_1.FunctionType.createSynthesizedInstance('__new__', 1 /* ConstructorMethod */);
@@ -8938,10 +8828,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8938
8828
  function getTypeOfConstant(node, flags) {
8939
8829
  let type;
8940
8830
  if (node.constType === 26 /* None */) {
8941
- type =
8942
- (flags & 128 /* ExpectingInstantiableType */) !== 0
8943
- ? types_1.NoneType.createType()
8944
- : types_1.NoneType.createInstance();
8831
+ type = (flags & 128 /* ExpectingInstantiableType */) !== 0 ? noneClassType : noneType;
8945
8832
  }
8946
8833
  else if (node.constType === 33 /* True */ ||
8947
8834
  node.constType === 15 /* False */ ||
@@ -8958,46 +8845,37 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8958
8845
  }
8959
8846
  }
8960
8847
  }
8961
- if (!type) {
8962
- return undefined;
8963
- }
8964
- return { type };
8848
+ return { type: type !== null && type !== void 0 ? type : types_1.UnknownType.create() };
8965
8849
  }
8966
- function getTypeOfMagicMethodReturn(objType, args, magicMethodName, errorNode, inferenceContext) {
8850
+ function getTypeOfMagicMethodCall(objType, methodName, argList, errorNode, inferenceContext) {
8967
8851
  let magicMethodSupported = true;
8968
8852
  // Create a helper lambda for object subtypes.
8969
8853
  const handleSubtype = (subtype) => {
8970
- var _a, _b;
8971
8854
  let magicMethodType;
8972
8855
  const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
8973
- if ((0, types_1.isClassInstance)(concreteSubtype)) {
8974
- magicMethodType = (_a = getTypeOfObjectMember(errorNode, concreteSubtype, magicMethodName,
8975
- /* usage */ undefined,
8976
- /* diag */ undefined, 128 /* SkipAttributeAccessOverride */ | 1 /* AccessClassMembersOnly */)) === null || _a === void 0 ? void 0 : _a.type;
8977
- }
8978
- else if ((0, types_1.isInstantiableClass)(concreteSubtype)) {
8979
- magicMethodType = (_b = getTypeOfClassMember(errorNode, concreteSubtype, magicMethodName,
8980
- /* usage */ undefined,
8981
- /* diag */ undefined, 128 /* SkipAttributeAccessOverride */ | 64 /* ConsiderMetaclassOnly */)) === null || _b === void 0 ? void 0 : _b.type;
8856
+ if ((0, types_1.isClass)(concreteSubtype)) {
8857
+ magicMethodType = getBoundMagicMethod(concreteSubtype, methodName, subtype);
8982
8858
  }
8983
8859
  if (magicMethodType) {
8984
- const functionArgs = args.map((arg) => {
8860
+ const functionArgs = argList.map((arg) => {
8985
8861
  return {
8986
8862
  argumentCategory: 0 /* Simple */,
8987
8863
  typeResult: arg,
8988
8864
  };
8989
8865
  });
8990
8866
  let callResult;
8991
- useSpeculativeMode(errorNode, () => {
8992
- callResult = validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8867
+ callResult = useSpeculativeMode(errorNode, () => {
8868
+ (0, debug_1.assert)(magicMethodType !== undefined);
8869
+ return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8993
8870
  /* typeVarContext */ undefined,
8994
8871
  /* skipUnknownArgCheck */ true, inferenceContext);
8995
8872
  });
8996
8873
  // If there were errors with the expected type, try
8997
8874
  // to evaluate without the expected type.
8998
8875
  if (callResult.argumentErrors && inferenceContext) {
8999
- useSpeculativeMode(errorNode, () => {
9000
- callResult = validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8876
+ callResult = useSpeculativeMode(errorNode, () => {
8877
+ (0, debug_1.assert)(magicMethodType !== undefined);
8878
+ return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
9001
8879
  /* typeVarContext */ undefined,
9002
8880
  /* skipUnknownArgCheck */ true);
9003
8881
  });
@@ -9017,13 +8895,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9017
8895
  if ((0, types_1.isClassInstance)(subtype) || (0, types_1.isInstantiableClass)(subtype) || (0, types_1.isTypeVar)(subtype)) {
9018
8896
  return handleSubtype(subtype);
9019
8897
  }
9020
- if ((0, types_1.isNoneInstance)(subtype)) {
8898
+ if ((0, typeUtils_1.isNoneInstance)(subtype)) {
9021
8899
  if (objectType && (0, types_1.isClassInstance)(objectType)) {
9022
8900
  // Use 'object' for 'None'.
9023
8901
  return handleSubtype(objectType);
9024
8902
  }
9025
8903
  }
9026
- if ((0, types_1.isNoneTypeClass)(subtype)) {
8904
+ if ((0, typeUtils_1.isNoneTypeClass)(subtype)) {
9027
8905
  if (typeClassType && (0, types_1.isInstantiableClass)(typeClassType)) {
9028
8906
  // Use 'type' for 'type[None]'.
9029
8907
  return handleSubtype(types_1.ClassType.cloneAsInstance(typeClassType));
@@ -9640,7 +9518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9640
9518
  expectedFunctionTypes.push(subtype);
9641
9519
  }
9642
9520
  if ((0, types_1.isClassInstance)(subtype)) {
9643
- const boundMethod = getBoundMethod(subtype, '__call__');
9521
+ const boundMethod = getBoundMagicMethod(subtype, '__call__');
9644
9522
  if (boundMethod && (0, types_1.isFunction)(boundMethod)) {
9645
9523
  expectedFunctionTypes.push(boundMethod);
9646
9524
  }
@@ -9675,11 +9553,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9675
9553
  // Pre-cache the incomplete function type in case the evaluation of the
9676
9554
  // lambda depends on itself.
9677
9555
  writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* None */);
9556
+ // We assume for simplicity that the parameter signature of the lambda is
9557
+ // the same as the expected type. If this isn't the case, we'll use
9558
+ // object for any lambda parameters that don't match. We could make this
9559
+ // more sophisticated in the future, but it becomes very complex to handle
9560
+ // all of the permutations.
9561
+ let sawParamMismatch = false;
9678
9562
  node.parameters.forEach((param, index) => {
9679
9563
  let paramType;
9680
- if (expectedParamDetails) {
9564
+ if (expectedParamDetails && !sawParamMismatch) {
9681
9565
  if (index < expectedParamDetails.params.length) {
9682
- paramType = expectedParamDetails.params[index].type;
9566
+ const expectedParam = expectedParamDetails.params[index];
9567
+ // If the parameter category matches and both of the parameters are
9568
+ // either separators (/ or *) or not separators, copy the type
9569
+ // from the expected parameter.
9570
+ if (expectedParam.param.category === param.category && !param.name === !expectedParam.param.name) {
9571
+ paramType = expectedParam.type;
9572
+ }
9573
+ else {
9574
+ sawParamMismatch = true;
9575
+ }
9683
9576
  }
9684
9577
  else if (param.defaultValue) {
9685
9578
  // If the lambda param has a default value but there is no associated
@@ -9789,8 +9682,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9789
9682
  }
9790
9683
  let expectedElementType;
9791
9684
  if (inferenceContext) {
9792
- expectedElementType = (_a = getTypeOfIterator({ type: inferenceContext.expectedType }, isAsync,
9793
- /* errorNode */ undefined)) === null || _a === void 0 ? void 0 : _a.type;
9685
+ expectedElementType = (_a = getTypeOfIterator({ type: inferenceContext.expectedType }, isAsync, node,
9686
+ /* emitNotIterableError */ false)) === null || _a === void 0 ? void 0 : _a.type;
9794
9687
  }
9795
9688
  const elementTypeResult = getElementTypeFromListComprehension(node, expectedElementType);
9796
9689
  if (elementTypeResult.isIncomplete) {
@@ -9810,9 +9703,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9810
9703
  }
9811
9704
  const builtInIteratorType = getTypingType(node, isAsync ? 'AsyncGenerator' : 'Generator');
9812
9705
  if (builtInIteratorType && (0, types_1.isInstantiableClass)(builtInIteratorType)) {
9813
- type = types_1.ClassType.cloneAsInstance(types_1.ClassType.cloneForSpecialization(builtInIteratorType, isAsync
9814
- ? [elementType, types_1.NoneType.createInstance()]
9815
- : [elementType, types_1.NoneType.createInstance(), types_1.NoneType.createInstance()],
9706
+ type = types_1.ClassType.cloneAsInstance(types_1.ClassType.cloneForSpecialization(builtInIteratorType, isAsync ? [elementType, getNoneType()] : [elementType, getNoneType(), getNoneType()],
9816
9707
  /* isTypeArgumentExplicit */ true));
9817
9708
  }
9818
9709
  return { type, isIncomplete, typeErrors };
@@ -10141,7 +10032,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10141
10032
  addExpectedClassDiagnostic(typeArg0Type, typeArgs[0].node);
10142
10033
  typeArg0Type = types_1.UnknownType.create();
10143
10034
  }
10144
- const optionalType = (0, types_1.combineTypes)([typeArg0Type, types_1.NoneType.createType()]);
10035
+ const optionalType = (0, types_1.combineTypes)([typeArg0Type, noneClassType !== null && noneClassType !== void 0 ? noneClassType : types_1.UnknownType.create()]);
10145
10036
  if ((0, types_1.isUnion)(optionalType)) {
10146
10037
  types_1.TypeBase.setSpecialForm(optionalType);
10147
10038
  }
@@ -10204,7 +10095,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10204
10095
  type = cloneBuiltinClassWithLiteral(node, 'bool', false);
10205
10096
  }
10206
10097
  else if (itemExpr.constType === 26 /* None */) {
10207
- type = types_1.NoneType.createType();
10098
+ type = noneClassType !== null && noneClassType !== void 0 ? noneClassType : types_1.UnknownType.create();
10208
10099
  }
10209
10100
  }
10210
10101
  else if (itemExpr.nodeType === 55 /* UnaryOperation */ &&
@@ -10228,7 +10119,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10228
10119
  let isLiteralType = true;
10229
10120
  (0, typeUtils_1.doForEachSubtype)(exprType.type, (subtype) => {
10230
10121
  if (!(0, types_1.isInstantiableClass)(subtype) || subtype.literalValue === undefined) {
10231
- if (!(0, types_1.isNoneTypeClass)(subtype)) {
10122
+ if (!(0, typeUtils_1.isNoneTypeClass)(subtype)) {
10232
10123
  isLiteralType = false;
10233
10124
  }
10234
10125
  }
@@ -10510,6 +10401,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10510
10401
  let reportedUnpackedError = false;
10511
10402
  // Verify that we didn't receive any inappropriate types.
10512
10403
  typeArgs.forEach((typeArg, index) => {
10404
+ (0, debug_1.assert)(typeArgs !== undefined);
10513
10405
  if ((0, typeUtils_1.isEllipsisType)(typeArg.type)) {
10514
10406
  if (!isTupleTypeParam) {
10515
10407
  if (!allowParamSpec) {
@@ -10639,7 +10531,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10639
10531
  // is allowed if it's an unpacked variadic type var or tuple. None is also allowed
10640
10532
  // since it is used to define NoReturn in typeshed stubs).
10641
10533
  if (types.length === 1) {
10642
- if (!(0, types_1.isVariadicTypeVar)(types[0]) && !(0, types_1.isUnpacked)(types[0]) && !(0, types_1.isNoneInstance)(types[0])) {
10534
+ if (!(0, types_1.isVariadicTypeVar)(types[0]) && !(0, types_1.isUnpacked)(types[0]) && !(0, typeUtils_1.isNoneInstance)(types[0])) {
10643
10535
  addError(localize_1.Localizer.Diagnostic.unionTypeArgCount(), errorNode);
10644
10536
  }
10645
10537
  }
@@ -10696,6 +10588,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10696
10588
  // with this type alias.
10697
10589
  typeParameters = [];
10698
10590
  (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
10591
+ (0, debug_1.assert)(typeParameters !== undefined);
10699
10592
  (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
10700
10593
  });
10701
10594
  // Don't include any synthesized type variables.
@@ -10712,6 +10605,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10712
10605
  // Validate the default types for all type parameters.
10713
10606
  typeParameters.forEach((typeParam, index) => {
10714
10607
  var _a;
10608
+ (0, debug_1.assert)(typeParameters !== undefined);
10715
10609
  let bestErrorNode = errorNode;
10716
10610
  if (typeParamNodes && index < typeParamNodes.length) {
10717
10611
  bestErrorNode = (_a = typeParamNodes[index].defaultExpression) !== null && _a !== void 0 ? _a : typeParamNodes[index].name;
@@ -10988,11 +10882,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10988
10882
  if (typeAliasNameNode) {
10989
10883
  // If this was a speculative type alias, it becomes a real type alias
10990
10884
  // only if the evaluated type is an instantiable type.
10991
- if (!isSpeculativeTypeAlias ||
10992
- (types_1.TypeBase.isInstantiable(rightHandType) && !(0, types_1.isUnknown)(rightHandType))) {
10885
+ if (!isSpeculativeTypeAlias || isLegalImplicitTypeAliasType(rightHandType)) {
10993
10886
  // If this is a type alias, record its name based on the assignment target.
10994
10887
  rightHandType = transformTypeForTypeAlias(rightHandType, typeAliasNameNode, node.rightExpression,
10995
10888
  /* isPep695Syntax */ false);
10889
+ (0, debug_1.assert)(typeAliasTypeVar !== undefined);
10996
10890
  if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, rightHandType)) {
10997
10891
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
10998
10892
  name: typeAliasNameNode.value,
@@ -11115,6 +11009,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11115
11009
  return `__type_of_${paramName}`;
11116
11010
  }
11117
11011
  function getTypeOfClass(node) {
11012
+ initializedBasicTypes(node);
11118
11013
  // Is this type already cached?
11119
11014
  const cachedClassType = readTypeCache(node.name, 0 /* None */);
11120
11015
  if (cachedClassType) {
@@ -11135,7 +11030,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11135
11030
  if ((scope === null || scope === void 0 ? void 0 : scope.type) === 4 /* Builtin */ ||
11136
11031
  fileInfo.isTypingStubFile ||
11137
11032
  fileInfo.isTypingExtensionsStubFile ||
11138
- fileInfo.isBuiltInStubFile) {
11033
+ fileInfo.isBuiltInStubFile ||
11034
+ fileInfo.isTypeshedStubFile) {
11139
11035
  classFlags |= 1 /* BuiltInClass */;
11140
11036
  if (fileInfo.isTypingExtensionsStubFile) {
11141
11037
  classFlags |= 65536 /* TypingExtensionClass */;
@@ -11443,7 +11339,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11443
11339
  classType.details.fields.set('__hash__', symbol_1.Symbol.createWithType(4 /* ClassMember */ |
11444
11340
  128 /* ClassVar */ |
11445
11341
  64 /* IgnoredForProtocolMatch */ |
11446
- 4096 /* IgnoredForOverrideChecks */, types_1.NoneType.createInstance()));
11342
+ 4096 /* IgnoredForOverrideChecks */, getNoneType()));
11447
11343
  }
11448
11344
  // Determine whether the class's instance variables are constrained
11449
11345
  // to those defined by __slots__. We need to do this prior to dataclass
@@ -11707,6 +11603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11707
11603
  if (p.details.isVariadic) {
11708
11604
  return p;
11709
11605
  }
11606
+ (0, debug_1.assert)(objectType !== undefined);
11710
11607
  return i === paramIndex ? objectType : dummyTypeObject;
11711
11608
  });
11712
11609
  // Replace all type arguments with a dummy type except for the
@@ -11875,6 +11772,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11875
11772
  computeEffectiveMetaclass(type, errorNode);
11876
11773
  }
11877
11774
  function validateInitSubclassArgs(node, classType) {
11775
+ var _a, _b;
11878
11776
  // Collect arguments that will be passed to the `__init_subclass__`
11879
11777
  // method described in PEP 487 and validate it.
11880
11778
  const argList = [];
@@ -11888,72 +11786,91 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11888
11786
  });
11889
11787
  }
11890
11788
  });
11891
- const errorNode = argList.length > 0 ? argList[0].node.name : node.name;
11892
- const initSubclassMethodInfo = getTypeOfClassMemberName(errorNode, classType,
11893
- /* isAccessedThroughObject */ false, '__init_subclass__', { method: 'get' },
11894
- /* diag */ undefined, 1 /* AccessClassMembersOnly */ |
11895
- 8 /* SkipObjectBaseClass */ |
11896
- 256 /* SkipOriginalClass */, classType);
11897
- if (initSubclassMethodInfo) {
11898
- const initSubclassMethodType = initSubclassMethodInfo.type;
11899
- if (initSubclassMethodType) {
11900
- validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
11901
- /* typeVarContext */ undefined,
11902
- /* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(types_1.NoneType.createInstance()));
11903
- }
11904
- }
11905
- else if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
11789
+ const errorNode = argList.length > 0 ? (_b = (_a = argList[0].node) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : node.name : node.name;
11790
+ let newMethodMember;
11791
+ if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
11906
11792
  // See if the metaclass has a `__new__` method that accepts keyword parameters.
11907
- const newMethodMember = (0, typeUtils_1.lookUpClassMember)(classType.details.effectiveMetaclass, '__new__', 64 /* SkipTypeBaseClass */);
11908
- if (newMethodMember) {
11909
- const newMethodType = getTypeOfMember(newMethodMember);
11910
- if ((0, types_1.isFunction)(newMethodType)) {
11911
- const paramListDetails = (0, parameterUtils_1.getParameterListDetails)(newMethodType);
11912
- if (paramListDetails.firstKeywordOnlyIndex !== undefined) {
11913
- // Build a map of the keyword-only parameters.
11914
- const paramMap = new Map();
11915
- for (let i = paramListDetails.firstKeywordOnlyIndex; i < paramListDetails.params.length; i++) {
11916
- const paramInfo = paramListDetails.params[i];
11917
- if (paramInfo.param.category === 0 /* Simple */ && paramInfo.param.name) {
11918
- paramMap.set(paramInfo.param.name, i);
11919
- }
11793
+ newMethodMember = (0, typeUtils_1.lookUpClassMember)(classType.details.effectiveMetaclass, '__new__', 8 /* SkipTypeBaseClass */);
11794
+ }
11795
+ if (newMethodMember) {
11796
+ const newMethodType = getTypeOfMember(newMethodMember);
11797
+ if ((0, types_1.isFunction)(newMethodType)) {
11798
+ const paramListDetails = (0, parameterUtils_1.getParameterListDetails)(newMethodType);
11799
+ if (paramListDetails.firstKeywordOnlyIndex !== undefined) {
11800
+ // Build a map of the keyword-only parameters.
11801
+ const paramMap = new Map();
11802
+ for (let i = paramListDetails.firstKeywordOnlyIndex; i < paramListDetails.params.length; i++) {
11803
+ const paramInfo = paramListDetails.params[i];
11804
+ if (paramInfo.param.category === 0 /* Simple */ && paramInfo.param.name) {
11805
+ paramMap.set(paramInfo.param.name, i);
11920
11806
  }
11921
- argList.forEach((arg) => {
11922
- var _a, _b, _c;
11923
- const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
11924
- if (arg.argumentCategory === 0 /* Simple */ && arg.name) {
11925
- const paramIndex = (_a = paramMap.get(arg.name.value)) !== null && _a !== void 0 ? _a : paramListDetails.kwargsIndex;
11926
- if (paramIndex !== undefined) {
11927
- const paramInfo = paramListDetails.params[paramIndex];
11928
- const argParam = {
11929
- paramCategory: paramInfo.param.category,
11930
- paramType: types_1.FunctionType.getEffectiveParameterType(newMethodType, paramInfo.index),
11931
- requiresTypeVarMatching: false,
11932
- argument: arg,
11933
- errorNode: (_b = arg.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
11934
- };
11935
- validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType }, { skipUnknownArgCheck: true, skipOverloadArg: true });
11936
- paramMap.delete(arg.name.value);
11937
- }
11938
- else {
11939
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), (_c = arg.name) !== null && _c !== void 0 ? _c : errorNode);
11940
- }
11807
+ }
11808
+ argList.forEach((arg) => {
11809
+ var _a, _b, _c;
11810
+ const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
11811
+ if (arg.argumentCategory === 0 /* Simple */ && arg.name) {
11812
+ const paramIndex = (_a = paramMap.get(arg.name.value)) !== null && _a !== void 0 ? _a : paramListDetails.kwargsIndex;
11813
+ if (paramIndex !== undefined) {
11814
+ const paramInfo = paramListDetails.params[paramIndex];
11815
+ const argParam = {
11816
+ paramCategory: paramInfo.param.category,
11817
+ paramType: types_1.FunctionType.getEffectiveParameterType(newMethodType, paramInfo.index),
11818
+ requiresTypeVarMatching: false,
11819
+ argument: arg,
11820
+ errorNode: (_b = arg.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
11821
+ };
11822
+ validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType }, { skipUnknownArgCheck: true, skipOverloadArg: true });
11823
+ paramMap.delete(arg.name.value);
11941
11824
  }
11942
- });
11943
- // See if we have any remaining unmatched parameters without
11944
- // default values.
11945
- const unassignedParams = [];
11946
- paramMap.forEach((index, paramName) => {
11947
- const paramInfo = paramListDetails.params[index];
11948
- if (!paramInfo.param.hasDefault) {
11949
- unassignedParams.push(paramName);
11825
+ else {
11826
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), (_c = arg.name) !== null && _c !== void 0 ? _c : errorNode);
11950
11827
  }
11951
- });
11952
- if (unassignedParams.length > 0) {
11953
- const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
11954
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
11955
- ? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
11956
- : localize_1.Localizer.Diagnostic.argMissingForParams().format({ names: missingParamNames }), errorNode);
11828
+ }
11829
+ });
11830
+ // See if we have any remaining unmatched parameters without
11831
+ // default values.
11832
+ const unassignedParams = [];
11833
+ paramMap.forEach((index, paramName) => {
11834
+ const paramInfo = paramListDetails.params[index];
11835
+ if (!paramInfo.param.hasDefault) {
11836
+ unassignedParams.push(paramName);
11837
+ }
11838
+ });
11839
+ if (unassignedParams.length > 0) {
11840
+ const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
11841
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
11842
+ ? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
11843
+ : localize_1.Localizer.Diagnostic.argMissingForParams().format({ names: missingParamNames }), errorNode);
11844
+ }
11845
+ }
11846
+ }
11847
+ }
11848
+ else {
11849
+ // If there was no custom metaclass __new__ method, see if there is an __init_subclass__
11850
+ // method present somewhere in the class hierarchy.
11851
+ const initSubclassMethodInfo = getTypeOfBoundMember(errorNode, classType, '__init_subclass__',
11852
+ /* usage */ undefined,
11853
+ /* diag */ undefined, 32 /* SkipClassMembers */ |
11854
+ 1 /* SkipOriginalClass */ |
11855
+ 512 /* SkipAttributeAccessOverride */);
11856
+ if (initSubclassMethodInfo) {
11857
+ const initSubclassMethodType = initSubclassMethodInfo.type;
11858
+ if (initSubclassMethodType && initSubclassMethodInfo.classType) {
11859
+ const callResult = validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
11860
+ /* typeVarContext */ undefined,
11861
+ /* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(getNoneType()));
11862
+ if (callResult.argumentErrors) {
11863
+ const diag = addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.initSubclassCallFailed(), node.name);
11864
+ const initSubclassFunction = (0, types_1.isOverloadedFunction)(initSubclassMethodType)
11865
+ ? types_1.OverloadedFunctionType.getOverloads(initSubclassMethodType)[0]
11866
+ : initSubclassMethodType;
11867
+ const initSubclassDecl = (0, types_1.isFunction)(initSubclassFunction)
11868
+ ? initSubclassFunction.details.declaration
11869
+ : undefined;
11870
+ if (diag && initSubclassDecl) {
11871
+ diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.initSubclassLocation().format({
11872
+ name: printType((0, typeUtils_1.convertToInstance)(initSubclassMethodInfo.classType)),
11873
+ }), initSubclassDecl.path, initSubclassDecl.range);
11957
11874
  }
11958
11875
  }
11959
11876
  }
@@ -11967,6 +11884,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11967
11884
  });
11968
11885
  }
11969
11886
  function getTypeOfFunction(node) {
11887
+ initializedBasicTypes(node);
11970
11888
  // Is this predecorated function type cached?
11971
11889
  let functionType = readTypeCache(node.name, 0 /* None */);
11972
11890
  if (functionType) {
@@ -12116,7 +12034,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12116
12034
  // accumulate the list of type parameters upfront.
12117
12035
  const typeParametersSeen = [];
12118
12036
  if (node.typeParameters) {
12119
- functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
12037
+ functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters).map((typeParam) => (0, typeUtils_1.convertToInstance)(typeParam));
12120
12038
  }
12121
12039
  else {
12122
12040
  functionType.details.typeParameters = typeParametersSeen;
@@ -12329,7 +12247,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12329
12247
  // Special-case the __init__ method, which is commonly left without
12330
12248
  // an annotated return type, but we can assume it returns None.
12331
12249
  if (node.name.value === '__init__') {
12332
- functionType.details.declaredReturnType = types_1.NoneType.createInstance();
12250
+ functionType.details.declaredReturnType = getNoneType();
12333
12251
  }
12334
12252
  else {
12335
12253
  functionType.details.declaredReturnType = types_1.UnknownType.create();
@@ -12422,7 +12340,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12422
12340
  param.defaultValue.constType === 26 /* None */ &&
12423
12341
  !(0, typeUtils_1.isOptionalType)(type) &&
12424
12342
  !AnalyzerNodeInfo.getFileInfo(param).diagnosticRuleSet.strictParameterNoneValue) {
12425
- return (0, types_1.combineTypes)([type, types_1.NoneType.createInstance()]);
12343
+ return (0, types_1.combineTypes)([type, getNoneType()]);
12426
12344
  }
12427
12345
  return type;
12428
12346
  }
@@ -12482,7 +12400,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12482
12400
  // whose name starts with an underscore)? If so, we will assume that the
12483
12401
  // value is a singleton sentinel. The actual supported type is going to be
12484
12402
  // a union of this type and Unknown.
12485
- if ((0, types_1.isNoneInstance)(defaultValueType) ||
12403
+ if ((0, typeUtils_1.isNoneInstance)(defaultValueType) ||
12486
12404
  ((0, types_1.isClassInstance)(defaultValueType) && (0, symbolNameUtils_1.isPrivateOrProtectedName)(defaultValueType.details.name))) {
12487
12405
  inferredParamType = (0, types_1.combineTypes)([defaultValueType, types_1.UnknownType.create()]);
12488
12406
  }
@@ -12680,13 +12598,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12680
12598
  inferredReturnTypes.push(returnType);
12681
12599
  }
12682
12600
  else {
12683
- inferredReturnTypes.push(types_1.NoneType.createInstance());
12601
+ inferredReturnTypes.push(getNoneType());
12684
12602
  }
12685
12603
  }
12686
12604
  });
12687
12605
  }
12688
12606
  if (!functionNeverReturns && implicitlyReturnsNone) {
12689
- inferredReturnTypes.push(types_1.NoneType.createInstance());
12607
+ inferredReturnTypes.push(getNoneType());
12690
12608
  }
12691
12609
  inferredReturnType = (0, types_1.combineTypes)(inferredReturnTypes);
12692
12610
  // Remove any unbound values since those would generate an exception
@@ -12728,14 +12646,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12728
12646
  inferredYieldTypes.push(yieldType !== null && yieldType !== void 0 ? yieldType : types_1.UnknownType.create());
12729
12647
  }
12730
12648
  else {
12731
- inferredYieldTypes.push(types_1.NoneType.createInstance());
12649
+ inferredYieldTypes.push(getNoneType());
12732
12650
  }
12733
12651
  }
12734
12652
  }
12735
12653
  });
12736
12654
  }
12737
12655
  if (inferredYieldTypes.length === 0) {
12738
- inferredYieldTypes.push(types_1.NoneType.createInstance());
12656
+ inferredYieldTypes.push(getNoneType());
12739
12657
  }
12740
12658
  const inferredYieldType = (0, types_1.combineTypes)(inferredYieldTypes);
12741
12659
  // Inferred yield types need to be wrapped in a Generator or
@@ -12749,7 +12667,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12749
12667
  // This eliminates any "partially unknown" errors in strict mode
12750
12668
  // in the common case.
12751
12669
  const sendType = isYieldResultUsed ? types_1.UnknownType.create() : types_1.AnyType.create();
12752
- typeArgs.push(inferredYieldType, sendType, (0, types_1.isNever)(inferredReturnType) ? types_1.NoneType.createInstance() : inferredReturnType);
12670
+ typeArgs.push(inferredYieldType, sendType, (0, types_1.isNever)(inferredReturnType) ? getNoneType() : inferredReturnType);
12753
12671
  if (useAwaitableGenerator) {
12754
12672
  typeArgs.push(types_1.AnyType.create());
12755
12673
  }
@@ -12866,7 +12784,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12866
12784
  if ((0, typeUtils_1.isOptionalType)(exprType)) {
12867
12785
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
12868
12786
  addDiagnostic(fileInfo.diagnosticRuleSet.reportOptionalContextManager, diagnosticRules_1.DiagnosticRule.reportOptionalContextManager, localize_1.Localizer.Diagnostic.noneNotUsableWith(), node.expression);
12869
- exprType = (0, types_1.removeNoneFromUnion)(exprType);
12787
+ exprType = (0, typeUtils_1.removeNoneFromUnion)(exprType);
12870
12788
  }
12871
12789
  // Verify that the target has an __enter__ or __aenter__ method defined.
12872
12790
  const enterMethodName = isAsync ? '__aenter__' : '__enter__';
@@ -12877,7 +12795,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12877
12795
  }
12878
12796
  const additionalHelp = new diagnostic_1.DiagnosticAddendum();
12879
12797
  if ((0, types_1.isClass)(subtype)) {
12880
- let enterType = getTypeOfMagicMethodReturn(subtype, [], enterMethodName, node.expression,
12798
+ let enterType = getTypeOfMagicMethodCall(subtype, enterMethodName, [], node.expression,
12881
12799
  /* inferenceContext */ undefined);
12882
12800
  if (enterType) {
12883
12801
  // For "async while", an implicit "await" is performed.
@@ -12887,7 +12805,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12887
12805
  return enterType;
12888
12806
  }
12889
12807
  if (!isAsync) {
12890
- if (getTypeOfMagicMethodReturn(subtype, [], '__aenter__', node.expression,
12808
+ if (getTypeOfMagicMethodCall(subtype, '__aenter__', [], node.expression,
12891
12809
  /* inferenceContext */ undefined)) {
12892
12810
  additionalHelp.addMessage(localize_1.Localizer.DiagnosticAddendum.asyncHelp());
12893
12811
  }
@@ -12907,7 +12825,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12907
12825
  }
12908
12826
  if ((0, types_1.isClass)(subtype)) {
12909
12827
  const anyArg = { type: types_1.AnyType.create() };
12910
- const exitType = getTypeOfMagicMethodReturn(subtype, [anyArg, anyArg, anyArg], exitMethodName, node.expression,
12828
+ const exitType = getTypeOfMagicMethodCall(subtype, exitMethodName, [anyArg, anyArg, anyArg], node.expression,
12911
12829
  /* inferenceContext */ undefined);
12912
12830
  if (exitType) {
12913
12831
  return;
@@ -14001,6 +13919,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14001
13919
  else {
14002
13920
  // Avoid emitting this error for a partially-constructed class.
14003
13921
  if (!(0, types_1.isClassInstance)(typeArgType) || !types_1.ClassType.isPartiallyEvaluated(typeArgType)) {
13922
+ (0, debug_1.assert)(typeArgs !== undefined);
14004
13923
  const fileInfo = AnalyzerNodeInfo.getFileInfo(typeArgs[index].node);
14005
13924
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarAssignmentMismatch().format({
14006
13925
  type: printType(typeArgType),
@@ -14042,6 +13961,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14042
13961
  }
14043
13962
  // If there was no defined type provided, there should always
14044
13963
  // be a value expression from which we can retrieve the type.
13964
+ (0, debug_1.assert)(arg.valueExpression !== undefined);
14045
13965
  return getTypeOfExpressionExpectingType(arg.valueExpression, options);
14046
13966
  }
14047
13967
  function getTypeOfExpressionExpectingType(node, options) {
@@ -14345,7 +14265,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14345
14265
  if ((0, types_1.isInstantiableClass)(subtype)) {
14346
14266
  // Try to find a member that has a declared type. If so, that
14347
14267
  // overrides any inferred types.
14348
- let member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName, 32 /* DeclaredTypesOnly */);
14268
+ let member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName, 64 /* DeclaredTypesOnly */);
14349
14269
  if (!member) {
14350
14270
  member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName);
14351
14271
  }
@@ -14362,7 +14282,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14362
14282
  else if ((0, types_1.isClassInstance)(subtype)) {
14363
14283
  // Try to find a member that has a declared type. If so, that
14364
14284
  // overrides any inferred types.
14365
- let member = (0, typeUtils_1.lookUpObjectMember)(subtype, memberName, 32 /* DeclaredTypesOnly */);
14285
+ let member = (0, typeUtils_1.lookUpObjectMember)(subtype, memberName, 64 /* DeclaredTypesOnly */);
14366
14286
  if (!member) {
14367
14287
  member = (0, typeUtils_1.lookUpObjectMember)(subtype, memberName);
14368
14288
  }
@@ -14427,8 +14347,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14427
14347
  });
14428
14348
  }
14429
14349
  else if ((0, types_1.isInstantiableClass)(baseType)) {
14430
- const initMethodType = (_b = getTypeOfObjectMember(argNode.parent.leftExpression, types_1.ClassType.cloneAsInstance(baseType), '__init__', { method: 'get' },
14431
- /* diag */ undefined, 8 /* SkipObjectBaseClass */)) === null || _b === void 0 ? void 0 : _b.type;
14350
+ const initMethodType = (_b = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, argNode.parent.leftExpression, types_1.ClassType.cloneAsInstance(baseType))) === null || _b === void 0 ? void 0 : _b.type;
14432
14351
  if (initMethodType && (0, types_1.isFunction)(initMethodType)) {
14433
14352
  const paramDecl = getDeclarationFromFunctionNamedParameter(initMethodType, paramName);
14434
14353
  if (paramDecl) {
@@ -14492,7 +14411,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14492
14411
  return { type: strType };
14493
14412
  }
14494
14413
  if (declaration.intrinsicType === 'str | None') {
14495
- return { type: (0, types_1.combineTypes)([strType, types_1.NoneType.createInstance()]) };
14414
+ return { type: (0, types_1.combineTypes)([strType, getNoneType()]) };
14496
14415
  }
14497
14416
  if (declaration.intrinsicType === 'int') {
14498
14417
  return { type: intType };
@@ -14810,6 +14729,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14810
14729
  // If the resolved declaration had no defined type, use the
14811
14730
  // inferred type for this node.
14812
14731
  if (resolvedDecl.type === 2 /* Parameter */) {
14732
+ (0, debug_1.assert)(resolvedDecl.node.name !== undefined);
14813
14733
  return (_b = evaluateTypeForSubnode(resolvedDecl.node.name, () => {
14814
14734
  evaluateTypeOfParameter(resolvedDecl.node);
14815
14735
  })) === null || _b === void 0 ? void 0 : _b.type;
@@ -14828,8 +14748,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14828
14748
  // See if this is an enum member. If so, we need to handle it as a special case.
14829
14749
  const enumMemberType = (0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, resolvedDecl.node, () => {
14830
14750
  var _a, _b;
14831
- return ((_b = (_a = evaluateTypeForSubnode(resolvedDecl.inferredTypeSource, () => {
14832
- evaluateTypesForStatement(resolvedDecl.inferredTypeSource);
14751
+ (0, debug_1.assert)(resolvedDecl.inferredTypeSource !== undefined);
14752
+ const inferredTypeSource = resolvedDecl.inferredTypeSource;
14753
+ return ((_b = (_a = evaluateTypeForSubnode(inferredTypeSource, () => {
14754
+ evaluateTypesForStatement(inferredTypeSource);
14833
14755
  })) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create());
14834
14756
  });
14835
14757
  if (enumMemberType) {
@@ -14840,9 +14762,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14840
14762
  // If this was a speculative type alias, it becomes a real type alias only
14841
14763
  // in the event that its inferred type is instantiable or explicitly Any
14842
14764
  // (but not an ellipsis).
14843
- if (types_1.TypeBase.isInstantiable(inferredType) &&
14844
- !(0, types_1.isUnknown)(inferredType) &&
14845
- !(0, typeUtils_1.isEllipsisType)(inferredType)) {
14765
+ if (isLegalImplicitTypeAliasType(inferredType)) {
14846
14766
  inferredType = transformTypeForTypeAlias(inferredType, resolvedDecl.typeAliasName, resolvedDecl.node,
14847
14767
  /* isPep695Syntax */ false);
14848
14768
  isUnambiguousType = true;
@@ -15311,7 +15231,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15311
15231
  // Don't bother inferring the return type of __init__ because it's
15312
15232
  // always None.
15313
15233
  if (types_1.FunctionType.isInstanceMethod(type) && type.details.name === '__init__') {
15314
- returnType = types_1.NoneType.createInstance();
15234
+ returnType = getNoneType();
15315
15235
  }
15316
15236
  else if (type.details.declaration) {
15317
15237
  const functionNode = type.details.declaration.node;
@@ -15602,8 +15522,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15602
15522
  // derive from the source. We also need to use this path if we're
15603
15523
  // testing to see if the metaclass matches the protocol.
15604
15524
  if (types_1.ClassType.isProtocolClass(destType) && !isDerivedFrom) {
15605
- if (!(0, protocols_1.assignClassToProtocol)(evaluatorInterface, destType, srcType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags,
15606
- /* treatSourceAsInstantiable */ false, recursionCount)) {
15525
+ if (!(0, protocols_1.assignClassToProtocol)(evaluatorInterface, destType, types_1.ClassType.cloneAsInstance(srcType), diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
15607
15526
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.protocolIncompatible().format({
15608
15527
  sourceType: printType((0, typeUtils_1.convertToInstance)(srcType)),
15609
15528
  destType: printType((0, typeUtils_1.convertToInstance)(destType)),
@@ -15855,9 +15774,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15855
15774
  for (let ancestorIndex = inheritanceChain.length - 1; ancestorIndex >= 0; ancestorIndex--) {
15856
15775
  const ancestorType = inheritanceChain[ancestorIndex];
15857
15776
  // If we've hit an "unknown", all bets are off, and we need to assume
15858
- // that the type is assignable.
15777
+ // that the type is assignable. If the destType is marked "@final",
15778
+ // we should be able to assume that it's not assignable, but we can't do
15779
+ // this in the general case because it breaks assumptions with the
15780
+ // NotImplemented symbol exported by typeshed's builtins.pyi. Instead,
15781
+ // we'll special-case only None.
15859
15782
  if ((0, types_1.isUnknown)(ancestorType)) {
15860
- return true;
15783
+ return !(0, typeUtils_1.isNoneTypeClass)(destType);
15861
15784
  }
15862
15785
  // If this isn't the first time through the loop, specialize
15863
15786
  // for the next ancestor in the chain.
@@ -15910,24 +15833,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15910
15833
  const srcTypeArgs = curSrcType.typeArguments;
15911
15834
  for (let i = 0; i < destType.details.typeParameters.length; i++) {
15912
15835
  const typeArgType = i < srcTypeArgs.length ? srcTypeArgs[i] : types_1.UnknownType.create();
15913
- destTypeVarContext.setTypeVarType(destType.details.typeParameters[i],
15914
- /* narrowBound */ undefined,
15915
- /* narrowBoundNoLiterals */ undefined, typeArgType);
15836
+ const typeParam = destType.details.typeParameters[i];
15837
+ const variance = types_1.TypeVarType.getVariance(typeParam);
15838
+ (0, constraintSolver_1.updateTypeVarType)(evaluatorInterface, destTypeVarContext, typeParam, variance !== 4 /* Contravariant */ ? typeArgType : undefined, variance !== 3 /* Covariant */ ? typeArgType : undefined,
15839
+ /* forceRetainLiterals */ true);
15916
15840
  }
15917
15841
  }
15918
15842
  return true;
15919
15843
  }
15920
15844
  function getGetterTypeFromProperty(propertyClass, inferTypeIfNeeded) {
15921
- var _a;
15922
15845
  if (!types_1.ClassType.isPropertyClass(propertyClass)) {
15923
15846
  return undefined;
15924
15847
  }
15925
- const fgetSymbol = propertyClass.details.fields.get('fget');
15926
- if (fgetSymbol) {
15927
- const fgetType = (_a = getDeclaredTypeOfSymbol(fgetSymbol)) === null || _a === void 0 ? void 0 : _a.type;
15928
- if (fgetType && (0, types_1.isFunction)(fgetType)) {
15929
- return getFunctionEffectiveReturnType(fgetType, /* args */ undefined, inferTypeIfNeeded);
15930
- }
15848
+ if (propertyClass.fgetFunction) {
15849
+ return getFunctionEffectiveReturnType(propertyClass.fgetFunction, /* args */ undefined, inferTypeIfNeeded);
15931
15850
  }
15932
15851
  return undefined;
15933
15852
  }
@@ -16274,23 +16193,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16274
16193
  if ((0, types_1.isUnion)(destType)) {
16275
16194
  return assignToUnionType(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount);
16276
16195
  }
16277
- if ((0, types_1.isNoneInstance)(destType)) {
16278
- if ((0, types_1.isNoneInstance)(srcType)) {
16196
+ if ((0, typeUtils_1.isNoneInstance)(destType)) {
16197
+ if ((0, typeUtils_1.isNoneInstance)(srcType)) {
16279
16198
  return true;
16280
16199
  }
16281
16200
  if ((0, types_1.isClassInstance)(srcType) && types_1.ClassType.isBuiltIn(srcType, 'NoneType')) {
16282
16201
  return true;
16283
16202
  }
16284
16203
  }
16285
- if ((0, types_1.isNoneTypeClass)(destType)) {
16286
- if ((0, types_1.isNoneTypeClass)(srcType)) {
16204
+ if ((0, typeUtils_1.isNoneTypeClass)(destType)) {
16205
+ if ((0, typeUtils_1.isNoneTypeClass)(srcType)) {
16287
16206
  return true;
16288
16207
  }
16289
16208
  if ((0, types_1.isInstantiableClass)(srcType) && types_1.ClassType.isBuiltIn(srcType, 'NoneType')) {
16290
16209
  return true;
16291
16210
  }
16292
16211
  }
16293
- // Is the src a specialized "Type" object?
16212
+ // Is the src a specialized "type" object?
16294
16213
  if ((0, types_1.isClassInstance)(expandedSrcType) && types_1.ClassType.isBuiltIn(expandedSrcType, 'type')) {
16295
16214
  const srcTypeArgs = expandedSrcType.typeArguments;
16296
16215
  let typeTypeArg;
@@ -16342,6 +16261,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16342
16261
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
16343
16262
  return false;
16344
16263
  }
16264
+ else if ((0, types_1.isClassInstance)(expandedSrcType) && (0, typeUtils_1.isMetaclassInstance)(expandedSrcType)) {
16265
+ // If the source is a metaclass instance, verify that it's compatible with
16266
+ // the metaclass of the instantiable dest type.
16267
+ const destMetaclass = destType.details.effectiveMetaclass;
16268
+ if (destMetaclass && (0, types_1.isInstantiableClass)(destMetaclass)) {
16269
+ if (assignClass(types_1.ClassType.cloneAsInstance(destMetaclass), expandedSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount,
16270
+ /* reportErrorsUsingObjType */ false)) {
16271
+ return true;
16272
+ }
16273
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
16274
+ return false;
16275
+ }
16276
+ }
16345
16277
  }
16346
16278
  if ((0, types_1.isClassInstance)(destType)) {
16347
16279
  // Is the dest a specialized "Type" object?
@@ -16435,8 +16367,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16435
16367
  // If the destType is an instantiation of a Protocol,
16436
16368
  // see if the class type itself satisfies the protocol.
16437
16369
  if (types_1.ClassType.isProtocolClass(destType)) {
16438
- return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), concreteSrcType, diag, destTypeVarContext, srcTypeVarContext, flags,
16439
- /* treatSourceAsInstantiable */ true, recursionCount);
16370
+ return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), concreteSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16440
16371
  }
16441
16372
  // Determine if the metaclass can be assigned to the object.
16442
16373
  const metaclass = concreteSrcType.details.effectiveMetaclass;
@@ -16460,14 +16391,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16460
16391
  if ((0, types_1.isFunction)(destType)) {
16461
16392
  let concreteSrcType = makeTopLevelTypeVarsConcrete(srcType);
16462
16393
  if ((0, types_1.isClassInstance)(concreteSrcType)) {
16463
- const boundMethod = getBoundMethod(concreteSrcType, '__call__', recursionCount);
16394
+ const boundMethod = getBoundMagicMethod(concreteSrcType, '__call__',
16395
+ /* selfType */ undefined, recursionCount);
16464
16396
  if (boundMethod) {
16465
16397
  concreteSrcType = (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
16466
16398
  }
16467
16399
  }
16468
16400
  // If it's a class, use the constructor for type compatibility checking.
16469
16401
  if ((0, types_1.isInstantiableClass)(concreteSrcType) && concreteSrcType.literalValue === undefined) {
16470
- const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, recursionCount);
16402
+ const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, (0, types_1.isTypeVar)(srcType) ? (0, typeUtils_1.convertToInstance)(srcType) : undefined, recursionCount);
16471
16403
  if (constructor) {
16472
16404
  concreteSrcType = constructor;
16473
16405
  }
@@ -16560,13 +16492,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16560
16492
  }
16561
16493
  }
16562
16494
  // Are we trying to assign None to a protocol?
16563
- if ((0, types_1.isNoneInstance)(srcType) && (0, types_1.isClassInstance)(destType) && types_1.ClassType.isProtocolClass(destType)) {
16564
- if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
16565
- return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), noneType, diag, destTypeVarContext, srcTypeVarContext, flags,
16566
- /* treatSourceAsInstantiable */ false, recursionCount);
16495
+ if ((0, typeUtils_1.isNoneInstance)(srcType) && (0, types_1.isClassInstance)(destType) && types_1.ClassType.isProtocolClass(destType)) {
16496
+ if (noneClassType && (0, types_1.isInstantiableClass)(noneClassType)) {
16497
+ return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), types_1.ClassType.cloneAsInstance(noneClassType), diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16567
16498
  }
16568
16499
  }
16569
- if ((0, types_1.isNoneInstance)(destType)) {
16500
+ if ((0, typeUtils_1.isNoneInstance)(destType)) {
16570
16501
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.assignToNone());
16571
16502
  return false;
16572
16503
  }
@@ -16823,7 +16754,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16823
16754
  // match we find because we may need to match TypeVars in other
16824
16755
  // subtypes. We special-case "None" so we can handle Optional[T]
16825
16756
  // without matching the None to the type var.
16826
- if ((0, types_1.isNoneInstance)(srcType) && (0, typeUtils_1.isOptionalType)(destType)) {
16757
+ if ((0, typeUtils_1.isNoneInstance)(srcType) && (0, typeUtils_1.isOptionalType)(destType)) {
16827
16758
  foundMatch = true;
16828
16759
  }
16829
16760
  else {
@@ -16952,7 +16883,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16952
16883
  }
16953
16884
  }
16954
16885
  }
16955
- const boundMethod = getBoundMethod(objType, '__call__', recursionCount);
16886
+ const boundMethod = getBoundMagicMethod(objType, '__call__', /* selfType */ undefined, recursionCount);
16956
16887
  if (boundMethod) {
16957
16888
  return (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
16958
16889
  }
@@ -17038,7 +16969,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17038
16969
  if (srcDetails.params.length < destDetails.argsIndex) {
17039
16970
  return;
17040
16971
  }
17041
- let srcLastToPackIndex = srcDetails.params.findIndex((p, i) => i >= destDetails.argsIndex && p.source === parameterUtils_1.ParameterSource.KeywordOnly);
16972
+ let srcLastToPackIndex = srcDetails.params.findIndex((p, i) => {
16973
+ (0, debug_1.assert)(destDetails.argsIndex !== undefined);
16974
+ return i >= destDetails.argsIndex && p.source === parameterUtils_1.ParameterSource.KeywordOnly;
16975
+ });
17042
16976
  if (srcLastToPackIndex < 0) {
17043
16977
  srcLastToPackIndex = srcDetails.params.length;
17044
16978
  }
@@ -17106,15 +17040,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17106
17040
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
17107
17041
  let canAssign = true;
17108
17042
  const checkReturnType = (flags & 32 /* SkipFunctionReturnTypeCheck */) === 0;
17043
+ const reverseMatching = (flags & 2 /* ReverseTypeVarMatching */) !== 0;
17109
17044
  flags &= ~32 /* SkipFunctionReturnTypeCheck */;
17110
17045
  destType = (0, typeUtils_1.removeParamSpecVariadicsFromFunction)(destType);
17111
17046
  srcType = (0, typeUtils_1.removeParamSpecVariadicsFromFunction)(srcType);
17112
17047
  const destParamDetails = (0, parameterUtils_1.getParameterListDetails)(destType);
17113
17048
  const srcParamDetails = (0, parameterUtils_1.getParameterListDetails)(srcType);
17114
- adjustSourceParamDetailsForDestVariadic(srcParamDetails, destParamDetails);
17115
- const targetIncludesParamSpec = (flags & 2 /* ReverseTypeVarMatching */) !== 0
17116
- ? !!srcType.details.paramSpec
17117
- : !!destType.details.paramSpec;
17049
+ adjustSourceParamDetailsForDestVariadic(reverseMatching ? destParamDetails : srcParamDetails, reverseMatching ? srcParamDetails : destParamDetails);
17050
+ const targetIncludesParamSpec = reverseMatching ? !!srcType.details.paramSpec : !!destType.details.paramSpec;
17118
17051
  const destPositionalCount = (_b = (_a = destParamDetails.argsIndex) !== null && _a !== void 0 ? _a : destParamDetails.firstKeywordOnlyIndex) !== null && _b !== void 0 ? _b : destParamDetails.params.length;
17119
17052
  const srcPositionalCount = (_d = (_c = srcParamDetails.argsIndex) !== null && _c !== void 0 ? _c : srcParamDetails.firstKeywordOnlyIndex) !== null && _d !== void 0 ? _d : srcParamDetails.params.length;
17120
17053
  const positionalsToMatch = Math.min(destPositionalCount, srcPositionalCount);
@@ -17387,7 +17320,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17387
17320
  canAssign = false;
17388
17321
  }
17389
17322
  }
17390
- const effectiveSrcTypeVarContext = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? srcTypeVarContext : destTypeVarContext;
17323
+ const effectiveSrcTypeVarContext = reverseMatching ? destTypeVarContext : srcTypeVarContext;
17391
17324
  // If the target function was generic and we solved some of the type variables
17392
17325
  // in that generic type, assign them back to the destination typeVar.
17393
17326
  const typeVarSignatureContext = effectiveSrcTypeVarContext.getPrimarySignature();
@@ -17397,8 +17330,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17397
17330
  });
17398
17331
  // Are we assigning to a function with a ParamSpec?
17399
17332
  if (targetIncludesParamSpec) {
17400
- const effectiveDestType = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? destType : srcType;
17401
- const effectiveSrcType = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? srcType : destType;
17333
+ const effectiveDestType = reverseMatching ? srcType : destType;
17334
+ const effectiveSrcType = reverseMatching ? destType : srcType;
17402
17335
  if (effectiveDestType.details.paramSpec) {
17403
17336
  const requiredMatchParamCount = effectiveDestType.details.parameters.filter((p) => {
17404
17337
  if (!p.name) {
@@ -17451,9 +17384,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17451
17384
  remainingParams.forEach((param) => {
17452
17385
  types_1.FunctionType.addParameter(remainingFunction, param);
17453
17386
  });
17454
- remainingFunction.details.paramSpec = srcParamSpec
17455
- ? (0, typeUtils_1.convertToInstance)(srcParamSpec)
17456
- : undefined;
17387
+ remainingFunction.details.paramSpec = srcParamSpec ? (0, typeUtils_1.convertToInstance)(srcParamSpec) : undefined;
17457
17388
  if (!assignType(destParamSpec, remainingFunction,
17458
17389
  /* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags)) {
17459
17390
  // If we couldn't assign the function to the ParamSpec, see if we can
@@ -17703,7 +17634,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17703
17634
  matchIndex = possibleMatchIndex;
17704
17635
  }
17705
17636
  if (matchIndex < 0) {
17706
- continue;
17637
+ break;
17707
17638
  }
17708
17639
  if (matchIndex < previousMatchIndex) {
17709
17640
  diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadOrder());
@@ -17712,9 +17643,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17712
17643
  previousMatchIndex = matchIndex;
17713
17644
  }
17714
17645
  if (previousMatchIndex < baseOverloads.length - 1) {
17715
- // We didn't find matches for all of the base overloads.
17716
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch());
17717
- return false;
17646
+ const unmatchedOverloads = baseOverloads.slice(previousMatchIndex + 1);
17647
+ // See if all of the remaining overrides are nonapplicable.
17648
+ if (!baseClass ||
17649
+ unmatchedOverloads.some((overload) => {
17650
+ return isOverrideMethodApplicable(overload, baseClass);
17651
+ })) {
17652
+ // We didn't find matches for all of the base overloads.
17653
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch());
17654
+ return false;
17655
+ }
17718
17656
  }
17719
17657
  return true;
17720
17658
  }
@@ -18150,85 +18088,45 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18150
18088
  });
18151
18089
  return methodList;
18152
18090
  }
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
- }
18161
18091
  // If the memberType is an instance or class method, creates a new
18162
18092
  // version of the function that has the "self" or "cls" parameter bound
18163
- // to it. If treatAsClassMethod is true, the function is treated like a
18164
- // class method even if it's not marked as such. That's needed to
18165
- // special-case the __new__ magic method when it's invoked as a
18166
- // constructor (as opposed to by name).
18167
- function bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMember = false, firstParamType, diag, recursionCount = 0) {
18168
- if ((0, types_1.isFunction)(memberType)) {
18093
+ // to it. If treatConstructorAsClassMember is true, the function is
18094
+ // treated like a class method even if it's not marked as such. That's
18095
+ // needed to special-case the __new__ magic method when it's invoked as
18096
+ // a constructor (as opposed to by name).
18097
+ function bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMember = false, selfType, diag, recursionCount = 0) {
18098
+ return (0, typeUtils_1.mapSignatures)(memberType, (functionType) => {
18169
18099
  // If the caller specified no base type, always strip the
18170
18100
  // first parameter. This is used in cases like constructors.
18171
18101
  if (!baseType) {
18172
- return types_1.FunctionType.clone(memberType, /* stripFirstParam */ true);
18102
+ return types_1.FunctionType.clone(functionType, /* stripFirstParam */ true);
18173
18103
  }
18174
- if (types_1.FunctionType.isInstanceMethod(memberType)) {
18104
+ if (types_1.FunctionType.isInstanceMethod(functionType)) {
18175
18105
  // If the baseType is a metaclass, don't specialize the function.
18176
18106
  if ((0, typeUtils_1.isInstantiableMetaclass)(baseType)) {
18177
- return memberType;
18107
+ return functionType;
18178
18108
  }
18179
18109
  const baseObj = (0, types_1.isClassInstance)(baseType)
18180
18110
  ? baseType
18181
18111
  : types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType));
18182
- return partiallySpecializeFunctionForBoundClassOrObject(baseType, memberType, memberClass || types_1.ClassType.cloneAsInstantiable(baseObj), diag, recursionCount, firstParamType || baseObj,
18112
+ return partiallySpecializeFunctionForBoundClassOrObject(baseType, functionType, memberClass !== null && memberClass !== void 0 ? memberClass : types_1.ClassType.cloneAsInstantiable(baseObj), diag, recursionCount, selfType !== null && selfType !== void 0 ? selfType : baseObj,
18183
18113
  /* stripFirstParam */ (0, types_1.isClassInstance)(baseType));
18184
18114
  }
18185
- if (types_1.FunctionType.isClassMethod(memberType) ||
18186
- (treatConstructorAsClassMember && types_1.FunctionType.isConstructorMethod(memberType))) {
18115
+ if (types_1.FunctionType.isClassMethod(functionType) ||
18116
+ (treatConstructorAsClassMember && types_1.FunctionType.isConstructorMethod(functionType))) {
18187
18117
  const baseClass = (0, types_1.isInstantiableClass)(baseType) ? baseType : types_1.ClassType.cloneAsInstantiable(baseType);
18188
- // If the caller passed an object as the base type, we need to also
18189
- // convert the firstParamType to an instantiable.
18190
- const effectiveFirstParamType = firstParamType
18191
- ? (0, types_1.isInstantiableClass)(baseType)
18192
- ? firstParamType
18193
- : (0, typeUtils_1.convertToInstantiable)(firstParamType)
18194
- : baseClass;
18195
- return partiallySpecializeFunctionForBoundClassOrObject(types_1.TypeBase.isInstance(baseType) ? types_1.ClassType.cloneAsInstantiable(baseType) : baseType, memberType, memberClass || baseClass, diag, recursionCount, effectiveFirstParamType,
18118
+ const clsType = selfType ? (0, typeUtils_1.convertToInstantiable)(selfType) : undefined;
18119
+ return partiallySpecializeFunctionForBoundClassOrObject(baseClass, functionType, memberClass !== null && memberClass !== void 0 ? memberClass : baseClass, diag, recursionCount, clsType !== null && clsType !== void 0 ? clsType : baseClass,
18196
18120
  /* stripFirstParam */ true);
18197
18121
  }
18198
- if (types_1.FunctionType.isStaticMethod(memberType)) {
18122
+ if (types_1.FunctionType.isStaticMethod(functionType)) {
18199
18123
  const baseClass = (0, types_1.isInstantiableClass)(baseType) ? baseType : types_1.ClassType.cloneAsInstantiable(baseType);
18200
- return partiallySpecializeFunctionForBoundClassOrObject(types_1.TypeBase.isInstance(baseType) ? types_1.ClassType.cloneAsInstantiable(baseType) : baseType, memberType, memberClass || baseClass, diag, recursionCount,
18201
- /* effectiveFirstParamType */ undefined,
18124
+ return partiallySpecializeFunctionForBoundClassOrObject(baseClass, functionType, memberClass !== null && memberClass !== void 0 ? memberClass : baseClass, diag, recursionCount,
18125
+ /* firstParamType */ undefined,
18202
18126
  /* stripFirstParam */ false);
18203
18127
  }
18204
- }
18205
- else if ((0, types_1.isOverloadedFunction)(memberType)) {
18206
- const newOverloadType = types_1.OverloadedFunctionType.create([]);
18207
- // Don't bother binding the implementation.
18208
- types_1.OverloadedFunctionType.getOverloads(memberType).forEach((overload) => {
18209
- const boundMethod = bindFunctionToClassOrObject(baseType, overload, memberClass, treatConstructorAsClassMember, firstParamType,
18210
- /* diag */ undefined, recursionCount);
18211
- if (boundMethod) {
18212
- types_1.OverloadedFunctionType.addOverload(newOverloadType, boundMethod);
18213
- }
18214
- });
18215
- const newOverloads = types_1.OverloadedFunctionType.getOverloads(newOverloadType);
18216
- if (newOverloads.length === 0) {
18217
- // No overloads matched, so rebind with the diag
18218
- // to report the error(s) to the user.
18219
- if (diag) {
18220
- memberType.overloads.forEach((overload) => {
18221
- bindFunctionToClassOrObject(baseType, overload, memberClass, treatConstructorAsClassMember, firstParamType, diag, recursionCount);
18222
- });
18223
- }
18224
- return undefined;
18225
- }
18226
- if (newOverloads.length === 1) {
18227
- return newOverloads[0];
18228
- }
18229
- return newOverloadType;
18230
- }
18231
- return memberType;
18128
+ return functionType;
18129
+ });
18232
18130
  }
18233
18131
  // Specializes the specified function for the specified class,
18234
18132
  // optionally stripping the first first parameter (the "self" or "cls")
@@ -18333,6 +18231,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18333
18231
  }
18334
18232
  return true;
18335
18233
  }
18234
+ function isLegalImplicitTypeAliasType(type) {
18235
+ // We explicitly exclude "Unknown" and "...".
18236
+ if ((0, types_1.isUnknown)(type) || (0, typeUtils_1.isEllipsisType)(type)) {
18237
+ return false;
18238
+ }
18239
+ // Look at the subtypes within the union. If any of them are not
18240
+ // instantiable (other than "None" which is special-cased), it is
18241
+ // not a legal type alias type.
18242
+ let isLegal = true;
18243
+ (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
18244
+ if (!types_1.TypeBase.isInstantiable(subtype) && !(0, typeUtils_1.isNoneInstance)(subtype)) {
18245
+ isLegal = false;
18246
+ }
18247
+ });
18248
+ return isLegal;
18249
+ }
18336
18250
  function printObjectTypeForClass(type) {
18337
18251
  return TypePrinter.printObjectTypeForClass(type, evaluatorOptions.printTypeFlags, getFunctionEffectiveReturnType);
18338
18252
  }
@@ -18501,10 +18415,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18501
18415
  getBestOverloadForArguments,
18502
18416
  getBuiltInType,
18503
18417
  getTypeOfMember,
18504
- getTypeOfObjectMember,
18505
- getTypeOfClassMemberName,
18506
- getBoundMethod,
18507
- getTypeOfMagicMethodReturn,
18418
+ getTypeOfBoundMember,
18419
+ getBoundMagicMethod,
18420
+ getTypeOfMagicMethodCall,
18508
18421
  bindFunctionToClassOrObject,
18509
18422
  getCallSignatureInfo,
18510
18423
  getAbstractMethods,
@@ -18518,6 +18431,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18518
18431
  getTypedDictClassType,
18519
18432
  getTupleClassType,
18520
18433
  getObjectType,
18434
+ getNoneType,
18521
18435
  getBuiltInObject,
18522
18436
  getTypingType,
18523
18437
  assignTypeArguments,