@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.
- package/dist/analyzer/analyzerFileInfo.d.ts +1 -0
- package/dist/analyzer/analyzerFileInfo.js.map +1 -1
- package/dist/analyzer/checker.js +99 -105
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +12 -33
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/codeFlowUtils.js +4 -2
- package/dist/analyzer/codeFlowUtils.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +21 -23
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +4 -6
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +6 -3
- package/dist/analyzer/constructors.js +66 -41
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.js +13 -18
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/declarationUtils.js +1 -1
- package/dist/analyzer/declarationUtils.js.map +1 -1
- package/dist/analyzer/decorators.js +1 -1
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/enums.d.ts +2 -5
- package/dist/analyzer/enums.js +5 -3
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/functionTransform.js +1 -1
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +4 -2
- package/dist/analyzer/importResolver.js +30 -10
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/importStatementUtils.d.ts +1 -1
- package/dist/analyzer/importStatementUtils.js +33 -5
- package/dist/analyzer/importStatementUtils.js.map +1 -1
- package/dist/analyzer/namedTuples.js +3 -2
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.js +34 -31
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +28 -26
- package/dist/analyzer/packageTypeVerifier.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +1 -0
- package/dist/analyzer/parseTreeUtils.js +17 -2
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +6 -6
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +1 -1
- package/dist/analyzer/program.js +34 -21
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.js +25 -28
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +1 -1
- package/dist/analyzer/protocols.js +15 -19
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.js +12 -6
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +1 -0
- package/dist/analyzer/sourceFile.js +36 -2
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceFileInfoUtils.d.ts +1 -1
- package/dist/analyzer/sourceFileInfoUtils.js +9 -3
- package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
- package/dist/analyzer/tracePrinter.js +11 -13
- package/dist/analyzer/tracePrinter.js.map +1 -1
- package/dist/analyzer/typeDocStringUtils.js +3 -3
- package/dist/analyzer/typeDocStringUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.d.ts +3 -1
- package/dist/analyzer/typeEvaluator.js +1184 -1270
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +13 -26
- package/dist/analyzer/typeEvaluatorTypes.js +1 -36
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +37 -32
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +19 -18
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +17 -8
- package/dist/analyzer/typeUtils.js +149 -94
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.js +6 -7
- package/dist/analyzer/typeVarContext.js.map +1 -1
- package/dist/analyzer/typeWalker.d.ts +1 -2
- package/dist/analyzer/typeWalker.js +7 -13
- package/dist/analyzer/typeWalker.js.map +1 -1
- package/dist/analyzer/typedDicts.js +10 -10
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +11 -20
- package/dist/analyzer/types.js +45 -77
- package/dist/analyzer/types.js.map +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js +7 -9
- package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
- package/dist/common/commandLineOptions.d.ts +2 -1
- package/dist/common/commandLineOptions.js +1 -1
- package/dist/common/commandLineOptions.js.map +1 -1
- package/dist/common/configOptions.d.ts +3 -2
- package/dist/common/configOptions.js +40 -25
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/extensibility.d.ts +3 -0
- package/dist/common/pathUtils.d.ts +1 -1
- package/dist/common/pathUtils.js +11 -10
- package/dist/common/pathUtils.js.map +1 -1
- package/dist/common/realFileSystem.js +4 -6
- package/dist/common/realFileSystem.js.map +1 -1
- package/dist/common/serviceProviderExtensions.d.ts +2 -1
- package/dist/common/serviceProviderExtensions.js +1 -0
- package/dist/common/serviceProviderExtensions.js.map +1 -1
- package/dist/common/textEditTracker.js +2 -2
- package/dist/common/textEditTracker.js.map +1 -1
- package/dist/languageServerBase.d.ts +3 -3
- package/dist/languageServerBase.js +18 -15
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/analyzerServiceExecutor.js +1 -1
- package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.js +3 -3
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +2 -1
- package/dist/languageService/completionProvider.js +12 -10
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/completionProviderUtils.js +1 -1
- package/dist/languageService/definitionProvider.js +1 -1
- package/dist/languageService/documentSymbolCollector.js +1 -1
- package/dist/languageService/hoverProvider.js +1 -1
- package/dist/languageService/signatureHelpProvider.js +0 -14
- package/dist/languageService/signatureHelpProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +4 -4
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/localization/localize.d.ts +16 -0
- package/dist/localization/localize.js +6 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +4 -1
- package/dist/localization/package.nls.de.json +4 -1
- package/dist/localization/package.nls.en-us.json +7 -1
- package/dist/localization/package.nls.es.json +4 -1
- package/dist/localization/package.nls.fr.json +4 -1
- package/dist/localization/package.nls.it.json +4 -1
- package/dist/localization/package.nls.ja.json +4 -1
- package/dist/localization/package.nls.ko.json +4 -1
- package/dist/localization/package.nls.pl.json +4 -1
- package/dist/localization/package.nls.pt-br.json +4 -1
- package/dist/localization/package.nls.qps-ploc.json +3 -0
- package/dist/localization/package.nls.ru.json +4 -1
- package/dist/localization/package.nls.tr.json +4 -1
- package/dist/localization/package.nls.zh-cn.json +4 -1
- package/dist/localization/package.nls.zh-tw.json +4 -1
- package/dist/pyright.js +3 -6
- package/dist/pyright.js.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +10 -1
- package/dist/server.js.map +1 -1
- package/dist/tests/diagnosticOverrides.test.js +4 -2
- package/dist/tests/diagnosticOverrides.test.js.map +1 -1
- package/dist/tests/fourslash/{completions.importInterimFile.fourslash.js → completions.importInterimFile.fourslash.disabled.js} +2 -2
- package/dist/tests/fourslash/completions.importInterimFile.fourslash.disabled.js.map +1 -0
- package/dist/tests/fourslash/fourslash.d.ts +1 -1
- package/dist/tests/fourslash/signature.complicated.fourslash.js +6 -6
- package/dist/tests/fourslash/signature.complicated.fourslash.js.map +1 -1
- package/dist/tests/fourslash/signature.dunderNew.fourslash.js +1 -1
- package/dist/tests/fourslash/signature.dunderNew.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.d.ts +1 -1
- package/dist/tests/harness/fourslash/testState.js +4 -4
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/harness/vfs/filesystem.js +1 -1
- package/dist/tests/harness/vfs/filesystem.js.map +1 -1
- package/dist/tests/logger.test.js +0 -1
- package/dist/tests/logger.test.js.map +1 -1
- package/dist/tests/parseTreeUtils.test.js +15 -0
- package/dist/tests/parseTreeUtils.test.js.map +1 -1
- package/dist/tests/pathUtils.test.js +30 -1
- package/dist/tests/pathUtils.test.js.map +1 -1
- package/dist/tests/testUtils.js +2 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/tests/textEditUtil.test.js +25 -0
- package/dist/tests/textEditUtil.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +7 -3
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +5 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +10 -4
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +11 -7
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typePrinter.test.js +12 -16
- package/dist/tests/typePrinter.test.js.map +1 -1
- package/dist/tests/zipfs.test.js +2 -0
- package/dist/tests/zipfs.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/tests/fourslash/completions.importInterimFile.fourslash.js.map +0 -1
- /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
|
-
|
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
|
1083
|
-
case 3 /* None */: {
|
1088
|
+
case 3 /* Never */: {
|
1084
1089
|
return true;
|
1085
1090
|
}
|
1086
|
-
case
|
1091
|
+
case 8 /* Union */: {
|
1087
1092
|
return (0, types_1.findSubtype)(type, (subtype) => canBeFalsy(subtype, recursionCount)) !== undefined;
|
1088
1093
|
}
|
1089
|
-
case
|
1090
|
-
case
|
1091
|
-
case
|
1092
|
-
case
|
1094
|
+
case 4 /* Function */:
|
1095
|
+
case 5 /* OverloadedFunction */:
|
1096
|
+
case 7 /* Module */:
|
1097
|
+
case 9 /* TypeVar */: {
|
1093
1098
|
return false;
|
1094
1099
|
}
|
1095
|
-
case
|
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
|
-
|
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
|
1149
|
-
case
|
1150
|
-
case
|
1151
|
-
case
|
1152
|
-
case
|
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
|
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
|
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
|
1267
|
-
// it to the object. If
|
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
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
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
|
-
|
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',
|
1312
|
-
// uses this
|
1313
|
-
// in the common case where the metaclass is 'type' since we know
|
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,
|
1320
|
-
const
|
1321
|
-
/*
|
1322
|
-
if (
|
1323
|
-
|
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
|
-
|
1327
|
-
if (!
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
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
|
-
|
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
|
1356
|
-
const
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
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
|
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
|
1444
|
-
case
|
1468
|
+
case 4 /* Function */:
|
1469
|
+
case 5 /* OverloadedFunction */: {
|
1445
1470
|
addFunctionToSignature(subtype);
|
1446
1471
|
break;
|
1447
1472
|
}
|
1448
|
-
case
|
1473
|
+
case 6 /* Class */: {
|
1449
1474
|
if (types_1.TypeBase.isInstantiable(subtype)) {
|
1450
|
-
let
|
1475
|
+
let constructorType;
|
1451
1476
|
// Try to get the `__init__` method first because it typically has more
|
1452
1477
|
// type information than `__new__`.
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
const
|
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 (!
|
1463
|
-
const
|
1464
|
-
/*
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
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 (
|
1476
|
-
addFunctionToSignature(
|
1502
|
+
if (constructorType) {
|
1503
|
+
addFunctionToSignature(constructorType);
|
1477
1504
|
}
|
1478
1505
|
}
|
1479
1506
|
else {
|
1480
|
-
const methodType =
|
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,
|
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,
|
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,
|
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
|
1575
|
-
if (
|
1576
|
-
const
|
1577
|
-
if ((0, types_1.
|
1578
|
-
|
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
|
1606
|
-
|
1607
|
-
|
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 =
|
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 (
|
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,
|
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
|
-
|
1691
|
-
if (types_1.TypeBase.isInstance(subtype)
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
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 =
|
1755
|
+
const getItemReturnType = getTypeOfMagicMethodCall(subtype, '__getitem__', [
|
1710
1756
|
{
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
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 =
|
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 (
|
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 (
|
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,
|
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
|
-
|
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 (
|
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,
|
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 */ :
|
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,
|
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,
|
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
|
-
//
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
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
|
-
|
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 ===
|
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
|
-
},
|
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
|
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
|
3494
|
+
case 3 /* Never */: {
|
3507
3495
|
type = baseType;
|
3508
3496
|
break;
|
3509
3497
|
}
|
3510
|
-
case
|
3498
|
+
case 0 /* Unbound */: {
|
3499
|
+
break;
|
3500
|
+
}
|
3501
|
+
case 9 /* TypeVar */: {
|
3511
3502
|
if (baseType.details.isParamSpec) {
|
3512
|
-
|
3513
|
-
|
3514
|
-
|
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
|
-
|
3523
|
-
|
3524
|
-
|
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
|
-
|
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
|
-
|
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(
|
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
|
-
|
3533
|
+
type = types_1.UnknownType.create(isIncomplete);
|
3534
|
+
break;
|
3541
3535
|
}
|
3542
3536
|
if (baseType.details.recursiveTypeAliasName) {
|
3543
|
-
|
3537
|
+
type = types_1.UnknownType.create(/* isIncomplete */ true);
|
3538
|
+
isIncomplete = true;
|
3539
|
+
break;
|
3544
3540
|
}
|
3545
|
-
if (
|
3546
|
-
|
3547
|
-
type: makeTopLevelTypeVarsConcrete(baseType),
|
3548
|
-
bindToType: baseType,
|
3549
|
-
isIncomplete,
|
3550
|
-
}, usage, 0 /* None */);
|
3541
|
+
if (baseType.details.isVariadic) {
|
3542
|
+
break;
|
3551
3543
|
}
|
3552
|
-
|
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
|
3555
|
-
|
3556
|
-
|
3557
|
-
|
3558
|
-
|
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
|
-
|
3569
|
-
|
3570
|
-
|
3571
|
-
|
3572
|
-
|
3573
|
-
|
3574
|
-
|
3575
|
-
|
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
|
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(
|
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(
|
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(
|
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
|
3635
|
+
case 8 /* Union */: {
|
3660
3636
|
type = (0, typeUtils_1.mapSubtypes)(baseType, (subtype) => {
|
3661
|
-
if ((0, types_1.
|
3662
|
-
|
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
|
-
|
3671
|
-
|
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
|
-
|
3683
|
-
|
3684
|
-
|
3685
|
-
|
3686
|
-
|
3687
|
-
|
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
|
3699
|
-
case
|
3700
|
-
if (memberName === '
|
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
|
-
|
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
|
-
|
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, (
|
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,
|
3795
|
-
var _a, _b;
|
3796
|
-
|
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,
|
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,
|
3732
|
+
memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, flags);
|
3821
3733
|
}
|
3822
|
-
if (memberInfo) {
|
3823
|
-
|
3824
|
-
|
3825
|
-
|
3826
|
-
|
3827
|
-
|
3828
|
-
|
3829
|
-
|
3830
|
-
|
3831
|
-
|
3832
|
-
|
3833
|
-
|
3834
|
-
|
3835
|
-
|
3836
|
-
|
3837
|
-
|
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
|
-
|
3944
|
-
|
3945
|
-
|
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
|
-
|
3956
|
-
|
3957
|
-
|
3958
|
-
|
3959
|
-
|
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
|
-
|
3974
|
-
|
3975
|
-
|
3976
|
-
|
3977
|
-
|
3978
|
-
|
3979
|
-
|
3980
|
-
|
3981
|
-
|
3982
|
-
|
3983
|
-
|
3984
|
-
|
3985
|
-
|
3986
|
-
|
3987
|
-
|
3988
|
-
|
3989
|
-
|
3990
|
-
|
3991
|
-
|
3992
|
-
|
3993
|
-
|
3994
|
-
|
3995
|
-
|
3996
|
-
|
3997
|
-
|
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 (
|
4045
|
-
|
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
|
-
|
4193
|
-
|
4194
|
-
|
4195
|
-
|
4196
|
-
|
4197
|
-
|
4198
|
-
|
4199
|
-
|
4200
|
-
|
4201
|
-
|
4202
|
-
|
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
|
-
|
4215
|
-
|
4216
|
-
|
4217
|
-
|
4218
|
-
|
4219
|
-
|
4220
|
-
|
4221
|
-
|
4222
|
-
|
4223
|
-
|
4224
|
-
|
4225
|
-
|
4226
|
-
|
4227
|
-
|
4228
|
-
|
4229
|
-
|
4230
|
-
|
4231
|
-
|
4232
|
-
|
4233
|
-
|
4234
|
-
|
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
|
-
|
4238
|
-
|
4239
|
-
|
4240
|
-
|
4241
|
-
|
4242
|
-
|
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
|
-
|
4246
|
-
|
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
|
-
|
4258
|
-
|
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
|
-
|
4267
|
-
|
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
|
-
|
4272
|
-
|
4273
|
-
|
4274
|
-
|
4275
|
-
|
4276
|
-
|
4277
|
-
|
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
|
-
|
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 (!
|
4300
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
4374
|
-
|
4375
|
-
|
4376
|
-
|
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
|
-
|
4391
|
-
|
4392
|
-
|
4393
|
-
|
4394
|
-
|
4395
|
-
|
4396
|
-
|
4397
|
-
|
4398
|
-
|
4399
|
-
|
4400
|
-
|
4401
|
-
|
4402
|
-
|
4403
|
-
|
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
|
-
|
4407
|
-
|
4408
|
-
|
4409
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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 ===
|
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 ===
|
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
|
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 = (
|
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 = (
|
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: !!((
|
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 =
|
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: (
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
5931
|
-
? types_1.TypeBase.cloneForCondition((0, typeUtils_1.synthesizeTypeVarForSelfCls)(bindToType,
|
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
|
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
|
6309
|
+
case 4 /* Function */: {
|
6454
6310
|
return validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6455
6311
|
}
|
6456
|
-
case
|
6312
|
+
case 5 /* OverloadedFunction */: {
|
6457
6313
|
return validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6458
6314
|
}
|
6459
|
-
case
|
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
|
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
|
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,
|
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 =
|
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
|
6760
|
-
const
|
6609
|
+
var _a;
|
6610
|
+
const callMethodResult = getTypeOfBoundMember(errorNode, expandedCallType, '__call__',
|
6761
6611
|
/* usage */ undefined,
|
6762
|
-
/* diag */ undefined,
|
6763
|
-
|
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:
|
6770
|
-
let returnType = (
|
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
|
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
|
6963
|
-
|
6964
|
-
|
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 (
|
7025
|
-
if ((0, types_1.isTypeVar)(argTypeResult.type) &&
|
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
|
-
|
7074
|
-
|
7075
|
-
|
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: (
|
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: (
|
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: (
|
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: (
|
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
|
-
//
|
8166
|
-
|
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__',
|
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 =
|
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
|
-
|
8962
|
-
return undefined;
|
8963
|
-
}
|
8964
|
-
return { type };
|
8848
|
+
return { type: type !== null && type !== void 0 ? type : types_1.UnknownType.create() };
|
8965
8849
|
}
|
8966
|
-
function
|
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.
|
8974
|
-
magicMethodType = (
|
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 =
|
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
|
-
|
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
|
-
|
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,
|
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,
|
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 =
|
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
|
-
|
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
|
-
/*
|
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.
|
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.
|
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,
|
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,
|
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 */,
|
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
|
-
|
11893
|
-
|
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
|
-
|
11908
|
-
|
11909
|
-
|
11910
|
-
|
11911
|
-
|
11912
|
-
|
11913
|
-
|
11914
|
-
|
11915
|
-
|
11916
|
-
|
11917
|
-
|
11918
|
-
|
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
|
-
|
11922
|
-
|
11923
|
-
|
11924
|
-
|
11925
|
-
|
11926
|
-
|
11927
|
-
|
11928
|
-
|
11929
|
-
|
11930
|
-
|
11931
|
-
|
11932
|
-
|
11933
|
-
|
11934
|
-
|
11935
|
-
|
11936
|
-
|
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
|
-
|
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
|
-
|
11953
|
-
|
11954
|
-
|
11955
|
-
|
11956
|
-
|
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 =
|
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,
|
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,
|
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(
|
12601
|
+
inferredReturnTypes.push(getNoneType());
|
12684
12602
|
}
|
12685
12603
|
}
|
12686
12604
|
});
|
12687
12605
|
}
|
12688
12606
|
if (!functionNeverReturns && implicitlyReturnsNone) {
|
12689
|
-
inferredReturnTypes.push(
|
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(
|
12649
|
+
inferredYieldTypes.push(getNoneType());
|
12732
12650
|
}
|
12733
12651
|
}
|
12734
12652
|
}
|
12735
12653
|
});
|
12736
12654
|
}
|
12737
12655
|
if (inferredYieldTypes.length === 0) {
|
12738
|
-
inferredYieldTypes.push(
|
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) ?
|
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,
|
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 =
|
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 (
|
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 =
|
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,
|
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,
|
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 =
|
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,
|
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
|
-
|
14832
|
-
|
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 (
|
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 =
|
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
|
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
|
-
|
15914
|
-
|
15915
|
-
/*
|
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
|
-
|
15926
|
-
|
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,
|
16278
|
-
if ((0,
|
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,
|
16286
|
-
if ((0,
|
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 "
|
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 =
|
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,
|
16564
|
-
if (
|
16565
|
-
return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType),
|
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,
|
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,
|
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 =
|
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) =>
|
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 =
|
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 =
|
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 =
|
17401
|
-
const effectiveSrcType =
|
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
|
-
|
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
|
-
|
17716
|
-
|
17717
|
-
|
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
|
18164
|
-
// class method even if it's not marked as such. That's
|
18165
|
-
// special-case the __new__ magic method when it's invoked as
|
18166
|
-
// constructor (as opposed to by name).
|
18167
|
-
function bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMember = false,
|
18168
|
-
|
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(
|
18102
|
+
return types_1.FunctionType.clone(functionType, /* stripFirstParam */ true);
|
18173
18103
|
}
|
18174
|
-
if (types_1.FunctionType.isInstanceMethod(
|
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
|
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,
|
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(
|
18186
|
-
(treatConstructorAsClassMember && types_1.FunctionType.isConstructorMethod(
|
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
|
-
|
18189
|
-
|
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(
|
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(
|
18201
|
-
/*
|
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
|
-
|
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
|
-
|
18505
|
-
|
18506
|
-
|
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,
|