@zzzen/pyright-internal 1.2.0-dev.20261004 → 1.2.0-dev.20261018
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/binder.js +8 -0
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +0 -1
- package/dist/analyzer/checker.js +21 -42
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +75 -28
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +3 -2
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/operations.d.ts +2 -0
- package/dist/analyzer/operations.js +2 -1
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/overloadResultAdmission.js +115 -3
- package/dist/analyzer/overloadResultAdmission.js.map +1 -1
- package/dist/analyzer/overloadResultController.js +36 -10
- package/dist/analyzer/overloadResultController.js.map +1 -1
- package/dist/analyzer/overloadResultSelector.js +32 -12
- package/dist/analyzer/overloadResultSelector.js.map +1 -1
- package/dist/analyzer/parameterUtils.js +2 -1
- package/dist/analyzer/parameterUtils.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +1 -0
- package/dist/analyzer/parseTreeUtils.js +13 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +105 -35
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +3 -0
- package/dist/analyzer/program.js +34 -9
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.d.ts +2 -2
- package/dist/analyzer/properties.js +2 -2
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +3 -1
- package/dist/analyzer/protocols.js +24 -2
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.js +6 -2
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceEnumerator.d.ts +3 -1
- package/dist/analyzer/sourceEnumerator.js +30 -11
- package/dist/analyzer/sourceEnumerator.js.map +1 -1
- package/dist/analyzer/sourceMapper.d.ts +1 -0
- package/dist/analyzer/sourceMapper.js +10 -4
- package/dist/analyzer/sourceMapper.js.map +1 -1
- package/dist/analyzer/tuples.js +17 -6
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +419 -67
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
- package/dist/analyzer/typeEvaluatorTypes.js +4 -0
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +5 -1
- package/dist/analyzer/typeGuards.js +324 -99
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +32 -6
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeStubRenderer.d.ts +6 -1
- package/dist/analyzer/typeStubRenderer.js +19 -12
- package/dist/analyzer/typeStubRenderer.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +1 -0
- package/dist/analyzer/typeUtils.js +15 -1
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +2 -1
- package/dist/analyzer/typedDicts.js +49 -10
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +2 -1
- package/dist/analyzer/types.js +9 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +9 -0
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/windowsProcessTree.json +252 -33
- package/dist/tests/cacheManager.test.js +19 -15
- package/dist/tests/cacheManager.test.js.map +1 -1
- package/dist/tests/checker.test.js +50 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/config.test.js +126 -0
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/constraintSolver.test.d.ts +1 -0
- package/dist/tests/constraintSolver.test.js +39 -0
- package/dist/tests/constraintSolver.test.js.map +1 -0
- package/dist/tests/fourslash/hover.typedDict.get.fourslash.js +11 -0
- package/dist/tests/fourslash/hover.typedDict.get.fourslash.js.map +1 -1
- package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js +16 -0
- package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js.map +1 -0
- package/dist/tests/mypyPrimerAnalysis.test.js +67 -11
- package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
- package/dist/tests/overloadResultController.test.js +379 -1
- package/dist/tests/overloadResultController.test.js.map +1 -1
- package/dist/tests/signatureHelp.test.js +34 -0
- package/dist/tests/signatureHelp.test.js.map +1 -1
- package/dist/tests/sourceEnumeratorSymlink.test.js +98 -13
- package/dist/tests/sourceEnumeratorSymlink.test.js.map +1 -1
- package/dist/tests/sourceMapperUtils.test.js +143 -0
- package/dist/tests/sourceMapperUtils.test.js.map +1 -1
- package/dist/tests/typeEquality.test.js +85 -2
- package/dist/tests/typeEquality.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +47 -3
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +23 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +1 -1
- package/dist/tests/typeEvaluator6.test.js +83 -1
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +32 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +15 -1
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/package.json +3 -3
|
@@ -80,6 +80,7 @@ const namedTuples_1 = require("./namedTuples");
|
|
|
80
80
|
const operations_1 = require("./operations");
|
|
81
81
|
const parameterUtils_1 = require("./parameterUtils");
|
|
82
82
|
const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
|
|
83
|
+
const parseTreeWalker_1 = require("./parseTreeWalker");
|
|
83
84
|
const patternMatching_1 = require("./patternMatching");
|
|
84
85
|
const properties_1 = require("./properties");
|
|
85
86
|
const protocols_1 = require("./protocols");
|
|
@@ -203,8 +204,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
203
204
|
let functionRecursionMap = new Map();
|
|
204
205
|
let codeFlowAnalyzerCache = new Map();
|
|
205
206
|
let typeCache = new Map();
|
|
207
|
+
let contextualLambdaTypeCache;
|
|
206
208
|
let typeFormTypeCache = new Map();
|
|
207
209
|
let effectiveTypeCache = new Map();
|
|
210
|
+
let exceptionTargetSymbolCache = new Map();
|
|
208
211
|
let expectedTypeCache = new Map();
|
|
209
212
|
let asymmetricAccessorAssignmentCache = new Set();
|
|
210
213
|
let deferredClassCompletions = [];
|
|
@@ -272,6 +275,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
272
275
|
typeCache = new Map();
|
|
273
276
|
typeFormTypeCache = new Map();
|
|
274
277
|
effectiveTypeCache = new Map();
|
|
278
|
+
exceptionTargetSymbolCache = new Map();
|
|
275
279
|
expectedTypeCache = new Map();
|
|
276
280
|
asymmetricAccessorAssignmentCache = new Set();
|
|
277
281
|
}
|
|
@@ -397,6 +401,55 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
397
401
|
function setTypeResultForNode(node, typeResult, flags = 0 /* EvalFlags.None */) {
|
|
398
402
|
writeTypeCache(node, typeResult, flags);
|
|
399
403
|
}
|
|
404
|
+
function captureContextualLambdaTypes(node, typeResult) {
|
|
405
|
+
const cache = contextualLambdaTypeCache;
|
|
406
|
+
if (!cache || !cache.lambdaNodes.some((root) => ParseTreeUtils.isNodeContainedWithin(node, root))) {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
captureLambdaTypeCacheEntries(node, cache, typeResult);
|
|
410
|
+
}
|
|
411
|
+
function captureLambdaTypeCacheEntries(node, cache, typeResult) {
|
|
412
|
+
checkForCancellation();
|
|
413
|
+
const entry = typeResult ? { typeResult, flags: 0 /* EvalFlags.None */, incompleteGenCount } : readTypeCacheEntry(node);
|
|
414
|
+
if (entry && !entry.typeResult.isIncomplete) {
|
|
415
|
+
captureLambdaTypeCacheEntry(node, cache, entry);
|
|
416
|
+
}
|
|
417
|
+
if (typeResult) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
for (const child of (0, parseTreeWalker_1.getChildNodes)(node)) {
|
|
421
|
+
// Nested lambdas capture their own contextual types before any
|
|
422
|
+
// non-contextual fallback can replace them.
|
|
423
|
+
if (child && child.nodeType !== 33 /* ParseNodeType.Lambda */) {
|
|
424
|
+
captureLambdaTypeCacheEntries(child, cache);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function captureLambdaTypeCacheEntry(node, cache, entry) {
|
|
429
|
+
const nodeEntries = cache.entries.get(node) ?? new Map();
|
|
430
|
+
// Generic inference can revisit a lambda within the same callable branch.
|
|
431
|
+
nodeEntries.set(cache.branchIndex, entry);
|
|
432
|
+
cache.entries.set(node, nodeEntries);
|
|
433
|
+
}
|
|
434
|
+
function combineContextualLambdaTypes(cache) {
|
|
435
|
+
for (const [node, branchEntries] of cache.entries) {
|
|
436
|
+
checkForCancellation();
|
|
437
|
+
const nodeEntries = Array.from(branchEntries.values());
|
|
438
|
+
const lastEntry = nodeEntries[nodeEntries.length - 1];
|
|
439
|
+
writeTypeCache(node, {
|
|
440
|
+
...lastEntry.typeResult,
|
|
441
|
+
type: (0, types_1.combineTypes)(nodeEntries.map((entry) => entry.typeResult.type)),
|
|
442
|
+
typeErrors: nodeEntries.some((entry) => entry.typeResult.typeErrors),
|
|
443
|
+
}, readTypeCacheEntry(node)?.flags ?? lastEntry.flags);
|
|
444
|
+
const parentCache = contextualLambdaTypeCache;
|
|
445
|
+
const combinedEntry = readTypeCacheEntry(node);
|
|
446
|
+
if (parentCache &&
|
|
447
|
+
combinedEntry &&
|
|
448
|
+
parentCache.lambdaNodes.some((root) => ParseTreeUtils.isNodeContainedWithin(node, root))) {
|
|
449
|
+
captureLambdaTypeCacheEntry(node, parentCache, combinedEntry);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
400
453
|
function getMaxCodeComplexity() {
|
|
401
454
|
return maxCodeComplexity;
|
|
402
455
|
}
|
|
@@ -4945,8 +4998,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
4945
4998
|
}
|
|
4946
4999
|
// Determine if we're calling __set__ on an asymmetric descriptor or property.
|
|
4947
5000
|
let isAsymmetricAccessor = false;
|
|
4948
|
-
if (usage.method === 'set'
|
|
4949
|
-
if (isAsymmetricDescriptorClass(
|
|
5001
|
+
if (usage.method === 'set') {
|
|
5002
|
+
if (isAsymmetricDescriptorClass(concreteMemberType)) {
|
|
4950
5003
|
isAsymmetricAccessor = true;
|
|
4951
5004
|
}
|
|
4952
5005
|
}
|
|
@@ -5136,14 +5189,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5136
5189
|
return classType.priv.isAsymmetricDescriptor;
|
|
5137
5190
|
}
|
|
5138
5191
|
let isAsymmetric = false;
|
|
5139
|
-
|
|
5140
|
-
|
|
5192
|
+
// Accessors can be defined at different levels of the descriptor's MRO.
|
|
5193
|
+
// Ignore instance members so an instance attribute that happens to share
|
|
5194
|
+
// a dunder name doesn't shadow the descriptor protocol during this check.
|
|
5195
|
+
const accessorFlags = 16 /* MemberAccessFlags.SkipInstanceMembers */ | 512 /* MemberAccessFlags.SkipAttributeAccessOverride */;
|
|
5196
|
+
const getterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__get__', accessorFlags);
|
|
5197
|
+
const setterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__set__', accessorFlags);
|
|
5141
5198
|
if (!getterSymbolResult || !setterSymbolResult) {
|
|
5142
5199
|
isAsymmetric = false;
|
|
5143
5200
|
}
|
|
5144
5201
|
else {
|
|
5145
5202
|
let getterType = getTypeOfMember(getterSymbolResult);
|
|
5146
|
-
|
|
5203
|
+
let setterType = getTypeOfMember(setterSymbolResult);
|
|
5204
|
+
// The getter and setter can be declared on different classes. Specialize
|
|
5205
|
+
// both against the concrete descriptor class so Self and inherited type
|
|
5206
|
+
// variables are compared in the same context.
|
|
5207
|
+
if (getterSymbolResult.classType && (0, types_1.isInstantiableClass)(getterSymbolResult.classType)) {
|
|
5208
|
+
getterType = (0, typeUtils_1.partiallySpecializeType)(getterType, getterSymbolResult.classType, getTypeClassType(), classType);
|
|
5209
|
+
}
|
|
5210
|
+
if (setterSymbolResult.classType && (0, types_1.isInstantiableClass)(setterSymbolResult.classType)) {
|
|
5211
|
+
setterType = (0, typeUtils_1.partiallySpecializeType)(setterType, setterSymbolResult.classType, getTypeClassType(), classType);
|
|
5212
|
+
}
|
|
5147
5213
|
// If this is an overload, find the appropriate overload.
|
|
5148
5214
|
if ((0, types_1.isOverloaded)(getterType)) {
|
|
5149
5215
|
const getOverloads = types_1.OverloadedType.getOverloads(getterType).filter((overload) => {
|
|
@@ -6085,12 +6151,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6085
6151
|
}
|
|
6086
6152
|
}
|
|
6087
6153
|
}
|
|
6088
|
-
else if (
|
|
6154
|
+
else if (usage.method === 'get' &&
|
|
6155
|
+
index0Expr.nodeType === 46 /* ParseNodeType.Slice */ &&
|
|
6156
|
+
(0, types_1.isClassInstance)(valueType) &&
|
|
6157
|
+
types_1.ClassType.isBuiltIn(valueType, 'slice')) {
|
|
6089
6158
|
const tupleType = (0, typeUtils_1.getSpecializedTupleType)(baseType);
|
|
6090
|
-
if (tupleType
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6159
|
+
if (tupleType) {
|
|
6160
|
+
// Skip this if a subclass overrides the tuple's __getitem__ method.
|
|
6161
|
+
const getItemMember = (0, typeUtils_1.lookUpObjectMember)(baseType, '__getitem__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
|
|
6162
|
+
const isTupleGetItem = !getItemMember ||
|
|
6163
|
+
((0, types_1.isInstantiableClass)(getItemMember.classType) &&
|
|
6164
|
+
types_1.ClassType.isBuiltIn(getItemMember.classType, 'tuple'));
|
|
6165
|
+
if (isTupleGetItem) {
|
|
6166
|
+
const slicedTupleType = (0, tuples_1.getSlicedTupleType)(evaluatorInterface, tupleType, index0Expr);
|
|
6167
|
+
if (slicedTupleType) {
|
|
6168
|
+
return { type: slicedTupleType };
|
|
6169
|
+
}
|
|
6094
6170
|
}
|
|
6095
6171
|
}
|
|
6096
6172
|
}
|
|
@@ -7203,7 +7279,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7203
7279
|
// there will be only one argument list in expandedArgTypes, and all entries
|
|
7204
7280
|
// (one for each argument) will be undefined. On subsequent calls, this
|
|
7205
7281
|
// list will grow to include union expansions.
|
|
7206
|
-
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
7282
|
+
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext, skipFinalValidation = false) {
|
|
7207
7283
|
const returnTypes = [];
|
|
7208
7284
|
const specializedInitSelfTypes = [];
|
|
7209
7285
|
let matchedOverloads = [];
|
|
@@ -7246,17 +7322,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7246
7322
|
if (!callResult.argumentErrors && callResult.returnType) {
|
|
7247
7323
|
if (evaluatorOptions.experimentalOverloadResult &&
|
|
7248
7324
|
!callResult.isTypeIncomplete &&
|
|
7249
|
-
!overload.priv.boundToType &&
|
|
7250
|
-
!overload.shared.methodClass &&
|
|
7251
|
-
!overload.shared.declaration?.isMethod &&
|
|
7252
7325
|
errorNode.nodeType === 9 /* ParseNodeType.Call */ &&
|
|
7253
|
-
|
|
7254
|
-
errorNode.parent?.nodeType === 3 /* ParseNodeType.Assignment */ &&
|
|
7255
|
-
errorNode.parent.d.rightExpr === errorNode &&
|
|
7326
|
+
(0, overloadResultSelector_1.isAutomaticOverloadSeedSyntax)(errorNode) &&
|
|
7256
7327
|
expandedArgTypes.length === 1 &&
|
|
7257
|
-
!hasArgTypeOverride
|
|
7258
|
-
|
|
7259
|
-
evaluatorOptions.experimentalOverloadResult.considerActivation(errorNode,
|
|
7328
|
+
!hasArgTypeOverride) {
|
|
7329
|
+
const receiver = overload.priv.boundToType;
|
|
7330
|
+
evaluatorOptions.experimentalOverloadResult.considerActivation(errorNode, receiver && (0, types_1.isClassInstance)(receiver)
|
|
7331
|
+
? [{ argType: receiver }, ...(callResult.argResults ?? [])]
|
|
7332
|
+
: callResult.argResults ?? []);
|
|
7260
7333
|
}
|
|
7261
7334
|
overloadsUsedForCall.push(overload);
|
|
7262
7335
|
matchedOverload = overload;
|
|
@@ -7375,6 +7448,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7375
7448
|
if (constraints && isDefinitiveMatchFound) {
|
|
7376
7449
|
constraints.copyFromClone(matchedOverloads[matchedOverloads.length - 1].constraints);
|
|
7377
7450
|
}
|
|
7451
|
+
// A speculative refinement does not need to populate the type cache;
|
|
7452
|
+
// the original call has already performed the normal final validation.
|
|
7453
|
+
if (skipFinalValidation) {
|
|
7454
|
+
return {
|
|
7455
|
+
argumentErrors: false,
|
|
7456
|
+
returnType: (0, types_1.combineTypes)(returnTypes),
|
|
7457
|
+
isTypeIncomplete,
|
|
7458
|
+
overloadsUsedForCall,
|
|
7459
|
+
};
|
|
7460
|
+
}
|
|
7378
7461
|
// And run through the first expanded argument list one more time to
|
|
7379
7462
|
// populate the type cache, without applying a different branch's constraints.
|
|
7380
7463
|
const finalConstraints = expandedArgTypes.length > 1
|
|
@@ -7503,10 +7586,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7503
7586
|
name: arg.d.name,
|
|
7504
7587
|
}));
|
|
7505
7588
|
const sources = node.d.args.map((arg) => getTypeOfExpression(arg.d.valueExpr));
|
|
7506
|
-
|
|
7589
|
+
const receiver = node.d.leftExpr.nodeType === 35 /* ParseNodeType.MemberAccess */
|
|
7590
|
+
? getTypeOfExpression(node.d.leftExpr.d.leftExpr)
|
|
7591
|
+
: undefined;
|
|
7592
|
+
if ([...sources, ...(receiver ? [receiver] : [])].some((s) => s.isIncomplete || s.typeErrors || (0, types_1.isAny)(s.type) || !(0, overloadResultSelector_1.isFixedOverloadArgumentShape)(s.type, budget))) {
|
|
7507
7593
|
return decline('unsupported-argument-shape');
|
|
7508
7594
|
}
|
|
7509
|
-
if (!sources.some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
|
|
7595
|
+
if (![...sources, ...(receiver ? [receiver] : [])].some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
|
|
7510
7596
|
return decline('no-invariant-any');
|
|
7511
7597
|
}
|
|
7512
7598
|
const returns = [];
|
|
@@ -7516,10 +7602,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7516
7602
|
const declaration = overload.shared.declaration;
|
|
7517
7603
|
const declaredReturnType = overload.shared.declaredReturnType;
|
|
7518
7604
|
const returnType = types_1.FunctionType.getEffectiveReturnType(overload);
|
|
7605
|
+
const receiverParam = overload.priv.strippedFirstParamType;
|
|
7606
|
+
const supportedBinding = receiver
|
|
7607
|
+
? declaration?.isMethod &&
|
|
7608
|
+
types_1.FunctionType.isInstanceMethod(overload) &&
|
|
7609
|
+
overload.priv.boundToType &&
|
|
7610
|
+
(0, types_1.isClassInstance)(overload.priv.boundToType) &&
|
|
7611
|
+
receiverParam &&
|
|
7612
|
+
(0, types_1.isClassInstance)(receiverParam) &&
|
|
7613
|
+
(0, types_1.isClassInstance)(receiver.type) &&
|
|
7614
|
+
types_1.ClassType.isSameGenericClass(receiver.type, receiverParam) &&
|
|
7615
|
+
overload.shared.methodClass &&
|
|
7616
|
+
types_1.ClassType.isSameGenericClass(receiver.type, types_1.ClassType.cloneAsInstance(overload.shared.methodClass)) &&
|
|
7617
|
+
(0, overloadResultSelector_1.isFixedOverloadArgumentShape)(receiverParam, budget)
|
|
7618
|
+
: !declaration?.isMethod && !overload.shared.methodClass && !overload.priv.boundToType;
|
|
7519
7619
|
if (!declaration ||
|
|
7520
|
-
|
|
7521
|
-
overload.shared.methodClass ||
|
|
7522
|
-
overload.priv.boundToType ||
|
|
7620
|
+
!supportedBinding ||
|
|
7523
7621
|
overload.shared.typeParams.length ||
|
|
7524
7622
|
!declaredReturnType ||
|
|
7525
7623
|
!returnType ||
|
|
@@ -7561,6 +7659,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7561
7659
|
continue;
|
|
7562
7660
|
}
|
|
7563
7661
|
const proof = mapping.argParams.map((p, i) => (0, overloadResultSelector_1.getFixedOverloadCoverage)(sources[i].type, p.paramType, budget));
|
|
7662
|
+
if (receiver && receiverParam) {
|
|
7663
|
+
proof.unshift((0, overloadResultSelector_1.getFixedOverloadCoverage)(receiver.type, receiverParam, budget));
|
|
7664
|
+
}
|
|
7564
7665
|
const covered = proof.includes('unsupported')
|
|
7565
7666
|
? 'unsupported'
|
|
7566
7667
|
: proof.includes('not-covered')
|
|
@@ -7585,11 +7686,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7585
7686
|
: decline('equivalent-or-single-return');
|
|
7586
7687
|
});
|
|
7587
7688
|
}
|
|
7588
|
-
function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
7689
|
+
function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext, candidateOverloads) {
|
|
7589
7690
|
const filteredMatchResults = [];
|
|
7590
7691
|
let contextFreeArgTypes;
|
|
7591
7692
|
let isTypeIncomplete = !!typeResult.isIncomplete;
|
|
7592
7693
|
const type = typeResult.type;
|
|
7694
|
+
const overloads = candidateOverloads ?? types_1.OverloadedType.getOverloads(type);
|
|
7593
7695
|
const speculativeNode = getSpeculativeNodeForCall(errorNode);
|
|
7594
7696
|
// Start by evaluating the types of the arguments without any expected
|
|
7595
7697
|
// type. Also, filter the list of overloads based on the number of
|
|
@@ -7598,7 +7700,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7598
7700
|
// cache or record any diagnostics at this stage.
|
|
7599
7701
|
useSpeculativeMode(speculativeNode, () => {
|
|
7600
7702
|
let overloadIndex = 0;
|
|
7601
|
-
|
|
7703
|
+
overloads.forEach((overload) => {
|
|
7602
7704
|
// Consider only the functions that have the @overload decorator,
|
|
7603
7705
|
// not the final function that omits the overload. This is the
|
|
7604
7706
|
// intended behavior according to PEP 484.
|
|
@@ -7615,7 +7717,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7615
7717
|
// Skip the error message if we're in speculative mode because it's very
|
|
7616
7718
|
// expensive, and we're going to suppress the diagnostic anyway.
|
|
7617
7719
|
if (!canSkipDiagnosticForNode(errorNode)) {
|
|
7618
|
-
const overloads = types_1.OverloadedType.getOverloads(type);
|
|
7619
7720
|
const functionName = overloads.length > 0 && overloads[0].shared.name
|
|
7620
7721
|
? overloads[0].shared.name
|
|
7621
7722
|
: '<anonymous function>';
|
|
@@ -7670,7 +7771,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7670
7771
|
}
|
|
7671
7772
|
let expandedArgTypes = [argList.map((arg) => undefined)];
|
|
7672
7773
|
while (true) {
|
|
7673
|
-
const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext
|
|
7774
|
+
const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext,
|
|
7775
|
+
/* skipFinalValidation */ candidateOverloads !== undefined);
|
|
7674
7776
|
if (callResult.isTypeIncomplete) {
|
|
7675
7777
|
isTypeIncomplete = true;
|
|
7676
7778
|
}
|
|
@@ -7805,24 +7907,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7805
7907
|
}), exprNode);
|
|
7806
7908
|
return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
|
|
7807
7909
|
}
|
|
7808
|
-
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7910
|
+
const concreteCallType = makeTopLevelTypeVarsConcrete(callTypeResult.type);
|
|
7911
|
+
const lambdaNodes = (0, types_1.isUnion)(concreteCallType)
|
|
7912
|
+
? argList
|
|
7913
|
+
.map((arg) => arg.valueExpression)
|
|
7914
|
+
.filter((node) => node?.nodeType === 33 /* ParseNodeType.Lambda */)
|
|
7915
|
+
: undefined;
|
|
7916
|
+
const lambdaTypeCache = lambdaNodes?.length
|
|
7917
|
+
? { lambdaNodes, entries: new Map(), branchIndex: 0 }
|
|
7918
|
+
: undefined;
|
|
7919
|
+
const previousCache = contextualLambdaTypeCache;
|
|
7920
|
+
let returnType;
|
|
7921
|
+
try {
|
|
7922
|
+
if (lambdaTypeCache) {
|
|
7923
|
+
contextualLambdaTypeCache = lambdaTypeCache;
|
|
7924
|
+
}
|
|
7925
|
+
returnType = mapSubtypesExpandTypeVars(callTypeResult.type, { sortSubtypes: true }, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
|
|
7926
|
+
if (lambdaTypeCache) {
|
|
7927
|
+
lambdaTypeCache.branchIndex++;
|
|
7819
7928
|
}
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7929
|
+
return useSpeculativeMode(isLastIteration ? undefined : getSpeculativeNodeForCall(errorNode), () => {
|
|
7930
|
+
const callResult = validateCallArgsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, constraints, skipUnknownArgCheck, inferenceContext, recursionCount);
|
|
7931
|
+
if (callResult.argumentErrors) {
|
|
7932
|
+
argumentErrors = true;
|
|
7933
|
+
}
|
|
7934
|
+
if (callResult.isTypeIncomplete) {
|
|
7935
|
+
isTypeIncomplete = true;
|
|
7936
|
+
}
|
|
7937
|
+
if (callResult.overloadsUsedForCall) {
|
|
7938
|
+
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
|
|
7939
|
+
}
|
|
7940
|
+
specializedInitSelfType = callResult.specializedInitSelfType;
|
|
7941
|
+
return callResult.returnType;
|
|
7942
|
+
}, {
|
|
7943
|
+
allowDiagnostics: true,
|
|
7944
|
+
});
|
|
7824
7945
|
});
|
|
7825
|
-
}
|
|
7946
|
+
}
|
|
7947
|
+
finally {
|
|
7948
|
+
contextualLambdaTypeCache = previousCache;
|
|
7949
|
+
}
|
|
7950
|
+
// Keep branch-specific checking and return inference separate from the
|
|
7951
|
+
// combined contextual types retained for subsequent queries.
|
|
7952
|
+
if (!isTypeIncomplete && lambdaTypeCache && lambdaTypeCache.branchIndex > 1) {
|
|
7953
|
+
(0, cancellationUtils_1.invalidateTypeCacheIfCanceled)(() => combineContextualLambdaTypes(lambdaTypeCache));
|
|
7954
|
+
}
|
|
7826
7955
|
// If we ended up with a "Never" type because all code paths returned
|
|
7827
7956
|
// undefined due to argument errors, transform the result into an Unknown
|
|
7828
7957
|
// to avoid subsequent false positives.
|
|
@@ -8022,6 +8151,110 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8022
8151
|
}
|
|
8023
8152
|
return { symbol, symbolName, classType, hasImplementation };
|
|
8024
8153
|
}
|
|
8154
|
+
// The synthesized "get" and "pop" methods for a TypedDict include a
|
|
8155
|
+
// catch-all overload that accepts any str key. When the key argument is a
|
|
8156
|
+
// union of str literals, that catch-all overload matches before union
|
|
8157
|
+
// expansion is attempted, which produces an overly-wide return type. This
|
|
8158
|
+
// function evaluates the call separately for each literal key subtype
|
|
8159
|
+
// (speculatively) and, if every subtype is accepted, returns the union of
|
|
8160
|
+
// the resulting return types.
|
|
8161
|
+
function refineTypedDictMethodCallForUnionKey(errorNode, argList, overloadedType, isCallTypeIncomplete, constraints, inferenceContext) {
|
|
8162
|
+
const overloads = types_1.OverloadedType.getOverloads(overloadedType);
|
|
8163
|
+
const overload = overloads[0];
|
|
8164
|
+
if (!overload || !types_1.FunctionType.isSynthesizedMethod(overload)) {
|
|
8165
|
+
return undefined;
|
|
8166
|
+
}
|
|
8167
|
+
const methodName = overload.shared.name;
|
|
8168
|
+
if (methodName !== 'get' && methodName !== 'pop') {
|
|
8169
|
+
return undefined;
|
|
8170
|
+
}
|
|
8171
|
+
const isBound = (0, types_1.isMethodType)(overload);
|
|
8172
|
+
const receiverType = isBound
|
|
8173
|
+
? overload.priv.strippedFirstParamType
|
|
8174
|
+
: overload.shared.parameters.length > 0
|
|
8175
|
+
? types_1.FunctionType.getParamType(overload, 0)
|
|
8176
|
+
: undefined;
|
|
8177
|
+
if (!receiverType || !(0, types_1.isClassInstance)(receiverType) || !types_1.ClassType.isTypedDictClass(receiverType)) {
|
|
8178
|
+
return undefined;
|
|
8179
|
+
}
|
|
8180
|
+
// Unbound generic methods have not specialized their field types from the
|
|
8181
|
+
// receiver. Keep the normal result rather than refining it to Unknown.
|
|
8182
|
+
if (!isBound &&
|
|
8183
|
+
((0, typeUtils_1.requiresSpecialization)(receiverType) || (0, typeUtils_1.containsAnyOrUnknown)(receiverType, /* recurse */ true))) {
|
|
8184
|
+
return undefined;
|
|
8185
|
+
}
|
|
8186
|
+
// Handle only simple positional calls: (key) or (key, default).
|
|
8187
|
+
const keyIndex = isBound ? 0 : 1;
|
|
8188
|
+
if (argList.length <= keyIndex || argList.length > keyIndex + 2) {
|
|
8189
|
+
return undefined;
|
|
8190
|
+
}
|
|
8191
|
+
if (!argList.every((arg) => !arg.name && arg.argCategory === 0 /* ArgCategory.Simple */)) {
|
|
8192
|
+
return undefined;
|
|
8193
|
+
}
|
|
8194
|
+
const keyArg = argList[keyIndex];
|
|
8195
|
+
const keyTypeResult = keyArg.typeResult ?? (keyArg.valueExpression ? getTypeOfExpression(keyArg.valueExpression) : undefined);
|
|
8196
|
+
if (!keyTypeResult || !(0, types_1.isUnion)(keyTypeResult.type)) {
|
|
8197
|
+
return undefined;
|
|
8198
|
+
}
|
|
8199
|
+
// Every subtype must be a str literal; otherwise keep the normal result.
|
|
8200
|
+
const keySubtypes = [];
|
|
8201
|
+
let allStrLiterals = true;
|
|
8202
|
+
(0, typeUtils_1.doForEachSubtype)(keyTypeResult.type, (subtype) => {
|
|
8203
|
+
if ((0, types_1.isClassInstance)(subtype) &&
|
|
8204
|
+
types_1.ClassType.isBuiltIn(subtype, 'str') &&
|
|
8205
|
+
typeof subtype.priv.literalValue === 'string') {
|
|
8206
|
+
keySubtypes.push(subtype);
|
|
8207
|
+
}
|
|
8208
|
+
else {
|
|
8209
|
+
allStrLiterals = false;
|
|
8210
|
+
}
|
|
8211
|
+
});
|
|
8212
|
+
if (!allStrLiterals || keySubtypes.length < 2 || keySubtypes.length > maxSingleOverloadArgTypeExpansionCount) {
|
|
8213
|
+
return undefined;
|
|
8214
|
+
}
|
|
8215
|
+
let isTypeIncomplete = !!keyTypeResult.isIncomplete;
|
|
8216
|
+
const returnTypes = [];
|
|
8217
|
+
const overloadsUsedForCall = new Set();
|
|
8218
|
+
const succeeded = useSpeculativeMode(getSpeculativeNodeForCall(errorNode), () => {
|
|
8219
|
+
for (const keySubtype of keySubtypes) {
|
|
8220
|
+
// Avoid revalidating unrelated keys and their default parameters.
|
|
8221
|
+
const candidates = overloads.filter((candidate) => {
|
|
8222
|
+
const paramType = types_1.FunctionType.getParamType(candidate, keyIndex);
|
|
8223
|
+
return ((0, types_1.isClassInstance)(paramType) &&
|
|
8224
|
+
types_1.ClassType.isBuiltIn(paramType, 'str') &&
|
|
8225
|
+
(paramType.priv.literalValue === undefined ||
|
|
8226
|
+
paramType.priv.literalValue === keySubtype.priv.literalValue));
|
|
8227
|
+
});
|
|
8228
|
+
if (candidates.length === 0) {
|
|
8229
|
+
return false;
|
|
8230
|
+
}
|
|
8231
|
+
const subtypeArgList = [...argList];
|
|
8232
|
+
subtypeArgList[keyIndex] = {
|
|
8233
|
+
argCategory: 0 /* ArgCategory.Simple */,
|
|
8234
|
+
typeResult: { type: keySubtype, isIncomplete: keyTypeResult.isIncomplete },
|
|
8235
|
+
};
|
|
8236
|
+
const subtypeResult = validateOverloadedArgTypes(errorNode, subtypeArgList, { type: overloadedType, isIncomplete: isCallTypeIncomplete }, constraints?.clone(),
|
|
8237
|
+
/* skipUnknownArgCheck */ true, inferenceContext, candidates);
|
|
8238
|
+
if (subtypeResult.isTypeIncomplete) {
|
|
8239
|
+
isTypeIncomplete = true;
|
|
8240
|
+
}
|
|
8241
|
+
if (subtypeResult.argumentErrors || !subtypeResult.returnType) {
|
|
8242
|
+
return false;
|
|
8243
|
+
}
|
|
8244
|
+
returnTypes.push(subtypeResult.returnType);
|
|
8245
|
+
subtypeResult.overloadsUsedForCall?.forEach((matched) => overloadsUsedForCall.add(matched));
|
|
8246
|
+
}
|
|
8247
|
+
return true;
|
|
8248
|
+
});
|
|
8249
|
+
if (!succeeded) {
|
|
8250
|
+
return undefined;
|
|
8251
|
+
}
|
|
8252
|
+
return {
|
|
8253
|
+
returnType: (0, types_1.combineTypes)(returnTypes),
|
|
8254
|
+
isTypeIncomplete,
|
|
8255
|
+
overloadsUsedForCall: [...overloadsUsedForCall],
|
|
8256
|
+
};
|
|
8257
|
+
}
|
|
8025
8258
|
function validateCallForOverloaded(errorNode, argList, expandedCallType, isCallTypeIncomplete, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
8026
8259
|
const overloads = types_1.OverloadedType.getOverloads(expandedCallType);
|
|
8027
8260
|
// Handle the 'cast' call as a special case.
|
|
@@ -8034,11 +8267,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8034
8267
|
let returnType = callResult.returnType ?? types_1.UnknownType.create();
|
|
8035
8268
|
let isTypeIncomplete = !!callResult.isTypeIncomplete;
|
|
8036
8269
|
let argumentErrors = !!callResult.argumentErrors;
|
|
8270
|
+
let overloadsUsedForCall = callResult.overloadsUsedForCall;
|
|
8037
8271
|
if (!argumentErrors) {
|
|
8272
|
+
const refinedResult = refineTypedDictMethodCallForUnionKey(errorNode, argList, expandedCallType, isCallTypeIncomplete, constraints, inferenceContext);
|
|
8273
|
+
if (refinedResult?.isTypeIncomplete) {
|
|
8274
|
+
isTypeIncomplete = true;
|
|
8275
|
+
}
|
|
8276
|
+
if (refinedResult) {
|
|
8277
|
+
overloadsUsedForCall = refinedResult.overloadsUsedForCall;
|
|
8278
|
+
}
|
|
8038
8279
|
// Call the function transform logic to handle special-cased functions.
|
|
8039
8280
|
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
|
8040
8281
|
argumentErrors: !!callResult.argumentErrors,
|
|
8041
|
-
returnType: callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
|
|
8282
|
+
returnType: refinedResult?.returnType ?? callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
|
|
8042
8283
|
isTypeIncomplete,
|
|
8043
8284
|
});
|
|
8044
8285
|
returnType = transformed.returnType;
|
|
@@ -8053,7 +8294,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8053
8294
|
returnType,
|
|
8054
8295
|
isTypeIncomplete,
|
|
8055
8296
|
argumentErrors,
|
|
8056
|
-
overloadsUsedForCall
|
|
8297
|
+
overloadsUsedForCall,
|
|
8057
8298
|
specializedInitSelfType: callResult.specializedInitSelfType,
|
|
8058
8299
|
};
|
|
8059
8300
|
}
|
|
@@ -10922,7 +11163,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10922
11163
|
const tdEntries = (0, typedDicts_1.getTypedDictMembersForClass)(evaluatorInterface, unexpandedType,
|
|
10923
11164
|
/* allowNarrowed */ true);
|
|
10924
11165
|
tdEntries.knownItems.forEach((entry, name) => {
|
|
10925
|
-
if (entry.isRequired || entry.isProvided) {
|
|
11166
|
+
if (!expectedTypedDictEntries || entry.isRequired || entry.isProvided) {
|
|
10926
11167
|
keyTypes.push({
|
|
10927
11168
|
node: entryNode,
|
|
10928
11169
|
type: types_1.ClassType.cloneWithLiteral(strObject, name),
|
|
@@ -10931,6 +11172,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10931
11172
|
}
|
|
10932
11173
|
});
|
|
10933
11174
|
if (!expectedTypedDictEntries) {
|
|
11175
|
+
// Open TypedDicts can contain extra items with arbitrary value types.
|
|
10934
11176
|
keyTypes.push({ node: entryNode, type: types_1.ClassType.cloneAsInstance(strObject) });
|
|
10935
11177
|
valueTypes.push({
|
|
10936
11178
|
node: entryNode,
|
|
@@ -11330,27 +11572,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11330
11572
|
// Pre-cache the incomplete function type in case the evaluation of the
|
|
11331
11573
|
// lambda depends on itself.
|
|
11332
11574
|
writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* EvalFlags.None */);
|
|
11333
|
-
//
|
|
11334
|
-
//
|
|
11335
|
-
// object for any lambda parameters that don't match. We could make this
|
|
11336
|
-
// more sophisticated in the future, but it becomes very complex to handle
|
|
11337
|
-
// all of the permutations.
|
|
11575
|
+
// Match positional parameters in order, but allow keyword-only parameters
|
|
11576
|
+
// to be reordered. Unmatched parameters without defaults use Unknown.
|
|
11338
11577
|
let sawParamMismatch = false;
|
|
11578
|
+
let expectedParamIndex = 0;
|
|
11579
|
+
let expectedKeywordParams;
|
|
11580
|
+
const positionOnlySeparatorIndex = node.d.params.findIndex((param) => param.d.category === 0 /* ParamCategory.Simple */ && !param.d.name);
|
|
11339
11581
|
node.d.params.forEach((param, index) => {
|
|
11340
11582
|
let paramType;
|
|
11341
11583
|
if (expectedParamDetails && !sawParamMismatch) {
|
|
11342
|
-
|
|
11343
|
-
|
|
11584
|
+
const isKeywordOnlySeparator = param.d.category === 1 /* ParamCategory.ArgsList */ && !param.d.name;
|
|
11585
|
+
if (isKeywordOnlySeparator) {
|
|
11586
|
+
if (expectedParamIndex < expectedParamDetails.params.length &&
|
|
11587
|
+
expectedParamDetails.params[expectedParamIndex].kind !== parameterUtils_1.ParamKind.Keyword) {
|
|
11588
|
+
sawParamMismatch = true;
|
|
11589
|
+
}
|
|
11590
|
+
}
|
|
11591
|
+
else if (expectedParamIndex < expectedParamDetails.params.length) {
|
|
11592
|
+
let expectedParam = expectedParamDetails.params[expectedParamIndex];
|
|
11593
|
+
const isPositionOnlyParam = (positionOnlySeparatorIndex >= 0 && index < positionOnlySeparatorIndex) ||
|
|
11594
|
+
(positionOnlySeparatorIndex < 0 &&
|
|
11595
|
+
paramsArePositionOnly &&
|
|
11596
|
+
!!param.d.name &&
|
|
11597
|
+
(0, symbolNameUtils_1.isPrivateName)(param.d.name.d.value));
|
|
11598
|
+
if (expectedParam.kind === parameterUtils_1.ParamKind.Keyword &&
|
|
11599
|
+
expectedParam.param.category === 0 /* ParamCategory.Simple */ &&
|
|
11600
|
+
param.d.category === 0 /* ParamCategory.Simple */ &&
|
|
11601
|
+
param.d.name &&
|
|
11602
|
+
!isPositionOnlyParam &&
|
|
11603
|
+
param.d.name.d.value !== expectedParam.param.name) {
|
|
11604
|
+
if (!expectedKeywordParams) {
|
|
11605
|
+
expectedKeywordParams = new Map();
|
|
11606
|
+
for (const keywordParam of expectedParamDetails.params) {
|
|
11607
|
+
if (keywordParam.kind === parameterUtils_1.ParamKind.Keyword &&
|
|
11608
|
+
keywordParam.param.category === 0 /* ParamCategory.Simple */ &&
|
|
11609
|
+
keywordParam.param.name) {
|
|
11610
|
+
expectedKeywordParams.set(keywordParam.param.name, keywordParam);
|
|
11611
|
+
}
|
|
11612
|
+
}
|
|
11613
|
+
}
|
|
11614
|
+
expectedParam = expectedKeywordParams.get(param.d.name.d.value) ?? expectedParam;
|
|
11615
|
+
}
|
|
11616
|
+
const isCompatibleKeywordParam = expectedParam.kind !== parameterUtils_1.ParamKind.Keyword ||
|
|
11617
|
+
expectedParam.param.category === 2 /* ParamCategory.KwargsDict */ ||
|
|
11618
|
+
(!isPositionOnlyParam && param.d.name?.d.value === expectedParam.param.name);
|
|
11344
11619
|
// If the parameter category matches and both of the parameters are
|
|
11345
11620
|
// either separators (/ or *) or not separators, copy the type
|
|
11346
11621
|
// from the expected parameter.
|
|
11347
11622
|
if (expectedParam.param.category === param.d.category &&
|
|
11348
|
-
!param.d.name === !expectedParam.param.name
|
|
11623
|
+
!param.d.name === !expectedParam.param.name &&
|
|
11624
|
+
isCompatibleKeywordParam) {
|
|
11349
11625
|
paramType = expectedParam.type;
|
|
11350
11626
|
}
|
|
11351
11627
|
else {
|
|
11352
11628
|
sawParamMismatch = true;
|
|
11353
11629
|
}
|
|
11630
|
+
expectedParamIndex++;
|
|
11354
11631
|
}
|
|
11355
11632
|
else if (param.d.defaultValue) {
|
|
11356
11633
|
// If the lambda param has a default value but there is no associated
|
|
@@ -11365,15 +11642,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11365
11642
|
// use the default value to infer the parameter's type.
|
|
11366
11643
|
paramType = inferParamTypeFromDefaultValue(param.d.defaultValue);
|
|
11367
11644
|
}
|
|
11645
|
+
if (param.d.defaultValue) {
|
|
11646
|
+
const defaultValueResult = getTypeOfExpression(param.d.defaultValue, 1 /* EvalFlags.ConvertEllipsisToAny */, (0, typeUtils_1.makeInferenceContext)(paramType));
|
|
11647
|
+
if (defaultValueResult.isIncomplete) {
|
|
11648
|
+
isIncomplete = true;
|
|
11649
|
+
}
|
|
11650
|
+
// The lambda can also be called with its own default value.
|
|
11651
|
+
if (paramType && !assignType(paramType, defaultValueResult.type)) {
|
|
11652
|
+
paramType = (0, types_1.combineTypes)([paramType, stripLiteralValue(defaultValueResult.type)]);
|
|
11653
|
+
}
|
|
11654
|
+
}
|
|
11368
11655
|
if (param.d.name) {
|
|
11369
11656
|
writeTypeCache(param.d.name, {
|
|
11370
11657
|
type: transformVariadicParamType(node, param.d.category, paramType ?? types_1.UnknownType.create()),
|
|
11371
11658
|
}, 0 /* EvalFlags.None */);
|
|
11372
11659
|
}
|
|
11373
|
-
if (param.d.defaultValue) {
|
|
11374
|
-
// Evaluate the default value if it's present.
|
|
11375
|
-
getTypeOfExpression(param.d.defaultValue, 1 /* EvalFlags.ConvertEllipsisToAny */);
|
|
11376
|
-
}
|
|
11377
11660
|
// Determine whether we need to insert an implied position-only parameter.
|
|
11378
11661
|
// This is needed when a function's parameters are named using the old-style
|
|
11379
11662
|
// way of specifying position-only parameters.
|
|
@@ -11439,6 +11722,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11439
11722
|
}
|
|
11440
11723
|
}
|
|
11441
11724
|
}
|
|
11725
|
+
if (expectedType && !forceSpeculative && !isIncomplete) {
|
|
11726
|
+
captureContextualLambdaTypes(node);
|
|
11727
|
+
}
|
|
11442
11728
|
}, {
|
|
11443
11729
|
dependentType: inferenceContext?.expectedType,
|
|
11444
11730
|
allowDiagnostics: !forceSpeculative && !canSkipDiagnosticForNode(node) && !inferenceContext?.isTypeIncomplete,
|
|
@@ -11449,7 +11735,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11449
11735
|
if (expectedType && !assignType(expectedType, functionType)) {
|
|
11450
11736
|
typeErrors = true;
|
|
11451
11737
|
}
|
|
11452
|
-
|
|
11738
|
+
const typeResult = { type: functionType, isIncomplete, typeErrors };
|
|
11739
|
+
if (expectedType && !forceSpeculative && !isIncomplete) {
|
|
11740
|
+
captureContextualLambdaTypes(node, typeResult);
|
|
11741
|
+
}
|
|
11742
|
+
return typeResult;
|
|
11453
11743
|
});
|
|
11454
11744
|
}
|
|
11455
11745
|
function getTypeOfComprehension(node, flags, inferenceContext) {
|
|
@@ -13582,6 +13872,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13582
13872
|
}
|
|
13583
13873
|
}
|
|
13584
13874
|
}
|
|
13875
|
+
else {
|
|
13876
|
+
// Callable metaclasses can return classes with different equality semantics.
|
|
13877
|
+
classType.shared.flags |= 134217728 /* ClassTypeFlags.HasUnresolvedMetaclass */;
|
|
13878
|
+
}
|
|
13585
13879
|
}
|
|
13586
13880
|
const effectiveMetaclass = computeEffectiveMetaclass(classType, node.d.name);
|
|
13587
13881
|
const enumMemberSetMayBeDynamicallyModified = types_1.ClassType.isEnumClass(classType) &&
|
|
@@ -14994,9 +15288,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14994
15288
|
}
|
|
14995
15289
|
return getExceptionType(subType, node.d.typeExpr);
|
|
14996
15290
|
});
|
|
14997
|
-
// If this is an except group,
|
|
14998
|
-
//
|
|
14999
|
-
// a BaseException.
|
|
15291
|
+
// If this is an except group, use a BaseExceptionGroup when it can contain
|
|
15292
|
+
// an exception outside the Exception hierarchy.
|
|
15000
15293
|
if (node.d.isExceptGroup) {
|
|
15001
15294
|
targetType = getBuiltInObject(node, includesBaseException ? 'BaseExceptionGroup' : 'ExceptionGroup', [
|
|
15002
15295
|
targetType,
|
|
@@ -17799,8 +18092,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17799
18092
|
// This will avoid a pathological performance condition for unannotated
|
|
17800
18093
|
// code that reassigns the same variable hundreds of times. If the symbol
|
|
17801
18094
|
// effectively has an "Any" annotation, it won't be narrowed.
|
|
17802
|
-
|
|
17803
|
-
|
|
18095
|
+
const declarations = symbol.getDeclarations();
|
|
18096
|
+
if (declarations.length > maxDeclarationsToUseForInference) {
|
|
18097
|
+
let isExceptionVariable = exceptionTargetSymbolCache.get(symbol.id);
|
|
18098
|
+
if (isExceptionVariable === undefined) {
|
|
18099
|
+
isExceptionVariable = declarations.every((decl) => {
|
|
18100
|
+
if (decl.type !== 1 /* DeclarationType.Variable */) {
|
|
18101
|
+
return false;
|
|
18102
|
+
}
|
|
18103
|
+
const parent = decl.node.parent;
|
|
18104
|
+
return parent?.nodeType === 28 /* ParseNodeType.Except */ && parent.d.name === decl.node;
|
|
18105
|
+
});
|
|
18106
|
+
exceptionTargetSymbolCache.set(symbol.id, isExceptionVariable);
|
|
18107
|
+
}
|
|
18108
|
+
// Exception targets get their types from code flow. Don't let the
|
|
18109
|
+
// declaration-count safeguard turn repeated targets into declared Unknown.
|
|
18110
|
+
if (!isExceptionVariable) {
|
|
18111
|
+
return { type: types_1.UnknownType.create() };
|
|
18112
|
+
}
|
|
17804
18113
|
}
|
|
17805
18114
|
// There was no declaration with a defined type.
|
|
17806
18115
|
return { type: undefined };
|
|
@@ -18430,7 +18739,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
18430
18739
|
if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType,
|
|
18431
18740
|
/* diag */ undefined,
|
|
18432
18741
|
/* constraints */ undefined,
|
|
18433
|
-
/* selfConstraints */ undefined, recursionCount)) {
|
|
18742
|
+
/* selfConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
|
18434
18743
|
isAssignable = false;
|
|
18435
18744
|
}
|
|
18436
18745
|
}
|
|
@@ -20131,6 +20440,34 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20131
20440
|
return true;
|
|
20132
20441
|
}
|
|
20133
20442
|
}
|
|
20443
|
+
// Determines whether the dest accepts every argument list the source
|
|
20444
|
+
// accepts, apart from parameters that overlap only when omitted.
|
|
20445
|
+
function isParamListOverlapOnlyByOmission(destType, srcType, destParamDetails, srcParamDetails, recursionCount) {
|
|
20446
|
+
if (destParamDetails.params.length !== srcParamDetails.params.length) {
|
|
20447
|
+
return false;
|
|
20448
|
+
}
|
|
20449
|
+
const destScopeIds = (0, typeUtils_1.getTypeVarScopeIds)(destType);
|
|
20450
|
+
const srcScopeIds = (0, typeUtils_1.getTypeVarScopeIds)(srcType);
|
|
20451
|
+
const constraints = new constraintTracker_1.ConstraintTracker();
|
|
20452
|
+
return destParamDetails.params.every((destParam, index) => {
|
|
20453
|
+
const srcParam = srcParamDetails.params[index];
|
|
20454
|
+
if (destParam.kind !== srcParam.kind ||
|
|
20455
|
+
destParam.param.category !== srcParam.param.category ||
|
|
20456
|
+
destParam.param.name !== srcParam.param.name) {
|
|
20457
|
+
return false;
|
|
20458
|
+
}
|
|
20459
|
+
if (destParam.defaultType && srcParam.defaultType) {
|
|
20460
|
+
if ((0, typeUtils_1.isOverlapOnlyByOmission)(destParam.type, destParam.defaultType, srcParam.type)) {
|
|
20461
|
+
return true;
|
|
20462
|
+
}
|
|
20463
|
+
}
|
|
20464
|
+
else if (srcParam.defaultType) {
|
|
20465
|
+
return false;
|
|
20466
|
+
}
|
|
20467
|
+
return assignType((0, typeUtils_1.makeTypeVarsFree)(destParam.type, destScopeIds), (0, typeUtils_1.makeTypeVarsBound)(srcParam.type, srcScopeIds),
|
|
20468
|
+
/* diag */ undefined, constraints, 0 /* AssignTypeFlags.Default */, recursionCount);
|
|
20469
|
+
});
|
|
20470
|
+
}
|
|
20134
20471
|
function assignFunction(destType, srcType, diag, constraints, flags, recursionCount) {
|
|
20135
20472
|
let canAssign = true;
|
|
20136
20473
|
const checkReturnType = (flags & 64 /* AssignTypeFlags.SkipReturnTypeCheck */) === 0;
|
|
@@ -20151,6 +20488,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20151
20488
|
disallowExtraKwargsForTd: (flags & 131072 /* AssignTypeFlags.DisallowExtraKwargsForTd */) !== 0,
|
|
20152
20489
|
});
|
|
20153
20490
|
adjustSourceParamDetailsForDestVariadic(isContra ? destParamDetails : srcParamDetails, isContra ? srcParamDetails : destParamDetails);
|
|
20491
|
+
let paramListOmissionResult;
|
|
20492
|
+
const checkParamListOmission = () => {
|
|
20493
|
+
if (paramListOmissionResult === undefined) {
|
|
20494
|
+
paramListOmissionResult = isParamListOverlapOnlyByOmission(destType, srcType, destParamDetails, srcParamDetails, recursionCount);
|
|
20495
|
+
}
|
|
20496
|
+
return paramListOmissionResult;
|
|
20497
|
+
};
|
|
20154
20498
|
const targetIncludesParamSpec = isContra ? !!srcParamSpec : !!destParamSpec;
|
|
20155
20499
|
const destPositionalCount = destParamDetails.firstKeywordOnlyIndex ?? destParamDetails.params.length;
|
|
20156
20500
|
const srcPositionalCount = srcParamDetails.firstKeywordOnlyIndex ?? srcParamDetails.params.length;
|
|
@@ -20212,6 +20556,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20212
20556
|
// be a match.
|
|
20213
20557
|
if ((flags & 32 /* AssignTypeFlags.PartialOverloadOverlap */) !== 0) {
|
|
20214
20558
|
if (srcParam.defaultType) {
|
|
20559
|
+
if ((0, typeUtils_1.isOverlapOnlyByOmission)(destParamType, destParam.defaultType, srcParamType) &&
|
|
20560
|
+
checkParamListOmission()) {
|
|
20561
|
+
canAssign = false;
|
|
20562
|
+
}
|
|
20215
20563
|
continue;
|
|
20216
20564
|
}
|
|
20217
20565
|
}
|
|
@@ -20483,6 +20831,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20483
20831
|
// be a match.
|
|
20484
20832
|
if (srcParamInfo.defaultType && destParamInfo.defaultType) {
|
|
20485
20833
|
if ((flags & 32 /* AssignTypeFlags.PartialOverloadOverlap */) !== 0) {
|
|
20834
|
+
if ((0, typeUtils_1.isOverlapOnlyByOmission)(destParamInfo.type, destParamInfo.defaultType, srcParamType) &&
|
|
20835
|
+
checkParamListOmission()) {
|
|
20836
|
+
canAssign = false;
|
|
20837
|
+
}
|
|
20486
20838
|
destParamMap.delete(srcParamInfo.param.name);
|
|
20487
20839
|
return;
|
|
20488
20840
|
}
|