@zzzen/pyright-internal 1.2.0-dev.20261011 → 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.js +4 -3
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +73 -27
- package/dist/analyzer/codeFlowEngine.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/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 +64 -26
- 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/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 +276 -43
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +5 -1
- package/dist/analyzer/typeGuards.js +116 -31
- package/dist/analyzer/typeGuards.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/typedDicts.d.ts +2 -1
- package/dist/analyzer/typedDicts.js +49 -10
- package/dist/analyzer/typedDicts.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/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/fourslash/hover.typedDict.get.fourslash.js +11 -0
- package/dist/tests/fourslash/hover.typedDict.get.fourslash.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/typeEvaluator1.test.js +19 -2
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +1 -1
- package/dist/tests/typeEvaluator6.test.js +20 -0
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +10 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +2 -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,6 +204,7 @@ 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();
|
|
208
210
|
let exceptionTargetSymbolCache = new Map();
|
|
@@ -399,6 +401,55 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
399
401
|
function setTypeResultForNode(node, typeResult, flags = 0 /* EvalFlags.None */) {
|
|
400
402
|
writeTypeCache(node, typeResult, flags);
|
|
401
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
|
+
}
|
|
402
453
|
function getMaxCodeComplexity() {
|
|
403
454
|
return maxCodeComplexity;
|
|
404
455
|
}
|
|
@@ -6100,12 +6151,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6100
6151
|
}
|
|
6101
6152
|
}
|
|
6102
6153
|
}
|
|
6103
|
-
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')) {
|
|
6104
6158
|
const tupleType = (0, typeUtils_1.getSpecializedTupleType)(baseType);
|
|
6105
|
-
if (tupleType
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
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
|
+
}
|
|
6109
6170
|
}
|
|
6110
6171
|
}
|
|
6111
6172
|
}
|
|
@@ -7218,7 +7279,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7218
7279
|
// there will be only one argument list in expandedArgTypes, and all entries
|
|
7219
7280
|
// (one for each argument) will be undefined. On subsequent calls, this
|
|
7220
7281
|
// list will grow to include union expansions.
|
|
7221
|
-
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
7282
|
+
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext, skipFinalValidation = false) {
|
|
7222
7283
|
const returnTypes = [];
|
|
7223
7284
|
const specializedInitSelfTypes = [];
|
|
7224
7285
|
let matchedOverloads = [];
|
|
@@ -7261,17 +7322,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7261
7322
|
if (!callResult.argumentErrors && callResult.returnType) {
|
|
7262
7323
|
if (evaluatorOptions.experimentalOverloadResult &&
|
|
7263
7324
|
!callResult.isTypeIncomplete &&
|
|
7264
|
-
!overload.priv.boundToType &&
|
|
7265
|
-
!overload.shared.methodClass &&
|
|
7266
|
-
!overload.shared.declaration?.isMethod &&
|
|
7267
7325
|
errorNode.nodeType === 9 /* ParseNodeType.Call */ &&
|
|
7268
|
-
|
|
7269
|
-
errorNode.parent?.nodeType === 3 /* ParseNodeType.Assignment */ &&
|
|
7270
|
-
errorNode.parent.d.rightExpr === errorNode &&
|
|
7326
|
+
(0, overloadResultSelector_1.isAutomaticOverloadSeedSyntax)(errorNode) &&
|
|
7271
7327
|
expandedArgTypes.length === 1 &&
|
|
7272
|
-
!hasArgTypeOverride
|
|
7273
|
-
|
|
7274
|
-
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 ?? []);
|
|
7275
7333
|
}
|
|
7276
7334
|
overloadsUsedForCall.push(overload);
|
|
7277
7335
|
matchedOverload = overload;
|
|
@@ -7390,6 +7448,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7390
7448
|
if (constraints && isDefinitiveMatchFound) {
|
|
7391
7449
|
constraints.copyFromClone(matchedOverloads[matchedOverloads.length - 1].constraints);
|
|
7392
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
|
+
}
|
|
7393
7461
|
// And run through the first expanded argument list one more time to
|
|
7394
7462
|
// populate the type cache, without applying a different branch's constraints.
|
|
7395
7463
|
const finalConstraints = expandedArgTypes.length > 1
|
|
@@ -7518,10 +7586,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7518
7586
|
name: arg.d.name,
|
|
7519
7587
|
}));
|
|
7520
7588
|
const sources = node.d.args.map((arg) => getTypeOfExpression(arg.d.valueExpr));
|
|
7521
|
-
|
|
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))) {
|
|
7522
7593
|
return decline('unsupported-argument-shape');
|
|
7523
7594
|
}
|
|
7524
|
-
if (!sources.some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
|
|
7595
|
+
if (![...sources, ...(receiver ? [receiver] : [])].some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
|
|
7525
7596
|
return decline('no-invariant-any');
|
|
7526
7597
|
}
|
|
7527
7598
|
const returns = [];
|
|
@@ -7531,10 +7602,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7531
7602
|
const declaration = overload.shared.declaration;
|
|
7532
7603
|
const declaredReturnType = overload.shared.declaredReturnType;
|
|
7533
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;
|
|
7534
7619
|
if (!declaration ||
|
|
7535
|
-
|
|
7536
|
-
overload.shared.methodClass ||
|
|
7537
|
-
overload.priv.boundToType ||
|
|
7620
|
+
!supportedBinding ||
|
|
7538
7621
|
overload.shared.typeParams.length ||
|
|
7539
7622
|
!declaredReturnType ||
|
|
7540
7623
|
!returnType ||
|
|
@@ -7576,6 +7659,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7576
7659
|
continue;
|
|
7577
7660
|
}
|
|
7578
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
|
+
}
|
|
7579
7665
|
const covered = proof.includes('unsupported')
|
|
7580
7666
|
? 'unsupported'
|
|
7581
7667
|
: proof.includes('not-covered')
|
|
@@ -7600,11 +7686,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7600
7686
|
: decline('equivalent-or-single-return');
|
|
7601
7687
|
});
|
|
7602
7688
|
}
|
|
7603
|
-
function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
7689
|
+
function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext, candidateOverloads) {
|
|
7604
7690
|
const filteredMatchResults = [];
|
|
7605
7691
|
let contextFreeArgTypes;
|
|
7606
7692
|
let isTypeIncomplete = !!typeResult.isIncomplete;
|
|
7607
7693
|
const type = typeResult.type;
|
|
7694
|
+
const overloads = candidateOverloads ?? types_1.OverloadedType.getOverloads(type);
|
|
7608
7695
|
const speculativeNode = getSpeculativeNodeForCall(errorNode);
|
|
7609
7696
|
// Start by evaluating the types of the arguments without any expected
|
|
7610
7697
|
// type. Also, filter the list of overloads based on the number of
|
|
@@ -7613,7 +7700,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7613
7700
|
// cache or record any diagnostics at this stage.
|
|
7614
7701
|
useSpeculativeMode(speculativeNode, () => {
|
|
7615
7702
|
let overloadIndex = 0;
|
|
7616
|
-
|
|
7703
|
+
overloads.forEach((overload) => {
|
|
7617
7704
|
// Consider only the functions that have the @overload decorator,
|
|
7618
7705
|
// not the final function that omits the overload. This is the
|
|
7619
7706
|
// intended behavior according to PEP 484.
|
|
@@ -7630,7 +7717,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7630
7717
|
// Skip the error message if we're in speculative mode because it's very
|
|
7631
7718
|
// expensive, and we're going to suppress the diagnostic anyway.
|
|
7632
7719
|
if (!canSkipDiagnosticForNode(errorNode)) {
|
|
7633
|
-
const overloads = types_1.OverloadedType.getOverloads(type);
|
|
7634
7720
|
const functionName = overloads.length > 0 && overloads[0].shared.name
|
|
7635
7721
|
? overloads[0].shared.name
|
|
7636
7722
|
: '<anonymous function>';
|
|
@@ -7685,7 +7771,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7685
7771
|
}
|
|
7686
7772
|
let expandedArgTypes = [argList.map((arg) => undefined)];
|
|
7687
7773
|
while (true) {
|
|
7688
|
-
const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext
|
|
7774
|
+
const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext,
|
|
7775
|
+
/* skipFinalValidation */ candidateOverloads !== undefined);
|
|
7689
7776
|
if (callResult.isTypeIncomplete) {
|
|
7690
7777
|
isTypeIncomplete = true;
|
|
7691
7778
|
}
|
|
@@ -7820,24 +7907,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7820
7907
|
}), exprNode);
|
|
7821
7908
|
return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
|
|
7822
7909
|
}
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
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++;
|
|
7834
7928
|
}
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
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
|
+
});
|
|
7839
7945
|
});
|
|
7840
|
-
}
|
|
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
|
+
}
|
|
7841
7955
|
// If we ended up with a "Never" type because all code paths returned
|
|
7842
7956
|
// undefined due to argument errors, transform the result into an Unknown
|
|
7843
7957
|
// to avoid subsequent false positives.
|
|
@@ -8037,6 +8151,110 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8037
8151
|
}
|
|
8038
8152
|
return { symbol, symbolName, classType, hasImplementation };
|
|
8039
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
|
+
}
|
|
8040
8258
|
function validateCallForOverloaded(errorNode, argList, expandedCallType, isCallTypeIncomplete, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
8041
8259
|
const overloads = types_1.OverloadedType.getOverloads(expandedCallType);
|
|
8042
8260
|
// Handle the 'cast' call as a special case.
|
|
@@ -8049,11 +8267,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8049
8267
|
let returnType = callResult.returnType ?? types_1.UnknownType.create();
|
|
8050
8268
|
let isTypeIncomplete = !!callResult.isTypeIncomplete;
|
|
8051
8269
|
let argumentErrors = !!callResult.argumentErrors;
|
|
8270
|
+
let overloadsUsedForCall = callResult.overloadsUsedForCall;
|
|
8052
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
|
+
}
|
|
8053
8279
|
// Call the function transform logic to handle special-cased functions.
|
|
8054
8280
|
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
|
8055
8281
|
argumentErrors: !!callResult.argumentErrors,
|
|
8056
|
-
returnType: callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
|
|
8282
|
+
returnType: refinedResult?.returnType ?? callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
|
|
8057
8283
|
isTypeIncomplete,
|
|
8058
8284
|
});
|
|
8059
8285
|
returnType = transformed.returnType;
|
|
@@ -8068,7 +8294,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8068
8294
|
returnType,
|
|
8069
8295
|
isTypeIncomplete,
|
|
8070
8296
|
argumentErrors,
|
|
8071
|
-
overloadsUsedForCall
|
|
8297
|
+
overloadsUsedForCall,
|
|
8072
8298
|
specializedInitSelfType: callResult.specializedInitSelfType,
|
|
8073
8299
|
};
|
|
8074
8300
|
}
|
|
@@ -11496,6 +11722,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11496
11722
|
}
|
|
11497
11723
|
}
|
|
11498
11724
|
}
|
|
11725
|
+
if (expectedType && !forceSpeculative && !isIncomplete) {
|
|
11726
|
+
captureContextualLambdaTypes(node);
|
|
11727
|
+
}
|
|
11499
11728
|
}, {
|
|
11500
11729
|
dependentType: inferenceContext?.expectedType,
|
|
11501
11730
|
allowDiagnostics: !forceSpeculative && !canSkipDiagnosticForNode(node) && !inferenceContext?.isTypeIncomplete,
|
|
@@ -11506,7 +11735,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11506
11735
|
if (expectedType && !assignType(expectedType, functionType)) {
|
|
11507
11736
|
typeErrors = true;
|
|
11508
11737
|
}
|
|
11509
|
-
|
|
11738
|
+
const typeResult = { type: functionType, isIncomplete, typeErrors };
|
|
11739
|
+
if (expectedType && !forceSpeculative && !isIncomplete) {
|
|
11740
|
+
captureContextualLambdaTypes(node, typeResult);
|
|
11741
|
+
}
|
|
11742
|
+
return typeResult;
|
|
11510
11743
|
});
|
|
11511
11744
|
}
|
|
11512
11745
|
function getTypeOfComprehension(node, flags, inferenceContext) {
|