@zzzen/pyright-internal 1.2.0-dev.20260802 → 1.2.0-dev.20260816
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/analyzerNodeInfo.d.ts +4 -1
- package/dist/analyzer/analyzerNodeInfo.js +13 -0
- package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
- package/dist/analyzer/binder.js +88 -1
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +71 -15
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +47 -7
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructors.js +18 -8
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.d.ts +1 -0
- package/dist/analyzer/dataClasses.js +98 -19
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/decorators.js +18 -0
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/scope.d.ts +3 -0
- package/dist/analyzer/scope.js +10 -0
- package/dist/analyzer/scope.js.map +1 -1
- package/dist/analyzer/symbol.d.ts +4 -1
- package/dist/analyzer/symbol.js +8 -0
- package/dist/analyzer/symbol.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +6 -2
- package/dist/analyzer/typeCacheUtils.js +16 -37
- package/dist/analyzer/typeCacheUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +955 -105
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeGuards.js +11 -8
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/types.d.ts +11 -1
- package/dist/analyzer/types.js +48 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/localization/localize.d.ts +6 -0
- package/dist/localization/localize.js +4 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +13 -0
- package/dist/tests/typeCacheUtils.test.d.ts +1 -0
- package/dist/tests/typeCacheUtils.test.js +69 -0
- package/dist/tests/typeCacheUtils.test.js.map +1 -0
- package/dist/tests/typeEvaluator3.test.js +8 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +12 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/tests/typeEvaluator6.test.js +33 -1
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +37 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +318 -4
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/dist/tests/types.test.d.ts +1 -0
- package/dist/tests/types.test.js +63 -0
- package/dist/tests/types.test.js.map +1 -0
- package/dist/typeServer/typeGuards.js +4 -3
- package/dist/typeServer/typeGuards.js.map +1 -1
- package/package.json +1 -1
|
@@ -203,6 +203,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
203
203
|
let functionRecursionMap = new Map();
|
|
204
204
|
let codeFlowAnalyzerCache = new Map();
|
|
205
205
|
let typeCache = new Map();
|
|
206
|
+
let typeFormTypeCache = new Map();
|
|
206
207
|
let effectiveTypeCache = new Map();
|
|
207
208
|
let expectedTypeCache = new Map();
|
|
208
209
|
let asymmetricAccessorAssignmentCache = new Set();
|
|
@@ -212,6 +213,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
212
213
|
let incompleteGenCount = 0;
|
|
213
214
|
const returnTypeInferenceContextStack = [];
|
|
214
215
|
let returnTypeInferenceTypeCache;
|
|
216
|
+
let returnTypeInferenceTypeFormTypeCache;
|
|
215
217
|
const signatureTrackerStack = [];
|
|
216
218
|
let prefetched;
|
|
217
219
|
function runWithCancellationToken(token, callback) {
|
|
@@ -252,6 +254,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
252
254
|
functionRecursionMap = new Map();
|
|
253
255
|
codeFlowAnalyzerCache = new Map();
|
|
254
256
|
typeCache = new Map();
|
|
257
|
+
typeFormTypeCache = new Map();
|
|
255
258
|
effectiveTypeCache = new Map();
|
|
256
259
|
expectedTypeCache = new Map();
|
|
257
260
|
asymmetricAccessorAssignmentCache = new Set();
|
|
@@ -266,8 +269,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
266
269
|
return typeCache.get(node.id);
|
|
267
270
|
}
|
|
268
271
|
}
|
|
272
|
+
function getTypeFormTypeCache(node) {
|
|
273
|
+
if (returnTypeInferenceTypeFormTypeCache && isNodeInReturnTypeInferenceContext(node)) {
|
|
274
|
+
return returnTypeInferenceTypeFormTypeCache;
|
|
275
|
+
}
|
|
276
|
+
return typeFormTypeCache;
|
|
277
|
+
}
|
|
278
|
+
function readTypeFormTypeCacheEntry(node, expectedType) {
|
|
279
|
+
return getTypeFormTypeCache(node)
|
|
280
|
+
.get(node.id)
|
|
281
|
+
?.find((entry) => (0, typeCacheUtils_1.contextualTypeCacheEntryMatches)(entry, expectedType));
|
|
282
|
+
}
|
|
283
|
+
// Contextual reads consult expectedTypeCache and prefer a matching TypeForm result.
|
|
284
|
+
// Runtime-only consumers must use readTypeCacheEntry so this precedence is not
|
|
285
|
+
// accidentally applied where an ordinary runtime type is required.
|
|
286
|
+
function readContextualTypeCacheEntryForNode(node) {
|
|
287
|
+
const expectedType = expectedTypeCache.get(node.id)?.type;
|
|
288
|
+
if (expectedType && expectedTypeWantsTypeForm(expectedType)) {
|
|
289
|
+
return (readTypeFormTypeCacheEntry(node, expectedType) ??
|
|
290
|
+
readTypeFormTypeCacheEntry(node, /* expectedType */ undefined) ??
|
|
291
|
+
readTypeCacheEntry(node));
|
|
292
|
+
}
|
|
293
|
+
return readTypeCacheEntry(node) ?? readTypeFormTypeCacheEntry(node, /* expectedType */ undefined);
|
|
294
|
+
}
|
|
295
|
+
// Bumps the incomplete generation count using the same rules for both the
|
|
296
|
+
// regular type cache and the TypeForm type cache so the two cache-invalidation
|
|
297
|
+
// paths cannot drift. A complete result always bumps the count (invalidating
|
|
298
|
+
// dependent incomplete entries); an incomplete result bumps only when its type
|
|
299
|
+
// differs from the previously-cached value.
|
|
300
|
+
function updateIncompleteGenerationCount(typeResult, oldTypeResult) {
|
|
301
|
+
if (!typeResult.isIncomplete) {
|
|
302
|
+
incompleteGenCount++;
|
|
303
|
+
}
|
|
304
|
+
else if (oldTypeResult !== undefined && !(0, types_1.isTypeSame)(typeResult.type, oldTypeResult.type)) {
|
|
305
|
+
incompleteGenCount++;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
269
308
|
function isTypeCached(node) {
|
|
270
|
-
|
|
309
|
+
// This helper is used by runtime-evaluation guards. A contextual TypeForm
|
|
310
|
+
// entry does not prove that the ordinary runtime type was evaluated.
|
|
311
|
+
return isTypeCacheEntryValid(readTypeCacheEntry(node));
|
|
312
|
+
}
|
|
313
|
+
function isTypeFormTypeCached(node, expectedType) {
|
|
314
|
+
return isTypeCacheEntryValid(readTypeFormTypeCacheEntry(node, expectedType));
|
|
315
|
+
}
|
|
316
|
+
function isTypeCacheEntryValid(cacheEntry) {
|
|
271
317
|
if (!cacheEntry) {
|
|
272
318
|
return false;
|
|
273
319
|
}
|
|
@@ -300,20 +346,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
300
346
|
return cacheEntry.typeResult.type;
|
|
301
347
|
}
|
|
302
348
|
function writeTypeCache(node, typeResult, flags, inferenceContext, allowSpeculativeCaching = false) {
|
|
349
|
+
const useTypeFormCache = (flags !== undefined && (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) ||
|
|
350
|
+
(!!inferenceContext && expectedTypeWantsTypeForm(inferenceContext.expectedType));
|
|
351
|
+
if (useTypeFormCache) {
|
|
352
|
+
const expectedType = inferenceContext?.expectedType;
|
|
353
|
+
// Speculative TypeForm results are not retained, so they must not invalidate
|
|
354
|
+
// persistent incomplete entries through the global generation counter.
|
|
355
|
+
if (isSpeculativeModeInUse(node)) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const typeFormCache = getTypeFormTypeCache(node);
|
|
359
|
+
const cacheEntries = typeFormCache.get(node.id) ?? [];
|
|
360
|
+
const oldEntry = cacheEntries.find((entry) => (0, typeCacheUtils_1.contextualTypeCacheEntryMatches)(entry, expectedType));
|
|
361
|
+
updateIncompleteGenerationCount(typeResult, oldEntry?.typeResult);
|
|
362
|
+
typeFormCache.set(node.id, (0, typeCacheUtils_1.addContextualTypeCacheEntry)(cacheEntries, { typeResult, flags, incompleteGenCount, expectedType }));
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
303
365
|
// Should we use a temporary cache associated with a contextual
|
|
304
366
|
// analysis of a function, contextualized based on call-site argument types?
|
|
305
367
|
const typeCacheToUse = returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)
|
|
306
368
|
? returnTypeInferenceTypeCache
|
|
307
369
|
: typeCache;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
const oldValue = typeCacheToUse.get(node.id);
|
|
313
|
-
if (oldValue !== undefined && !(0, types_1.isTypeSame)(typeResult.type, oldValue.typeResult.type)) {
|
|
314
|
-
incompleteGenCount++;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
370
|
+
const oldValue = typeCacheToUse.get(node.id);
|
|
371
|
+
updateIncompleteGenerationCount(typeResult, oldValue?.typeResult);
|
|
317
372
|
typeCacheToUse.set(node.id, { typeResult, flags, incompleteGenCount });
|
|
318
373
|
// If the entry is located within a part of the parse tree that is currently being
|
|
319
374
|
// "speculatively" evaluated, track it so we delete the cached entry when we leave
|
|
@@ -404,7 +459,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
404
459
|
// type of surrounding statements to be evaluated.
|
|
405
460
|
function getType(node) {
|
|
406
461
|
initializePrefetchedTypes(node);
|
|
407
|
-
let type =
|
|
462
|
+
let type = evaluateContextualTypeForSubnode(node, () => {
|
|
408
463
|
evaluateTypesForExpressionInContext(node);
|
|
409
464
|
})?.type;
|
|
410
465
|
// If this is a type parameter with a calculated variance, see if we
|
|
@@ -441,18 +496,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
441
496
|
return type;
|
|
442
497
|
}
|
|
443
498
|
function getTypeResult(node) {
|
|
444
|
-
return
|
|
499
|
+
return evaluateContextualTypeForSubnode(node, () => {
|
|
445
500
|
evaluateTypesForExpressionInContext(node);
|
|
446
501
|
});
|
|
447
502
|
}
|
|
448
503
|
function getTypeResultForDecorator(node) {
|
|
449
|
-
return
|
|
504
|
+
return evaluateContextualTypeForSubnode(node, () => {
|
|
450
505
|
evaluateTypesForExpressionInContext(node.d.expr);
|
|
451
506
|
});
|
|
452
507
|
}
|
|
453
508
|
// Reads the type of the node from the cache.
|
|
454
509
|
function getCachedType(node) {
|
|
455
|
-
|
|
510
|
+
// Prefer the ordinary runtime type when both caches contain an entry for this node.
|
|
511
|
+
// Fall back to the contextual cache so TypeForm-only evaluations remain discoverable.
|
|
512
|
+
const cacheEntry = readTypeCacheEntry(node) ?? readContextualTypeCacheEntryForNode(node);
|
|
513
|
+
if (!cacheEntry || cacheEntry.typeResult.isIncomplete) {
|
|
514
|
+
return undefined;
|
|
515
|
+
}
|
|
516
|
+
return cacheEntry.typeResult.type;
|
|
456
517
|
}
|
|
457
518
|
// Determines the expected type of a specified node based on surrounding
|
|
458
519
|
// context. For example, if it's a subexpression of an argument expression,
|
|
@@ -570,8 +631,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
570
631
|
}
|
|
571
632
|
}
|
|
572
633
|
function getTypeOfExpression(node, flags = 0 /* EvalFlags.None */, inferenceContext) {
|
|
634
|
+
let useTypeFormCache = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0;
|
|
635
|
+
if (inferenceContext) {
|
|
636
|
+
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
|
637
|
+
useTypeFormCache || (useTypeFormCache = expectedTypeWantsTypeForm(inferenceContext.expectedType));
|
|
638
|
+
if (expectedTypeRequiresTypeForm(inferenceContext.expectedType)) {
|
|
639
|
+
flags |= 1073741824 /* EvalFlags.TypeFormArg */;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (flags & 33554432 /* EvalFlags.NoConvertSpecialForm */) === 0) {
|
|
643
|
+
flags |= 32 /* EvalFlags.NoParamSpec */ | 64 /* EvalFlags.NoTypeVarTuple */;
|
|
644
|
+
}
|
|
573
645
|
// Is this type already cached?
|
|
574
|
-
const cacheEntry =
|
|
646
|
+
const cacheEntry = useTypeFormCache
|
|
647
|
+
? readTypeFormTypeCacheEntry(node, inferenceContext?.expectedType)
|
|
648
|
+
: readTypeCacheEntry(node);
|
|
575
649
|
if (cacheEntry) {
|
|
576
650
|
if (!cacheEntry.typeResult.isIncomplete || cacheEntry.incompleteGenCount === incompleteGenCount) {
|
|
577
651
|
if (printExpressionTypes) {
|
|
@@ -581,7 +655,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
581
655
|
}
|
|
582
656
|
}
|
|
583
657
|
// Is it cached in the speculative type cache?
|
|
584
|
-
const specCacheEntry =
|
|
658
|
+
const specCacheEntry = useTypeFormCache
|
|
659
|
+
? undefined
|
|
660
|
+
: speculativeTypeTracker.getSpeculativeType(node, inferenceContext?.expectedType);
|
|
585
661
|
if (specCacheEntry) {
|
|
586
662
|
if (!specCacheEntry.typeResult.isIncomplete ||
|
|
587
663
|
specCacheEntry.incompleteGenerationCount === incompleteGenCount) {
|
|
@@ -599,9 +675,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
599
675
|
// the cancellation check. If the operation is canceled, an exception
|
|
600
676
|
// will be thrown at this point.
|
|
601
677
|
checkForCancellation();
|
|
602
|
-
if (inferenceContext) {
|
|
603
|
-
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
|
604
|
-
}
|
|
605
678
|
// If we haven't already fetched some core type definitions from the
|
|
606
679
|
// typeshed stubs, do so here. It would be better to fetch this when it's
|
|
607
680
|
// needed in assignType, but we don't have access to the parse tree
|
|
@@ -966,7 +1039,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
966
1039
|
}
|
|
967
1040
|
function getTypeOfStringList(node, flags, inferenceContext) {
|
|
968
1041
|
let typeResult;
|
|
969
|
-
if ((flags & 8 /* EvalFlags.StrLiteralAsType */) !== 0 &&
|
|
1042
|
+
if ((flags & 8 /* EvalFlags.StrLiteralAsType */) !== 0 &&
|
|
1043
|
+
((flags & 1073741824 /* EvalFlags.TypeFormArg */) === 0 || (flags & 33554432 /* EvalFlags.NoConvertSpecialForm */) !== 0)) {
|
|
970
1044
|
return getTypeOfStringListAsType(node, flags);
|
|
971
1045
|
}
|
|
972
1046
|
const isBytesNode = (node) => (node.d.token.flags & 32 /* StringTokenFlags.Bytes */) !== 0;
|
|
@@ -1071,7 +1145,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
1071
1145
|
if ((flags & 16777216 /* EvalFlags.ParsesStringLiteral */) === 0) {
|
|
1072
1146
|
updatedFlags |= 524288 /* EvalFlags.NotParsed */;
|
|
1073
1147
|
}
|
|
1074
|
-
updatedFlags &= ~1073741824 /* EvalFlags.TypeFormArg */;
|
|
1075
1148
|
if (node.d.annotation && (flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
1076
1149
|
return getTypeOfExpression(node.d.annotation, updatedFlags);
|
|
1077
1150
|
}
|
|
@@ -3448,6 +3521,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3448
3521
|
type = types_1.UnknownType.create();
|
|
3449
3522
|
}
|
|
3450
3523
|
}
|
|
3524
|
+
if ((0, types_1.isTypeVarTuple)(type) && (flags & 64 /* EvalFlags.NoTypeVarTuple */) !== 0 && !type.priv.isInUnion) {
|
|
3525
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeVarTupleContext(), node);
|
|
3526
|
+
type = types_1.UnknownType.create();
|
|
3527
|
+
}
|
|
3451
3528
|
// If we're expecting a type expression and got a sentinel literal instance,
|
|
3452
3529
|
// treat it as its instantiable counterpart. This is similar to how None
|
|
3453
3530
|
// is treated in a type expression context.
|
|
@@ -3458,16 +3535,64 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3458
3535
|
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0) {
|
|
3459
3536
|
reportUseOfTypeCheckOnly(type, node);
|
|
3460
3537
|
}
|
|
3461
|
-
if ((flags & 128 /* EvalFlags.InstantiableType */) !== 0) {
|
|
3538
|
+
if ((flags & (128 /* EvalFlags.InstantiableType */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
3462
3539
|
if ((flags & 1024 /* EvalFlags.AllowGeneric */) === 0) {
|
|
3463
3540
|
if ((0, types_1.isInstantiableClass)(type) && types_1.ClassType.isBuiltIn(type, 'Generic')) {
|
|
3464
3541
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.genericNotAllowed(), node);
|
|
3542
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
3543
|
+
type = types_1.UnknownType.create();
|
|
3544
|
+
}
|
|
3465
3545
|
}
|
|
3466
3546
|
}
|
|
3467
3547
|
}
|
|
3468
3548
|
return { type, isIncomplete };
|
|
3469
3549
|
}
|
|
3550
|
+
const typeFormSpecialFormDiagnosticFactories = [
|
|
3551
|
+
['Final', () => localize_1.LocMessage.finalContext()],
|
|
3552
|
+
['Optional', () => localize_1.LocMessage.optionalExtraArgs()],
|
|
3553
|
+
['Protocol', () => localize_1.LocMessage.protocolNotAllowed()],
|
|
3554
|
+
['TypedDict', () => localize_1.LocMessage.typedDictNotAllowed()],
|
|
3555
|
+
['TypeAlias', () => localize_1.LocMessage.typeAnnotationVariable()],
|
|
3556
|
+
['Literal', () => localize_1.LocMessage.literalNotAllowed()],
|
|
3557
|
+
[['TypeGuard', 'TypeIs'], () => localize_1.LocMessage.typeGuardArgCount()],
|
|
3558
|
+
['Union', () => localize_1.LocMessage.unionTypeArgCount()],
|
|
3559
|
+
['Annotated', () => localize_1.LocMessage.annotatedTypeArgMissing()],
|
|
3560
|
+
['ClassVar', () => localize_1.LocMessage.classVarNotAllowed()],
|
|
3561
|
+
['Required', () => localize_1.LocMessage.requiredArgCount()],
|
|
3562
|
+
['NotRequired', () => localize_1.LocMessage.notRequiredArgCount()],
|
|
3563
|
+
['ReadOnly', () => localize_1.LocMessage.readOnlyArgCount()],
|
|
3564
|
+
['Unpack', () => localize_1.LocMessage.unpackArgCount()],
|
|
3565
|
+
['Concatenate', () => localize_1.LocMessage.concatenateContext()],
|
|
3566
|
+
];
|
|
3567
|
+
function rejectBareSpecialFormInTypeForm(type, node) {
|
|
3568
|
+
for (const [className, diagnosticFactory] of typeFormSpecialFormDiagnosticFactories) {
|
|
3569
|
+
if (types_1.ClassType.isBuiltIn(type, className)) {
|
|
3570
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, diagnosticFactory(), node);
|
|
3571
|
+
return types_1.UnknownType.create();
|
|
3572
|
+
}
|
|
3573
|
+
}
|
|
3574
|
+
return undefined;
|
|
3575
|
+
}
|
|
3470
3576
|
function addTypeFormForSymbol(node, type, flags, includesVarDecl) {
|
|
3577
|
+
const isIndexBase = node.parent?.nodeType === 27 /* ParseNodeType.Index */ && node.parent.d.leftExpr === node;
|
|
3578
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (0, types_1.isTypeVar)(type) && types_1.TypeVarType.isSelf(type)) {
|
|
3579
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)(type));
|
|
3580
|
+
}
|
|
3581
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (0, types_1.isInstantiableClass)(type) && !isIndexBase) {
|
|
3582
|
+
if (isTypeFormClass(type)) {
|
|
3583
|
+
return createTypeFormType(type, node, /* typeArgs */ undefined);
|
|
3584
|
+
}
|
|
3585
|
+
const rejectedType = rejectBareSpecialFormInTypeForm(type, node);
|
|
3586
|
+
if (rejectedType) {
|
|
3587
|
+
return rejectedType;
|
|
3588
|
+
}
|
|
3589
|
+
if (types_1.ClassType.isBuiltIn(type, 'Self')) {
|
|
3590
|
+
type = createSelfType(type, node, /* typeArgs */ undefined, flags);
|
|
3591
|
+
if ((0, types_1.isTypeVar)(type)) {
|
|
3592
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)(type));
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3471
3596
|
const isValid = isSymbolValidTypeExpression(type, includesVarDecl);
|
|
3472
3597
|
// If the type already has type information associated with it, don't replace.
|
|
3473
3598
|
if (type.props?.typeForm) {
|
|
@@ -3794,7 +3919,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3794
3919
|
// Is this a generic class that needs to be specialized?
|
|
3795
3920
|
if ((0, types_1.isInstantiableClass)(type)) {
|
|
3796
3921
|
if ((flags & 128 /* EvalFlags.InstantiableType */) !== 0 && (flags & 512 /* EvalFlags.AllowMissingTypeArgs */) === 0) {
|
|
3797
|
-
if (!type.props?.typeAliasInfo && (0, typeUtils_1.requiresTypeArgs)(type)) {
|
|
3922
|
+
if (!type.props?.typeAliasInfo && !isTypeFormClass(type) && (0, typeUtils_1.requiresTypeArgs)(type)) {
|
|
3798
3923
|
if (!type.priv.typeArgs || !type.priv.isTypeArgExplicit) {
|
|
3799
3924
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.LocMessage.typeArgsMissingForClass().format({
|
|
3800
3925
|
name: type.priv.aliasName || type.shared.name,
|
|
@@ -5199,6 +5324,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5199
5324
|
}), { ...aliasInfo, typeArgs: defaultTypeArgs });
|
|
5200
5325
|
return type;
|
|
5201
5326
|
}
|
|
5327
|
+
function convertTypeArgToInstance(type, flags) {
|
|
5328
|
+
const contextualType = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? type.props?.typeForm ?? type : type;
|
|
5329
|
+
return (0, typeUtils_1.convertToInstance)(contextualType);
|
|
5330
|
+
}
|
|
5202
5331
|
// Handles index expressions that are providing type arguments for a
|
|
5203
5332
|
// generic type alias.
|
|
5204
5333
|
function createSpecializedTypeAlias(node, baseType, flags) {
|
|
@@ -5318,7 +5447,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5318
5447
|
}
|
|
5319
5448
|
let typeArgType;
|
|
5320
5449
|
if (index < typeArgs.length) {
|
|
5321
|
-
typeArgType = (
|
|
5450
|
+
typeArgType = convertTypeArgToInstance(typeArgs[index].type, flags);
|
|
5322
5451
|
}
|
|
5323
5452
|
else if (param.shared.isDefaultExplicit) {
|
|
5324
5453
|
typeArgType = solveAndApplyConstraints(param, constraints, {
|
|
@@ -5473,11 +5602,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5473
5602
|
if (types_1.ClassType.isBuiltIn(concreteSubtype, 'InitVar')) {
|
|
5474
5603
|
// Special-case InitVar, used in dataclasses.
|
|
5475
5604
|
const typeArgs = getTypeArgs(node, flags);
|
|
5476
|
-
|
|
5477
|
-
|
|
5605
|
+
const isTypeFormArg = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0;
|
|
5606
|
+
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0 || isTypeFormArg) {
|
|
5607
|
+
if (isTypeFormArg || (flags & 32768 /* EvalFlags.VarTypeAnnotation */) === 0) {
|
|
5478
5608
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.initVarNotAllowed(), node.d.leftExpr);
|
|
5479
5609
|
}
|
|
5480
5610
|
}
|
|
5611
|
+
if (isTypeFormArg) {
|
|
5612
|
+
return types_1.UnknownType.create();
|
|
5613
|
+
}
|
|
5481
5614
|
if (typeArgs.length === 1) {
|
|
5482
5615
|
return typeArgs[0].type;
|
|
5483
5616
|
}
|
|
@@ -5562,12 +5695,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5562
5695
|
}
|
|
5563
5696
|
return types_1.UnknownType.create();
|
|
5564
5697
|
});
|
|
5565
|
-
// In case we didn't walk the list items above, do so now.
|
|
5566
|
-
//
|
|
5698
|
+
// In case we didn't walk the list items above, do so now. TypeForm arguments
|
|
5699
|
+
// use a separate cache, so check it when the enclosing expression is a TypeForm.
|
|
5567
5700
|
if (!baseTypeResult.isIncomplete) {
|
|
5701
|
+
const isTypeFormArg = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0;
|
|
5568
5702
|
node.d.items.forEach((item) => {
|
|
5569
|
-
|
|
5570
|
-
|
|
5703
|
+
const isItemCached = isTypeFormArg
|
|
5704
|
+
? isTypeFormTypeCached(item.d.valueExpr, /* expectedType */ undefined)
|
|
5705
|
+
: isTypeCached(item.d.valueExpr);
|
|
5706
|
+
if (!isItemCached) {
|
|
5707
|
+
getTypeOfExpression(item.d.valueExpr, flags & (4 /* EvalFlags.ForwardRefs */ | 1073741824 /* EvalFlags.TypeFormArg */));
|
|
5571
5708
|
}
|
|
5572
5709
|
});
|
|
5573
5710
|
}
|
|
@@ -5862,7 +5999,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5862
5999
|
function getTypeArgs(node, flags, options) {
|
|
5863
6000
|
const typeArgs = [];
|
|
5864
6001
|
let adjFlags = flags | 33554432 /* EvalFlags.NoConvertSpecialForm */;
|
|
5865
|
-
adjFlags
|
|
6002
|
+
if ((adjFlags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
6003
|
+
adjFlags |= 256 /* EvalFlags.TypeExpression */;
|
|
6004
|
+
}
|
|
5866
6005
|
const allowFinalClassVar = () => {
|
|
5867
6006
|
// If the annotation is a variable within the body of a dataclass, a
|
|
5868
6007
|
// Final is allowed with a ClassVar annotation. In all other cases,
|
|
@@ -6191,12 +6330,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6191
6330
|
const isCyclicalTypeVarCall = (0, types_1.isInstantiableClass)(baseTypeResult.type) &&
|
|
6192
6331
|
types_1.ClassType.isBuiltIn(baseTypeResult.type, 'TypeVar') &&
|
|
6193
6332
|
AnalyzerNodeInfo.getFileInfo(node).isTypingStubFile;
|
|
6194
|
-
|
|
6333
|
+
const isTypeFormCall = (0, types_1.isInstantiableClass)(baseTypeResult.type) && isTypeFormClass(baseTypeResult.type);
|
|
6334
|
+
if (!isCyclicalTypeVarCall && !isTypeFormCall) {
|
|
6195
6335
|
argList.forEach((arg) => {
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6336
|
+
const valueExpression = arg.valueExpression;
|
|
6337
|
+
if (valueExpression &&
|
|
6338
|
+
valueExpression.nodeType !== 48 /* ParseNodeType.StringList */ &&
|
|
6339
|
+
!isTypeCached(valueExpression)) {
|
|
6340
|
+
const expectedType = expectedTypeCache.get(valueExpression.id)?.type;
|
|
6341
|
+
if (isTypeFormTypeCached(valueExpression, expectedType)) {
|
|
6342
|
+
suppressDiagnostics(valueExpression, () => getTypeOfExpression(valueExpression));
|
|
6343
|
+
}
|
|
6344
|
+
else {
|
|
6345
|
+
getTypeOfExpression(valueExpression);
|
|
6346
|
+
}
|
|
6200
6347
|
}
|
|
6201
6348
|
});
|
|
6202
6349
|
}
|
|
@@ -6266,6 +6413,166 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6266
6413
|
}
|
|
6267
6414
|
return typeFormResult;
|
|
6268
6415
|
}
|
|
6416
|
+
function expandEnumTypeForLiteralComparison(typeToExpand, comparisonType, concretizeTypeVars) {
|
|
6417
|
+
// Assignment checks apply this at each recursive assignType call so existing
|
|
6418
|
+
// variance and constraint handling remains intact. Keep this equivalence
|
|
6419
|
+
// relation aligned with the recursive normalization used by assert_type below.
|
|
6420
|
+
if (!containsTopLevelLiteralEnum(comparisonType)) {
|
|
6421
|
+
return typeToExpand;
|
|
6422
|
+
}
|
|
6423
|
+
const literalEnumClasses = collectLiteralEnumClasses(comparisonType);
|
|
6424
|
+
if (literalEnumClasses.length === 0) {
|
|
6425
|
+
return typeToExpand;
|
|
6426
|
+
}
|
|
6427
|
+
// Concretize top-level TypeVars only to probe for a matching enum subtype.
|
|
6428
|
+
// If no enum expansion actually occurs (for example, an unrelated source
|
|
6429
|
+
// TypeVar whose bound is not one of the comparison's enum classes), preserve
|
|
6430
|
+
// the original type rather than replacing the TypeVar with its bound. Doing so
|
|
6431
|
+
// keeps unrelated invariant comparisons like `list[T]` vs `list[ColorLiterals]`
|
|
6432
|
+
// unaffected.
|
|
6433
|
+
const concreteType = concretizeTypeVars ? makeTopLevelTypeVarsConcrete(typeToExpand) : typeToExpand;
|
|
6434
|
+
const expandedType = expandEnumTypeForLiteralClasses(concreteType, literalEnumClasses);
|
|
6435
|
+
return expandedType === concreteType ? typeToExpand : expandedType;
|
|
6436
|
+
}
|
|
6437
|
+
function containsTopLevelLiteralEnum(type) {
|
|
6438
|
+
if ((0, types_1.isClassInstance)(type) && types_1.ClassType.isEnumClass(type) && type.priv.literalValue instanceof types_1.EnumLiteral) {
|
|
6439
|
+
return true;
|
|
6440
|
+
}
|
|
6441
|
+
if (!(0, types_1.isUnion)(type)) {
|
|
6442
|
+
return false;
|
|
6443
|
+
}
|
|
6444
|
+
return type.priv.includesEnumLiteral;
|
|
6445
|
+
}
|
|
6446
|
+
function expandEnumTypeForLiteralClasses(typeToExpand, literalEnumClasses) {
|
|
6447
|
+
if (literalEnumClasses.length === 0) {
|
|
6448
|
+
return typeToExpand;
|
|
6449
|
+
}
|
|
6450
|
+
return (0, typeUtils_1.mapSubtypes)(typeToExpand, (subtype) => {
|
|
6451
|
+
if ((0, types_1.isClassInstance)(subtype) &&
|
|
6452
|
+
types_1.ClassType.isEnumClass(subtype) &&
|
|
6453
|
+
!types_1.ClassType.isEnumMemberSetMayBeIncomplete(subtype) &&
|
|
6454
|
+
subtype.priv.literalValue === undefined &&
|
|
6455
|
+
literalEnumClasses.some((enumClass) => types_1.ClassType.isSameGenericClass(enumClass, subtype))) {
|
|
6456
|
+
const literalTypes = (0, typeGuards_1.enumerateLiteralsForType)(evaluatorInterface, subtype);
|
|
6457
|
+
if (literalTypes && literalTypes.length > 0) {
|
|
6458
|
+
return (0, types_1.combineTypes)(literalTypes);
|
|
6459
|
+
}
|
|
6460
|
+
}
|
|
6461
|
+
return subtype;
|
|
6462
|
+
});
|
|
6463
|
+
}
|
|
6464
|
+
function collectLiteralEnumClasses(type, literalEnumClasses = [], recursively = false, recursionCount = 0) {
|
|
6465
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
6466
|
+
return literalEnumClasses;
|
|
6467
|
+
}
|
|
6468
|
+
recursionCount++;
|
|
6469
|
+
if (recursively && (0, types_1.isFunction)(type)) {
|
|
6470
|
+
type.shared.parameters.forEach((_, index) => collectLiteralEnumClasses(types_1.FunctionType.getParamType(type, index), literalEnumClasses, recursively, recursionCount));
|
|
6471
|
+
const returnType = types_1.FunctionType.getEffectiveReturnType(type);
|
|
6472
|
+
if (returnType) {
|
|
6473
|
+
collectLiteralEnumClasses(returnType, literalEnumClasses, recursively, recursionCount);
|
|
6474
|
+
}
|
|
6475
|
+
}
|
|
6476
|
+
else if (recursively && (0, types_1.isOverloaded)(type)) {
|
|
6477
|
+
types_1.OverloadedType.getOverloads(type).forEach((overload) => collectLiteralEnumClasses(overload, literalEnumClasses, recursively, recursionCount));
|
|
6478
|
+
const implementation = types_1.OverloadedType.getImplementation(type);
|
|
6479
|
+
if (implementation) {
|
|
6480
|
+
collectLiteralEnumClasses(implementation, literalEnumClasses, recursively, recursionCount);
|
|
6481
|
+
}
|
|
6482
|
+
}
|
|
6483
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
|
6484
|
+
if (!(0, types_1.isClass)(subtype)) {
|
|
6485
|
+
return;
|
|
6486
|
+
}
|
|
6487
|
+
if ((0, types_1.isClassInstance)(subtype) &&
|
|
6488
|
+
types_1.ClassType.isEnumClass(subtype) &&
|
|
6489
|
+
subtype.priv.literalValue instanceof types_1.EnumLiteral &&
|
|
6490
|
+
!literalEnumClasses.some((enumClass) => types_1.ClassType.isSameGenericClass(enumClass, subtype))) {
|
|
6491
|
+
literalEnumClasses.push(subtype);
|
|
6492
|
+
}
|
|
6493
|
+
if (recursively && subtype.priv.typeArgs) {
|
|
6494
|
+
if (subtype.priv.tupleTypeArgs) {
|
|
6495
|
+
subtype.priv.tupleTypeArgs.forEach((typeArg) => collectLiteralEnumClasses(typeArg.type, literalEnumClasses, recursively, recursionCount));
|
|
6496
|
+
}
|
|
6497
|
+
else {
|
|
6498
|
+
subtype.priv.typeArgs.forEach((typeArg) => collectLiteralEnumClasses(typeArg, literalEnumClasses, recursively, recursionCount));
|
|
6499
|
+
}
|
|
6500
|
+
}
|
|
6501
|
+
});
|
|
6502
|
+
return literalEnumClasses;
|
|
6503
|
+
}
|
|
6504
|
+
function normalizeEnumTypes(typeToNormalize, literalEnumClasses, recursionCount = 0) {
|
|
6505
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
6506
|
+
return typeToNormalize;
|
|
6507
|
+
}
|
|
6508
|
+
recursionCount++;
|
|
6509
|
+
typeToNormalize = expandEnumTypeForLiteralClasses(typeToNormalize, literalEnumClasses);
|
|
6510
|
+
if ((0, types_1.isUnion)(typeToNormalize)) {
|
|
6511
|
+
return (0, typeUtils_1.mapSubtypes)(typeToNormalize, (subtype) => normalizeEnumTypes(subtype, literalEnumClasses, recursionCount));
|
|
6512
|
+
}
|
|
6513
|
+
if ((0, types_1.isFunction)(typeToNormalize)) {
|
|
6514
|
+
let typeChanged = false;
|
|
6515
|
+
const parameterTypes = typeToNormalize.shared.parameters.map((_, index) => {
|
|
6516
|
+
const parameterType = types_1.FunctionType.getParamType(typeToNormalize, index);
|
|
6517
|
+
const normalizedType = normalizeEnumTypes(parameterType, literalEnumClasses, recursionCount);
|
|
6518
|
+
typeChanged || (typeChanged = normalizedType !== parameterType);
|
|
6519
|
+
return normalizedType;
|
|
6520
|
+
});
|
|
6521
|
+
const returnType = types_1.FunctionType.getEffectiveReturnType(typeToNormalize);
|
|
6522
|
+
const normalizedReturnType = returnType
|
|
6523
|
+
? normalizeEnumTypes(returnType, literalEnumClasses, recursionCount)
|
|
6524
|
+
: undefined;
|
|
6525
|
+
typeChanged || (typeChanged = normalizedReturnType !== returnType);
|
|
6526
|
+
return typeChanged
|
|
6527
|
+
? types_1.FunctionType.specialize(typeToNormalize, {
|
|
6528
|
+
parameterTypes,
|
|
6529
|
+
parameterDefaultTypes: typeToNormalize.priv.specializedTypes?.parameterDefaultTypes,
|
|
6530
|
+
returnType: normalizedReturnType,
|
|
6531
|
+
})
|
|
6532
|
+
: typeToNormalize;
|
|
6533
|
+
}
|
|
6534
|
+
if ((0, types_1.isOverloaded)(typeToNormalize)) {
|
|
6535
|
+
let typeChanged = false;
|
|
6536
|
+
const overloads = types_1.OverloadedType.getOverloads(typeToNormalize).map((overload) => {
|
|
6537
|
+
const normalizedType = normalizeEnumTypes(overload, literalEnumClasses, recursionCount);
|
|
6538
|
+
typeChanged || (typeChanged = normalizedType !== overload);
|
|
6539
|
+
return (0, types_1.isFunction)(normalizedType) ? normalizedType : overload;
|
|
6540
|
+
});
|
|
6541
|
+
const implementation = types_1.OverloadedType.getImplementation(typeToNormalize);
|
|
6542
|
+
const normalizedImplementation = implementation
|
|
6543
|
+
? normalizeEnumTypes(implementation, literalEnumClasses, recursionCount)
|
|
6544
|
+
: undefined;
|
|
6545
|
+
typeChanged || (typeChanged = normalizedImplementation !== implementation);
|
|
6546
|
+
return typeChanged ? types_1.OverloadedType.create(overloads, normalizedImplementation) : typeToNormalize;
|
|
6547
|
+
}
|
|
6548
|
+
if (!(0, types_1.isClass)(typeToNormalize) || !typeToNormalize.priv.typeArgs) {
|
|
6549
|
+
return typeToNormalize;
|
|
6550
|
+
}
|
|
6551
|
+
if (typeToNormalize.priv.tupleTypeArgs) {
|
|
6552
|
+
let typeChanged = false;
|
|
6553
|
+
const tupleTypeArgs = typeToNormalize.priv.tupleTypeArgs.map((typeArg) => {
|
|
6554
|
+
const normalizedType = normalizeEnumTypes(typeArg.type, literalEnumClasses, recursionCount);
|
|
6555
|
+
if (normalizedType !== typeArg.type) {
|
|
6556
|
+
typeChanged = true;
|
|
6557
|
+
}
|
|
6558
|
+
return { ...typeArg, type: normalizedType };
|
|
6559
|
+
});
|
|
6560
|
+
return typeChanged
|
|
6561
|
+
? (0, typeUtils_1.specializeTupleClass)(typeToNormalize, tupleTypeArgs, !!typeToNormalize.priv.isTypeArgExplicit, !!typeToNormalize.priv.isUnpacked)
|
|
6562
|
+
: typeToNormalize;
|
|
6563
|
+
}
|
|
6564
|
+
let typeChanged = false;
|
|
6565
|
+
const typeArgs = typeToNormalize.priv.typeArgs.map((typeArg) => {
|
|
6566
|
+
const normalizedType = normalizeEnumTypes(typeArg, literalEnumClasses, recursionCount);
|
|
6567
|
+
if (normalizedType !== typeArg) {
|
|
6568
|
+
typeChanged = true;
|
|
6569
|
+
}
|
|
6570
|
+
return normalizedType;
|
|
6571
|
+
});
|
|
6572
|
+
return typeChanged
|
|
6573
|
+
? types_1.ClassType.specialize(typeToNormalize, typeArgs, typeToNormalize.priv.isTypeArgExplicit)
|
|
6574
|
+
: typeToNormalize;
|
|
6575
|
+
}
|
|
6269
6576
|
function getTypeOfAssertType(node, inferenceContext) {
|
|
6270
6577
|
if (node.d.args.length !== 2 ||
|
|
6271
6578
|
node.d.args[0].d.argCategory !== 0 /* ArgCategory.Simple */ ||
|
|
@@ -6286,11 +6593,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6286
6593
|
// The spec is unclear on whether this is the correct behavior, but it seems to be
|
|
6287
6594
|
// what mypy does -- and what various library authors expect.
|
|
6288
6595
|
const arg0Type = stripTypeGuard(arg0TypeResult.type);
|
|
6289
|
-
|
|
6596
|
+
const typeSameOptions = {
|
|
6290
6597
|
treatAnySameAsUnknown: true,
|
|
6291
6598
|
ignorePseudoGeneric: true,
|
|
6292
6599
|
ignoreConditions: true,
|
|
6293
|
-
}
|
|
6600
|
+
};
|
|
6601
|
+
let typesMatch = (0, types_1.isTypeSame)(assertedType, arg0Type, typeSameOptions);
|
|
6602
|
+
if (!typesMatch) {
|
|
6603
|
+
// Unlike assignType, assert_type requires exact structural identity, so
|
|
6604
|
+
// normalize both types recursively. Keep this equivalence relation aligned
|
|
6605
|
+
// with expandEnumTypeForLiteralComparison, which assignType applies as it recurses.
|
|
6606
|
+
const literalEnumClasses = collectLiteralEnumClasses(assertedType, [], /* recursively */ true);
|
|
6607
|
+
collectLiteralEnumClasses(arg0Type, literalEnumClasses, /* recursively */ true);
|
|
6608
|
+
const normalizedAssertedType = normalizeEnumTypes(assertedType, literalEnumClasses);
|
|
6609
|
+
const normalizedArg0Type = normalizeEnumTypes(arg0Type, literalEnumClasses);
|
|
6610
|
+
typesMatch = (0, types_1.isTypeSame)(normalizedAssertedType, normalizedArg0Type, typeSameOptions);
|
|
6611
|
+
}
|
|
6612
|
+
if (!typesMatch) {
|
|
6294
6613
|
const srcDestTypes = printSrcDestTypes(arg0TypeResult.type, assertedType, { expandTypeAlias: true });
|
|
6295
6614
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportAssertTypeFailure, localize_1.LocMessage.assertTypeTypeMismatch().format({
|
|
6296
6615
|
expected: srcDestTypes.destType,
|
|
@@ -6672,13 +6991,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6672
6991
|
// list will grow to include union expansions.
|
|
6673
6992
|
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
6674
6993
|
const returnTypes = [];
|
|
6994
|
+
const specializedInitSelfTypes = [];
|
|
6675
6995
|
let matchedOverloads = [];
|
|
6676
6996
|
let isTypeIncomplete = false;
|
|
6677
|
-
|
|
6997
|
+
const overloadsUsedForCall = [];
|
|
6678
6998
|
let isDefinitiveMatchFound = false;
|
|
6999
|
+
let hasInitSelfMaterializationAmbiguity = false;
|
|
7000
|
+
let hasEffectiveInitSelfType = false;
|
|
6679
7001
|
const speculativeNode = getSpeculativeNodeForCall(errorNode);
|
|
6680
7002
|
for (let expandedTypesIndex = 0; expandedTypesIndex < expandedArgTypes.length; expandedTypesIndex++) {
|
|
7003
|
+
const overloadsUsedStartIndex = overloadsUsedForCall.length;
|
|
6681
7004
|
let matchedOverload;
|
|
7005
|
+
let effectiveInitSelfType;
|
|
6682
7006
|
const argTypeOverride = expandedArgTypes[expandedTypesIndex];
|
|
6683
7007
|
const hasArgTypeOverride = argTypeOverride.some((a) => a !== undefined);
|
|
6684
7008
|
let possibleMatchResults = [];
|
|
@@ -6718,9 +7042,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6718
7042
|
constraints: effectiveConstraints,
|
|
6719
7043
|
returnType: callResult.returnType,
|
|
6720
7044
|
argResults: callResult.argResults ?? [],
|
|
7045
|
+
specializedInitSelfType: callResult.specializedInitSelfType,
|
|
6721
7046
|
};
|
|
6722
7047
|
matchedOverloads.push(matchedOverloadInfo);
|
|
6723
|
-
if (callResult.anyOrUnknownArg ||
|
|
7048
|
+
if (callResult.anyOrUnknownArg ||
|
|
7049
|
+
matchResults.unpackedArgOfUnknownLength ||
|
|
7050
|
+
possibleMatchResults.length > 0) {
|
|
6724
7051
|
possibleMatchResults.push(matchedOverloadInfo);
|
|
6725
7052
|
if (callResult.anyOrUnknownArg) {
|
|
6726
7053
|
if ((0, typeUtils_1.isIncompleteUnknown)(callResult.anyOrUnknownArg)) {
|
|
@@ -6730,6 +7057,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6730
7057
|
}
|
|
6731
7058
|
else {
|
|
6732
7059
|
returnTypes.push(callResult.returnType);
|
|
7060
|
+
effectiveInitSelfType = getEffectiveInitSelfType(matchedOverloadInfo);
|
|
6733
7061
|
isDefinitiveMatchFound = true;
|
|
6734
7062
|
break;
|
|
6735
7063
|
}
|
|
@@ -6743,20 +7071,53 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6743
7071
|
if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
|
|
6744
7072
|
possibleMatchResults = filterOverloadMatchesForUnpackedArgs(possibleMatchResults);
|
|
6745
7073
|
possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
|
|
7074
|
+
// Keep diagnostic bookkeeping aligned with the candidates that remain possible.
|
|
7075
|
+
// This applies to both top-level gradual arguments and nested materialization,
|
|
7076
|
+
// so deprecation diagnostics are reported only for retained overloads.
|
|
7077
|
+
overloadsUsedForCall.splice(overloadsUsedStartIndex, overloadsUsedForCall.length - overloadsUsedStartIndex, ...possibleMatchResults.map((result) => result.overload));
|
|
6746
7078
|
// Did the filtering produce a single result? If so, we're done.
|
|
6747
7079
|
if (possibleMatchResults.length === 1) {
|
|
6748
|
-
overloadsUsedForCall = [possibleMatchResults[0].overload];
|
|
6749
7080
|
returnTypes.push(possibleMatchResults[0].returnType);
|
|
7081
|
+
effectiveInitSelfType = getEffectiveInitSelfType(possibleMatchResults[0]);
|
|
6750
7082
|
matchedOverloads = [possibleMatchResults[0]];
|
|
6751
7083
|
}
|
|
6752
7084
|
else {
|
|
7085
|
+
const firstArgParamPairs = getOverloadArgParamPairs(possibleMatchResults[0]);
|
|
7086
|
+
let ambiguousMatchIncludesNestedAny = false;
|
|
7087
|
+
let ambiguousMatchIncludesNestedUnknown = false;
|
|
7088
|
+
let ambiguousMatchIncludesTopLevelAnyOrUnknown = false;
|
|
7089
|
+
firstArgParamPairs.forEach((pair, index) => {
|
|
7090
|
+
const paramTypes = possibleMatchResults.map((match) => {
|
|
7091
|
+
const argParamPairs = getOverloadArgParamPairs(match);
|
|
7092
|
+
return index < argParamPairs.length ? argParamPairs[index].paramType : types_1.UnknownType.create();
|
|
7093
|
+
});
|
|
7094
|
+
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
|
7095
|
+
if ((0, types_1.isAnyOrUnknown)(pair.argType)) {
|
|
7096
|
+
ambiguousMatchIncludesTopLevelAnyOrUnknown = true;
|
|
7097
|
+
}
|
|
7098
|
+
else {
|
|
7099
|
+
const anyOrUnknown = getAnyOrUnknownInInvariantPosition(pair.argType);
|
|
7100
|
+
if (anyOrUnknown && (0, types_1.isAny)(anyOrUnknown)) {
|
|
7101
|
+
ambiguousMatchIncludesNestedAny = true;
|
|
7102
|
+
}
|
|
7103
|
+
else if (anyOrUnknown && (0, types_1.isUnknown)(anyOrUnknown)) {
|
|
7104
|
+
ambiguousMatchIncludesNestedUnknown = true;
|
|
7105
|
+
}
|
|
7106
|
+
}
|
|
7107
|
+
}
|
|
7108
|
+
});
|
|
6753
7109
|
// Eliminate any return types that are subsumed by other return types.
|
|
6754
7110
|
let dedupedMatchResults = [];
|
|
6755
7111
|
let dedupedResultsIncludeAny = false;
|
|
7112
|
+
const isInitSelfMaterializationAmbiguity = (ambiguousMatchIncludesNestedAny || ambiguousMatchIncludesNestedUnknown) &&
|
|
7113
|
+
possibleMatchResults.some((result) => !!result.specializedInitSelfType);
|
|
6756
7114
|
possibleMatchResults.forEach((result) => {
|
|
7115
|
+
const resultType = isInitSelfMaterializationAmbiguity
|
|
7116
|
+
? getEffectiveOverloadReturnType(result)
|
|
7117
|
+
: result.returnType;
|
|
6757
7118
|
let isSubtypeSubsumed = false;
|
|
6758
7119
|
for (let dedupedIndex = 0; dedupedIndex < dedupedMatchResults.length; dedupedIndex++) {
|
|
6759
|
-
if (assignType(dedupedMatchResults[dedupedIndex],
|
|
7120
|
+
if (assignType(dedupedMatchResults[dedupedIndex], resultType)) {
|
|
6760
7121
|
const anyOrUnknown = (0, typeUtils_1.containsAnyOrUnknown)(dedupedMatchResults[dedupedIndex],
|
|
6761
7122
|
/* recurse */ false);
|
|
6762
7123
|
if (!anyOrUnknown) {
|
|
@@ -6767,8 +7128,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6767
7128
|
}
|
|
6768
7129
|
break;
|
|
6769
7130
|
}
|
|
6770
|
-
else if (assignType(
|
|
6771
|
-
const anyOrUnknown = (0, typeUtils_1.containsAnyOrUnknown)(
|
|
7131
|
+
else if (assignType(resultType, dedupedMatchResults[dedupedIndex])) {
|
|
7132
|
+
const anyOrUnknown = (0, typeUtils_1.containsAnyOrUnknown)(resultType, /* recurse */ false);
|
|
6772
7133
|
if (!anyOrUnknown) {
|
|
6773
7134
|
dedupedMatchResults[dedupedIndex] = types_1.NeverType.createNever();
|
|
6774
7135
|
}
|
|
@@ -6779,13 +7140,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6779
7140
|
}
|
|
6780
7141
|
}
|
|
6781
7142
|
if (!isSubtypeSubsumed) {
|
|
6782
|
-
dedupedMatchResults.push(
|
|
7143
|
+
dedupedMatchResults.push(resultType);
|
|
6783
7144
|
}
|
|
6784
7145
|
});
|
|
6785
7146
|
dedupedMatchResults = dedupedMatchResults.filter((t) => !(0, types_1.isNever)(t));
|
|
6786
7147
|
const combinedTypes = (0, types_1.combineTypes)(dedupedMatchResults);
|
|
6787
7148
|
let returnType = combinedTypes;
|
|
6788
|
-
if (
|
|
7149
|
+
if (ambiguousMatchIncludesNestedUnknown) {
|
|
7150
|
+
returnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
|
7151
|
+
}
|
|
7152
|
+
else if (ambiguousMatchIncludesNestedAny && !ambiguousMatchIncludesTopLevelAnyOrUnknown) {
|
|
7153
|
+
returnType = types_1.AnyType.create();
|
|
7154
|
+
}
|
|
7155
|
+
else if (dedupedMatchResults.length > 1) {
|
|
6789
7156
|
// If one or more of the deduped types is Any or contains Any,
|
|
6790
7157
|
// we will assume that the person who defined the overload really
|
|
6791
7158
|
// wanted Any rather than Unknown. In cases where the deduped types
|
|
@@ -6798,13 +7165,33 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6798
7165
|
returnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
|
6799
7166
|
}
|
|
6800
7167
|
}
|
|
6801
|
-
|
|
7168
|
+
if (isInitSelfMaterializationAmbiguity) {
|
|
7169
|
+
// Overloaded __init__ methods normally return None. Preserve that
|
|
7170
|
+
// ordinary return as a placeholder while union-expanded calls are
|
|
7171
|
+
// combined, and carry the effective constructed types separately.
|
|
7172
|
+
// validateInitMethod consumes specializedInitSelfType to reconstruct
|
|
7173
|
+
// the constructor result after call validation is complete.
|
|
7174
|
+
effectiveInitSelfType = returnType;
|
|
7175
|
+
hasInitSelfMaterializationAmbiguity = true;
|
|
7176
|
+
returnTypes.push(possibleMatchResults[0].returnType);
|
|
7177
|
+
}
|
|
7178
|
+
else {
|
|
7179
|
+
returnTypes.push(returnType);
|
|
7180
|
+
}
|
|
6802
7181
|
}
|
|
6803
7182
|
}
|
|
7183
|
+
if (effectiveInitSelfType) {
|
|
7184
|
+
specializedInitSelfTypes.push(effectiveInitSelfType);
|
|
7185
|
+
hasEffectiveInitSelfType = true;
|
|
7186
|
+
}
|
|
6804
7187
|
if (!matchedOverload) {
|
|
6805
7188
|
return { argumentErrors: true, isTypeIncomplete, overloadsUsedForCall };
|
|
6806
7189
|
}
|
|
6807
7190
|
}
|
|
7191
|
+
// Union expansion requires one constructor handoff per expanded argument list.
|
|
7192
|
+
// Materialization ambiguity requires a combined handoff even when there is only
|
|
7193
|
+
// one argument list because multiple overload candidates contribute to its result.
|
|
7194
|
+
const shouldCombineInitSelfTypes = hasInitSelfMaterializationAmbiguity || (expandedArgTypes.length > 1 && hasEffectiveInitSelfType);
|
|
6808
7195
|
// We found a match for all of the expanded argument lists. Copy the
|
|
6809
7196
|
// resulting type var context back into the caller's type var context.
|
|
6810
7197
|
// Use the type var context from the last matched overload because it
|
|
@@ -6814,7 +7201,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6814
7201
|
}
|
|
6815
7202
|
// And run through the first expanded argument list one more time to
|
|
6816
7203
|
// populate the type cache.
|
|
6817
|
-
const finalConstraints =
|
|
7204
|
+
const finalConstraints = shouldCombineInitSelfTypes
|
|
7205
|
+
? matchedOverloads[0].constraints
|
|
7206
|
+
: constraints ?? matchedOverloads[0].constraints;
|
|
6818
7207
|
const finalCallResult = validateArgTypesWithContext(errorNode, matchedOverloads[0].matchResults, finalConstraints, skipUnknownArgCheck, inferenceContext);
|
|
6819
7208
|
if (finalCallResult.isTypeIncomplete) {
|
|
6820
7209
|
isTypeIncomplete = true;
|
|
@@ -6824,7 +7213,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6824
7213
|
anyOrUnknownArg: finalCallResult.anyOrUnknownArg,
|
|
6825
7214
|
returnType: (0, types_1.combineTypes)(returnTypes),
|
|
6826
7215
|
isTypeIncomplete,
|
|
6827
|
-
specializedInitSelfType:
|
|
7216
|
+
specializedInitSelfType: specializedInitSelfTypes.length > 0 && shouldCombineInitSelfTypes
|
|
7217
|
+
? (0, types_1.combineTypes)(specializedInitSelfTypes)
|
|
7218
|
+
: finalCallResult.specializedInitSelfType,
|
|
6828
7219
|
overloadsUsedForCall,
|
|
6829
7220
|
};
|
|
6830
7221
|
}
|
|
@@ -6842,28 +7233,303 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6842
7233
|
}
|
|
6843
7234
|
return unpackedArgsOverloads;
|
|
6844
7235
|
}
|
|
7236
|
+
// assignType cannot be used for this detection because it accepts Any and Unknown
|
|
7237
|
+
// without exposing whether acceptance depends on a gradual invariant type argument.
|
|
7238
|
+
function getAnyOrUnknownInInvariantPosition(type, recursionCount = 0) {
|
|
7239
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
7240
|
+
return undefined;
|
|
7241
|
+
}
|
|
7242
|
+
recursionCount++;
|
|
7243
|
+
let result;
|
|
7244
|
+
const addResult = (newResult) => {
|
|
7245
|
+
if (newResult) {
|
|
7246
|
+
result = result ? (0, typeUtils_1.preserveUnknown)(result, newResult) : newResult;
|
|
7247
|
+
}
|
|
7248
|
+
};
|
|
7249
|
+
if ((0, types_1.isUnion)(type)) {
|
|
7250
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
|
7251
|
+
addResult(getAnyOrUnknownInInvariantPosition(subtype, recursionCount));
|
|
7252
|
+
});
|
|
7253
|
+
return result;
|
|
7254
|
+
}
|
|
7255
|
+
if (!(0, types_1.isClass)(type)) {
|
|
7256
|
+
return undefined;
|
|
7257
|
+
}
|
|
7258
|
+
// Tuple entries are covariant, but they can contain an invariant type.
|
|
7259
|
+
if (type.priv.tupleTypeArgs) {
|
|
7260
|
+
type.priv.tupleTypeArgs.forEach((typeArg) => {
|
|
7261
|
+
addResult(getAnyOrUnknownInInvariantPosition(typeArg.type, recursionCount));
|
|
7262
|
+
});
|
|
7263
|
+
return result;
|
|
7264
|
+
}
|
|
7265
|
+
if (!type.priv.typeArgs) {
|
|
7266
|
+
return undefined;
|
|
7267
|
+
}
|
|
7268
|
+
inferVarianceForClass(type);
|
|
7269
|
+
const typeParams = types_1.ClassType.getTypeParams(type);
|
|
7270
|
+
type.priv.typeArgs.forEach((typeArg, index) => {
|
|
7271
|
+
const typeParam = index < typeParams.length ? typeParams[index] : undefined;
|
|
7272
|
+
const variance = typeParam ? types_1.TypeVarType.getVariance(typeParam) : 2 /* Variance.Invariant */;
|
|
7273
|
+
if (variance === 2 /* Variance.Invariant */) {
|
|
7274
|
+
addResult((0, typeUtils_1.containsAnyOrUnknown)(typeArg, /* recurse */ true));
|
|
7275
|
+
}
|
|
7276
|
+
else {
|
|
7277
|
+
addResult(getAnyOrUnknownInInvariantPosition(typeArg, recursionCount));
|
|
7278
|
+
}
|
|
7279
|
+
});
|
|
7280
|
+
return result;
|
|
7281
|
+
}
|
|
7282
|
+
function getEffectiveOverloadReturnType(match) {
|
|
7283
|
+
return getEffectiveInitSelfType(match) ?? match.returnType;
|
|
7284
|
+
}
|
|
7285
|
+
function getEffectiveInitSelfType(match) {
|
|
7286
|
+
if (match.specializedInitSelfType) {
|
|
7287
|
+
return match.specializedInitSelfType;
|
|
7288
|
+
}
|
|
7289
|
+
const boundToType = match.overload.priv.boundToType;
|
|
7290
|
+
if (match.overload.shared.name === '__init__' && boundToType && (0, types_1.isClassInstance)(boundToType)) {
|
|
7291
|
+
return solveAndApplyConstraints(boundToType, match.constraints, {
|
|
7292
|
+
replaceUnsolved: {
|
|
7293
|
+
scopeIds: (0, typeUtils_1.getTypeVarScopeIds)(boundToType),
|
|
7294
|
+
tupleClassType: getTupleClassType(),
|
|
7295
|
+
},
|
|
7296
|
+
});
|
|
7297
|
+
}
|
|
7298
|
+
return undefined;
|
|
7299
|
+
}
|
|
7300
|
+
function getOverloadArgParamPairs(match) {
|
|
7301
|
+
const pairs = [];
|
|
7302
|
+
// argResults and argParams share validation order: supplied arguments in caller
|
|
7303
|
+
// order, followed by synthesized defaults. Preserve that order so the same index
|
|
7304
|
+
// across overloads represents the same supplied argument, even for keyword calls.
|
|
7305
|
+
match.argResults.forEach((argResult, index) => {
|
|
7306
|
+
const argParam = index < match.matchResults.argParams.length ? match.matchResults.argParams[index] : undefined;
|
|
7307
|
+
if (!argParam?.isDefaultArg) {
|
|
7308
|
+
pairs.push({
|
|
7309
|
+
argType: argResult.argType,
|
|
7310
|
+
paramType: argParam?.paramType ?? types_1.UnknownType.create(),
|
|
7311
|
+
});
|
|
7312
|
+
}
|
|
7313
|
+
});
|
|
7314
|
+
if (match.overload.priv.boundToType && match.overload.priv.strippedFirstParamType) {
|
|
7315
|
+
pairs.unshift({
|
|
7316
|
+
argType: match.overload.priv.boundToType,
|
|
7317
|
+
paramType: match.overload.priv.strippedFirstParamType,
|
|
7318
|
+
});
|
|
7319
|
+
}
|
|
7320
|
+
return pairs;
|
|
7321
|
+
}
|
|
7322
|
+
function combineMaterializationCoverage(results) {
|
|
7323
|
+
if (results.some((result) => result === false)) {
|
|
7324
|
+
return false;
|
|
7325
|
+
}
|
|
7326
|
+
return results.some((result) => result === undefined) ? undefined : true;
|
|
7327
|
+
}
|
|
7328
|
+
function areAllMaterializationsEquivalent(destType, srcType, recursionCount = 0) {
|
|
7329
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
7330
|
+
return undefined;
|
|
7331
|
+
}
|
|
7332
|
+
recursionCount++;
|
|
7333
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(srcType, /* recurse */ true)) {
|
|
7334
|
+
return (0, types_1.isTypeSame)(destType, srcType, { treatAnySameAsUnknown: true });
|
|
7335
|
+
}
|
|
7336
|
+
if ((0, types_1.isAnyOrUnknown)(destType)) {
|
|
7337
|
+
return true;
|
|
7338
|
+
}
|
|
7339
|
+
if ((0, types_1.isTypeSame)(destType, srcType, { treatAnySameAsUnknown: true })) {
|
|
7340
|
+
return true;
|
|
7341
|
+
}
|
|
7342
|
+
if ((0, types_1.isTypeVar)(destType) ||
|
|
7343
|
+
(0, types_1.isUnion)(destType) ||
|
|
7344
|
+
(0, types_1.isFunction)(destType) ||
|
|
7345
|
+
(0, types_1.isOverloaded)(destType) ||
|
|
7346
|
+
((0, types_1.isClass)(destType) && types_1.ClassType.isProtocolClass(destType))) {
|
|
7347
|
+
return undefined;
|
|
7348
|
+
}
|
|
7349
|
+
if ((0, types_1.isAnyOrUnknown)(srcType)) {
|
|
7350
|
+
return false;
|
|
7351
|
+
}
|
|
7352
|
+
if ((0, types_1.isUnion)(srcType) || (0, types_1.isUnion)(destType) || (0, types_1.isFunction)(srcType) || (0, types_1.isFunction)(destType)) {
|
|
7353
|
+
return undefined;
|
|
7354
|
+
}
|
|
7355
|
+
if (!(0, types_1.isClass)(destType) || !(0, types_1.isClass)(srcType)) {
|
|
7356
|
+
return false;
|
|
7357
|
+
}
|
|
7358
|
+
if (!types_1.ClassType.isSameGenericClass(destType, srcType)) {
|
|
7359
|
+
return false;
|
|
7360
|
+
}
|
|
7361
|
+
if (destType.priv.tupleTypeArgs || srcType.priv.tupleTypeArgs) {
|
|
7362
|
+
const destTupleTypeArgs = destType.priv.tupleTypeArgs;
|
|
7363
|
+
const srcTupleTypeArgs = srcType.priv.tupleTypeArgs;
|
|
7364
|
+
if (!destTupleTypeArgs ||
|
|
7365
|
+
!srcTupleTypeArgs ||
|
|
7366
|
+
destTupleTypeArgs.length !== srcTupleTypeArgs.length ||
|
|
7367
|
+
destTupleTypeArgs.some((destTypeArg, index) => destTypeArg.isUnbounded !== srcTupleTypeArgs[index].isUnbounded)) {
|
|
7368
|
+
return false;
|
|
7369
|
+
}
|
|
7370
|
+
return combineMaterializationCoverage(srcTupleTypeArgs.map((srcTypeArg, index) => areAllMaterializationsEquivalent(destTupleTypeArgs[index].type, srcTypeArg.type, recursionCount)));
|
|
7371
|
+
}
|
|
7372
|
+
const destTypeArgs = destType.priv.typeArgs;
|
|
7373
|
+
const srcTypeArgs = srcType.priv.typeArgs;
|
|
7374
|
+
if (!destTypeArgs || !srcTypeArgs || destTypeArgs.length !== srcTypeArgs.length) {
|
|
7375
|
+
return false;
|
|
7376
|
+
}
|
|
7377
|
+
return combineMaterializationCoverage(srcTypeArgs.map((srcTypeArg, index) => areAllMaterializationsEquivalent(destTypeArgs[index], srcTypeArg, recursionCount)));
|
|
7378
|
+
}
|
|
7379
|
+
function areAllMaterializationsAssignable(destType, srcType, recursionCount = 0) {
|
|
7380
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
7381
|
+
return undefined;
|
|
7382
|
+
}
|
|
7383
|
+
recursionCount++;
|
|
7384
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(srcType, /* recurse */ true)) {
|
|
7385
|
+
return assignType(destType, srcType);
|
|
7386
|
+
}
|
|
7387
|
+
if ((0, types_1.isAnyOrUnknown)(destType)) {
|
|
7388
|
+
return true;
|
|
7389
|
+
}
|
|
7390
|
+
if ((0, types_1.isTypeSame)(destType, srcType, { treatAnySameAsUnknown: true })) {
|
|
7391
|
+
return true;
|
|
7392
|
+
}
|
|
7393
|
+
if ((0, types_1.isTypeVar)(destType) ||
|
|
7394
|
+
(0, types_1.isUnion)(destType) ||
|
|
7395
|
+
(0, types_1.isFunction)(destType) ||
|
|
7396
|
+
(0, types_1.isOverloaded)(destType) ||
|
|
7397
|
+
((0, types_1.isClass)(destType) && types_1.ClassType.isProtocolClass(destType))) {
|
|
7398
|
+
return undefined;
|
|
7399
|
+
}
|
|
7400
|
+
if ((0, types_1.isAnyOrUnknown)(srcType)) {
|
|
7401
|
+
return assignType(destType, getObjectType());
|
|
7402
|
+
}
|
|
7403
|
+
if ((0, types_1.isUnion)(srcType) ||
|
|
7404
|
+
(0, types_1.isUnion)(destType) ||
|
|
7405
|
+
(0, types_1.isFunction)(srcType) ||
|
|
7406
|
+
(0, types_1.isFunction)(destType) ||
|
|
7407
|
+
(0, types_1.isOverloaded)(srcType) ||
|
|
7408
|
+
(0, types_1.isOverloaded)(destType)) {
|
|
7409
|
+
return undefined;
|
|
7410
|
+
}
|
|
7411
|
+
if (!(0, types_1.isClass)(destType) || !(0, types_1.isClass)(srcType)) {
|
|
7412
|
+
return false;
|
|
7413
|
+
}
|
|
7414
|
+
if ((0, typeUtils_1.isTupleClass)(destType) && (0, typeUtils_1.isTupleClass)(srcType)) {
|
|
7415
|
+
const destTupleTypeArgs = destType.priv.tupleTypeArgs;
|
|
7416
|
+
const srcTupleTypeArgs = srcType.priv.tupleTypeArgs;
|
|
7417
|
+
if (!destTupleTypeArgs || !srcTupleTypeArgs) {
|
|
7418
|
+
return undefined;
|
|
7419
|
+
}
|
|
7420
|
+
if (destTupleTypeArgs.length === 1 && destTupleTypeArgs[0].isUnbounded) {
|
|
7421
|
+
return combineMaterializationCoverage(srcTupleTypeArgs.map((srcTypeArg) => areAllMaterializationsAssignable(destTupleTypeArgs[0].type, srcTypeArg.type, recursionCount)));
|
|
7422
|
+
}
|
|
7423
|
+
if (destTupleTypeArgs.length !== srcTupleTypeArgs.length ||
|
|
7424
|
+
destTupleTypeArgs.some((destTypeArg, index) => destTypeArg.isUnbounded !== srcTupleTypeArgs[index].isUnbounded)) {
|
|
7425
|
+
return false;
|
|
7426
|
+
}
|
|
7427
|
+
return combineMaterializationCoverage(srcTupleTypeArgs.map((srcTypeArg, index) => areAllMaterializationsAssignable(destTupleTypeArgs[index].type, srcTypeArg.type, recursionCount)));
|
|
7428
|
+
}
|
|
7429
|
+
let specializedSrcType;
|
|
7430
|
+
if (types_1.ClassType.isSameGenericClass(destType, srcType)) {
|
|
7431
|
+
specializedSrcType = srcType;
|
|
7432
|
+
}
|
|
7433
|
+
else {
|
|
7434
|
+
const instantiableDestType = (0, types_1.isClassInstance)(destType) ? types_1.ClassType.cloneAsInstantiable(destType) : destType;
|
|
7435
|
+
const baseClass = srcType.shared.mro.find((mroClass) => (0, types_1.isClass)(mroClass) && types_1.ClassType.isSameGenericClass(instantiableDestType, mroClass));
|
|
7436
|
+
if (baseClass && (0, types_1.isClass)(baseClass)) {
|
|
7437
|
+
specializedSrcType = (0, typeUtils_1.specializeForBaseClass)(srcType, baseClass);
|
|
7438
|
+
}
|
|
7439
|
+
}
|
|
7440
|
+
if (!specializedSrcType) {
|
|
7441
|
+
return types_1.ClassType.isBuiltIn(destType, 'object') ? true : undefined;
|
|
7442
|
+
}
|
|
7443
|
+
const typeParams = types_1.ClassType.getTypeParams(destType);
|
|
7444
|
+
if (typeParams.length === 0) {
|
|
7445
|
+
return true;
|
|
7446
|
+
}
|
|
7447
|
+
const destTypeArgs = destType.priv.typeArgs;
|
|
7448
|
+
const srcTypeArgs = specializedSrcType.priv.typeArgs;
|
|
7449
|
+
if (!destTypeArgs) {
|
|
7450
|
+
return true;
|
|
7451
|
+
}
|
|
7452
|
+
if (!srcTypeArgs) {
|
|
7453
|
+
return false;
|
|
7454
|
+
}
|
|
7455
|
+
inferVarianceForClass(destType);
|
|
7456
|
+
return combineMaterializationCoverage(srcTypeArgs.map((srcTypeArg, index) => {
|
|
7457
|
+
const destTypeArg = index < destTypeArgs.length ? destTypeArgs[index] : types_1.UnknownType.create();
|
|
7458
|
+
const typeParam = index < typeParams.length ? typeParams[index] : undefined;
|
|
7459
|
+
const variance = typeParam ? types_1.TypeVarType.getVariance(typeParam) : 2 /* Variance.Invariant */;
|
|
7460
|
+
if (variance === 3 /* Variance.Covariant */) {
|
|
7461
|
+
return areAllMaterializationsAssignable(destTypeArg, srcTypeArg, recursionCount);
|
|
7462
|
+
}
|
|
7463
|
+
if (variance === 2 /* Variance.Invariant */) {
|
|
7464
|
+
return areAllMaterializationsEquivalent(destTypeArg, srcTypeArg, recursionCount);
|
|
7465
|
+
}
|
|
7466
|
+
return undefined;
|
|
7467
|
+
}));
|
|
7468
|
+
}
|
|
6845
7469
|
// Determines whether multiple incompatible overloads match
|
|
6846
7470
|
// due to an Any or Unknown argument type.
|
|
6847
7471
|
function filterOverloadMatchesForAnyArgs(matches) {
|
|
6848
7472
|
if (matches.length < 2) {
|
|
6849
7473
|
return matches;
|
|
6850
7474
|
}
|
|
6851
|
-
|
|
6852
|
-
|
|
7475
|
+
let firstArgParamPairs = getOverloadArgParamPairs(matches[0]);
|
|
7476
|
+
const hasInvariantAnyOrUnknownArg = firstArgParamPairs.some((pair) => getAnyOrUnknownInInvariantPosition(pair.argType));
|
|
7477
|
+
// If all of the effective return types match, select the first one.
|
|
7478
|
+
if ((0, typeUtils_1.areTypesSame)(matches.map((match) => hasInvariantAnyOrUnknownArg ? getEffectiveOverloadReturnType(match) : match.returnType), { treatAnySameAsUnknown: true })) {
|
|
6853
7479
|
return [matches[0]];
|
|
6854
7480
|
}
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
7481
|
+
// Apply overload step 5 to arguments that contain a gradual type in an
|
|
7482
|
+
// invariant position. An overload that covers all materializations
|
|
7483
|
+
// eliminates only the overloads that follow it.
|
|
7484
|
+
if (hasInvariantAnyOrUnknownArg) {
|
|
7485
|
+
let materializationCheckSupported = true;
|
|
7486
|
+
for (let matchIndex = 0; matchIndex < matches.length; matchIndex++) {
|
|
7487
|
+
const argParamPairs = getOverloadArgParamPairs(matches[matchIndex]);
|
|
7488
|
+
const coverage = argParamPairs.length === firstArgParamPairs.length
|
|
7489
|
+
? combineMaterializationCoverage(argParamPairs.map((pair, index) => {
|
|
7490
|
+
const argType = firstArgParamPairs[index].argType;
|
|
7491
|
+
return areAllMaterializationsAssignable(pair.paramType, argType);
|
|
7492
|
+
}))
|
|
7493
|
+
: false;
|
|
7494
|
+
if (coverage === undefined) {
|
|
7495
|
+
materializationCheckSupported = false;
|
|
7496
|
+
break;
|
|
7497
|
+
}
|
|
7498
|
+
if (coverage) {
|
|
7499
|
+
matches = matches.slice(0, matchIndex + 1);
|
|
7500
|
+
break;
|
|
7501
|
+
}
|
|
7502
|
+
}
|
|
7503
|
+
if (materializationCheckSupported) {
|
|
7504
|
+
if (matches.length < 2) {
|
|
7505
|
+
return matches;
|
|
7506
|
+
}
|
|
7507
|
+
if ((0, typeUtils_1.areTypesSame)(matches.map((match) => getEffectiveOverloadReturnType(match)), { treatAnySameAsUnknown: true })) {
|
|
7508
|
+
return [matches[0]];
|
|
7509
|
+
}
|
|
7510
|
+
firstArgParamPairs = getOverloadArgParamPairs(matches[0]);
|
|
7511
|
+
for (let i = 0; i < firstArgParamPairs.length; i++) {
|
|
7512
|
+
if (getAnyOrUnknownInInvariantPosition(firstArgParamPairs[i].argType)) {
|
|
7513
|
+
const paramTypes = matches.map((match) => {
|
|
7514
|
+
const argParamPairs = getOverloadArgParamPairs(match);
|
|
7515
|
+
return i < argParamPairs.length ? argParamPairs[i].paramType : types_1.UnknownType.create();
|
|
7516
|
+
});
|
|
7517
|
+
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
|
7518
|
+
return matches;
|
|
7519
|
+
}
|
|
7520
|
+
}
|
|
7521
|
+
}
|
|
7522
|
+
}
|
|
6858
7523
|
}
|
|
6859
7524
|
let foundAmbiguousAnyArg = false;
|
|
6860
|
-
for (let i = 0; i <
|
|
7525
|
+
for (let i = 0; i < firstArgParamPairs.length; i++) {
|
|
6861
7526
|
// If the arg is Any or Unknown, see if the corresponding
|
|
6862
7527
|
// parameter types differ in any way.
|
|
6863
|
-
if ((0, types_1.isAnyOrUnknown)(
|
|
6864
|
-
const paramTypes = matches.map((match) =>
|
|
6865
|
-
|
|
6866
|
-
: types_1.UnknownType.create()
|
|
7528
|
+
if ((0, types_1.isAnyOrUnknown)(firstArgParamPairs[i].argType)) {
|
|
7529
|
+
const paramTypes = matches.map((match) => {
|
|
7530
|
+
const argParamPairs = getOverloadArgParamPairs(match);
|
|
7531
|
+
return i < argParamPairs.length ? argParamPairs[i].paramType : types_1.UnknownType.create();
|
|
7532
|
+
});
|
|
6867
7533
|
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
|
6868
7534
|
foundAmbiguousAnyArg = true;
|
|
6869
7535
|
}
|
|
@@ -6874,7 +7540,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6874
7540
|
// that one of the arguments is an unpacked iterator, and it maps to
|
|
6875
7541
|
// an indeterminate number of parameters, which means that the overload
|
|
6876
7542
|
// selection is ambiguous.
|
|
6877
|
-
if (foundAmbiguousAnyArg ||
|
|
7543
|
+
if (foundAmbiguousAnyArg ||
|
|
7544
|
+
matches.some((match) => getOverloadArgParamPairs(match).length !== firstArgParamPairs.length)) {
|
|
6878
7545
|
return matches;
|
|
6879
7546
|
}
|
|
6880
7547
|
return [matches[0]];
|
|
@@ -8628,7 +9295,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8628
9295
|
let argumentErrors = false;
|
|
8629
9296
|
let argumentMatchScore = 0;
|
|
8630
9297
|
let specializedInitSelfType;
|
|
8631
|
-
let anyOrUnknownArg
|
|
9298
|
+
let anyOrUnknownArg = type.priv.boundToType
|
|
9299
|
+
? getAnyOrUnknownInInvariantPosition(type.priv.boundToType)
|
|
9300
|
+
: undefined;
|
|
8632
9301
|
const speculativeNode = getSpeculativeNodeForCall(errorNode);
|
|
8633
9302
|
const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
|
|
8634
9303
|
const paramSpec = types_1.FunctionType.getParamSpecFromArgsKwargs(type);
|
|
@@ -8726,10 +9395,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8726
9395
|
if (argResult.condition) {
|
|
8727
9396
|
condition = types_1.TypeCondition.combine(condition, argResult.condition) ?? [];
|
|
8728
9397
|
}
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
9398
|
+
const argAnyOrUnknown = (0, types_1.isAnyOrUnknown)(argResult.argType)
|
|
9399
|
+
? argResult.argType
|
|
9400
|
+
: getAnyOrUnknownInInvariantPosition(argResult.argType);
|
|
9401
|
+
if (argAnyOrUnknown && !argParam.isDefaultArg) {
|
|
9402
|
+
anyOrUnknownArg = anyOrUnknownArg ? (0, typeUtils_1.preserveUnknown)(argAnyOrUnknown, anyOrUnknownArg) : argAnyOrUnknown;
|
|
8733
9403
|
}
|
|
8734
9404
|
if (paramSpec) {
|
|
8735
9405
|
if (argParam.argument.argCategory === 1 /* ArgCategory.UnpackedList */) {
|
|
@@ -11100,7 +11770,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11100
11770
|
// If no type arguments are provided, the resulting type
|
|
11101
11771
|
// depends on whether we're evaluating a type annotation or
|
|
11102
11772
|
// we're in some other context.
|
|
11103
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
11773
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11104
11774
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.optionalExtraArgs(), errorNode);
|
|
11105
11775
|
return types_1.UnknownType.create();
|
|
11106
11776
|
}
|
|
@@ -11170,7 +11840,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11170
11840
|
isValidTypeForm = false;
|
|
11171
11841
|
}
|
|
11172
11842
|
}
|
|
11173
|
-
else if (itemExpr.nodeType === 48 /* ParseNodeType.StringList */
|
|
11843
|
+
else if (itemExpr.nodeType === 48 /* ParseNodeType.StringList */ &&
|
|
11844
|
+
itemExpr.d.strings.every((stringNode) => stringNode.nodeType === 49 /* ParseNodeType.String */)) {
|
|
11174
11845
|
const isBytes = (itemExpr.d.strings[0].d.token.flags & 32 /* StringTokenFlags.Bytes */) !== 0;
|
|
11175
11846
|
const value = itemExpr.d.strings.map((s) => s.d.value).join('');
|
|
11176
11847
|
if (isBytes) {
|
|
@@ -11261,9 +11932,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11261
11932
|
}
|
|
11262
11933
|
// Creates a ClassVar type.
|
|
11263
11934
|
function createClassVarType(classType, errorNode, typeArgs, flags) {
|
|
11264
|
-
if (flags & 131072 /* EvalFlags.NoClassVar */) {
|
|
11935
|
+
if (flags & (131072 /* EvalFlags.NoClassVar */ | 1073741824 /* EvalFlags.TypeFormArg */)) {
|
|
11265
11936
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.classVarNotAllowed(), errorNode);
|
|
11266
|
-
return types_1.AnyType.create();
|
|
11937
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : types_1.AnyType.create();
|
|
11267
11938
|
}
|
|
11268
11939
|
if (!typeArgs) {
|
|
11269
11940
|
return classType;
|
|
@@ -11285,8 +11956,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11285
11956
|
return type;
|
|
11286
11957
|
}
|
|
11287
11958
|
function createTypeFormType(classType, errorNode, typeArgs) {
|
|
11288
|
-
if (!typeArgs
|
|
11289
|
-
|
|
11959
|
+
if (!typeArgs) {
|
|
11960
|
+
const specializedType = types_1.ClassType.specialize(classType, [types_1.AnyType.create()]);
|
|
11961
|
+
return types_1.TypeBase.cloneWithTypeForm(specializedType, types_1.ClassType.cloneAsInstance(specializedType));
|
|
11962
|
+
}
|
|
11963
|
+
if (typeArgs.length === 0) {
|
|
11964
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeArgsTooFew().format({
|
|
11965
|
+
name: classType.priv.aliasName || classType.shared.name,
|
|
11966
|
+
expected: 1,
|
|
11967
|
+
received: 0,
|
|
11968
|
+
}), errorNode);
|
|
11969
|
+
return types_1.UnknownType.create();
|
|
11290
11970
|
}
|
|
11291
11971
|
if (typeArgs.length > 1) {
|
|
11292
11972
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeArgsTooMany().format({
|
|
@@ -11309,10 +11989,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11309
11989
|
// depends on whether we're evaluating a type annotation or
|
|
11310
11990
|
// we're in some other context.
|
|
11311
11991
|
if (!typeArgs) {
|
|
11312
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
11992
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11313
11993
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeGuardArgCount(), errorNode);
|
|
11314
11994
|
}
|
|
11315
|
-
return classType;
|
|
11995
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11316
11996
|
}
|
|
11317
11997
|
else if (typeArgs.length !== 1) {
|
|
11318
11998
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeGuardArgCount(), errorNode);
|
|
@@ -11341,7 +12021,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11341
12021
|
}
|
|
11342
12022
|
const enclosingClassTypeResult = enclosingClass ? getTypeOfClass(enclosingClass) : undefined;
|
|
11343
12023
|
if (!enclosingClassTypeResult) {
|
|
11344
|
-
if ((flags & (256 /* EvalFlags.TypeExpression */ | 128 /* EvalFlags.InstantiableType */)) !== 0) {
|
|
12024
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 128 /* EvalFlags.InstantiableType */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11345
12025
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.selfTypeContext(), errorNode);
|
|
11346
12026
|
}
|
|
11347
12027
|
return types_1.UnknownType.create();
|
|
@@ -11393,18 +12073,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11393
12073
|
// If no type arguments are provided, the resulting type
|
|
11394
12074
|
// depends on whether we're evaluating a type annotation or
|
|
11395
12075
|
// we're in some other context.
|
|
11396
|
-
|
|
12076
|
+
const typeExpressionFlags = 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */;
|
|
12077
|
+
if (!typeArgs && (flags & typeExpressionFlags) === 0) {
|
|
11397
12078
|
return { type: classType };
|
|
11398
12079
|
}
|
|
11399
12080
|
if (!typeArgs || typeArgs.length !== 1) {
|
|
11400
|
-
if ((flags &
|
|
12081
|
+
if ((flags & typeExpressionFlags) !== 0) {
|
|
11401
12082
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, classType.shared.name === 'ReadOnly'
|
|
11402
12083
|
? localize_1.LocMessage.readOnlyArgCount()
|
|
11403
12084
|
: classType.shared.name === 'Required'
|
|
11404
12085
|
? localize_1.LocMessage.requiredArgCount()
|
|
11405
12086
|
: localize_1.LocMessage.notRequiredArgCount(), errorNode);
|
|
11406
12087
|
}
|
|
11407
|
-
return { type: classType };
|
|
12088
|
+
return { type: (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType };
|
|
11408
12089
|
}
|
|
11409
12090
|
const typeArgType = typeArgs[0].type;
|
|
11410
12091
|
// Make sure this is used only in a dataclass.
|
|
@@ -11444,23 +12125,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11444
12125
|
isNotRequired = classType.shared.name === 'NotRequired';
|
|
11445
12126
|
}
|
|
11446
12127
|
if (!isUsageLegal) {
|
|
11447
|
-
if ((flags &
|
|
12128
|
+
if ((flags & typeExpressionFlags) !== 0) {
|
|
11448
12129
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, classType.shared.name === 'ReadOnly'
|
|
11449
12130
|
? localize_1.LocMessage.readOnlyNotInTypedDict()
|
|
11450
12131
|
: classType.shared.name === 'Required'
|
|
11451
12132
|
? localize_1.LocMessage.requiredNotInTypedDict()
|
|
11452
12133
|
: localize_1.LocMessage.notRequiredNotInTypedDict(), errorNode);
|
|
11453
12134
|
}
|
|
11454
|
-
return { type: classType };
|
|
12135
|
+
return { type: (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType };
|
|
11455
12136
|
}
|
|
11456
12137
|
return { type: typeArgType, isReadOnly, isRequired, isNotRequired };
|
|
11457
12138
|
}
|
|
11458
12139
|
function createUnpackType(classType, errorNode, typeArgs, flags) {
|
|
11459
12140
|
if (!typeArgs || typeArgs.length !== 1) {
|
|
11460
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12141
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11461
12142
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.unpackArgCount(), errorNode);
|
|
11462
12143
|
}
|
|
11463
|
-
return classType;
|
|
12144
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11464
12145
|
}
|
|
11465
12146
|
const typeArgType = typeArgs[0].type;
|
|
11466
12147
|
if ((flags & 4194304 /* EvalFlags.AllowUnpackedTuple */) !== 0) {
|
|
@@ -11468,7 +12149,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11468
12149
|
if (unpackedType) {
|
|
11469
12150
|
return unpackedType;
|
|
11470
12151
|
}
|
|
11471
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0) {
|
|
12152
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) === 0) {
|
|
11472
12153
|
return classType;
|
|
11473
12154
|
}
|
|
11474
12155
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.unpackExpectedTypeVarTuple(), errorNode);
|
|
@@ -11484,19 +12165,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11484
12165
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.unpackExpectedTypedDict(), errorNode);
|
|
11485
12166
|
return types_1.UnknownType.create();
|
|
11486
12167
|
}
|
|
11487
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0) {
|
|
12168
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) === 0) {
|
|
11488
12169
|
return classType;
|
|
11489
12170
|
}
|
|
12171
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
12172
|
+
if ((0, types_1.isUnknown)(typeArgType)) {
|
|
12173
|
+
return typeArgType;
|
|
12174
|
+
}
|
|
12175
|
+
if ((0, types_1.isTypeVar)(typeArgType) && !typeArgType.priv.scopeId) {
|
|
12176
|
+
return types_1.UnknownType.create();
|
|
12177
|
+
}
|
|
12178
|
+
}
|
|
11490
12179
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.unpackNotAllowed(), errorNode);
|
|
11491
12180
|
return types_1.UnknownType.create();
|
|
11492
12181
|
}
|
|
11493
12182
|
// Creates a "Final" type.
|
|
11494
12183
|
function createFinalType(classType, errorNode, typeArgs, flags) {
|
|
11495
|
-
if (flags & 16 /* EvalFlags.NoFinal */) {
|
|
11496
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12184
|
+
if (flags & (16 /* EvalFlags.NoFinal */ | 1073741824 /* EvalFlags.TypeFormArg */)) {
|
|
12185
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11497
12186
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.finalContext(), errorNode);
|
|
11498
12187
|
}
|
|
11499
|
-
return classType;
|
|
12188
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11500
12189
|
}
|
|
11501
12190
|
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0 || !typeArgs || typeArgs.length === 0) {
|
|
11502
12191
|
return classType;
|
|
@@ -11508,10 +12197,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11508
12197
|
}
|
|
11509
12198
|
function createConcatenateType(classType, errorNode, typeArgs, flags) {
|
|
11510
12199
|
if ((flags & 134217728 /* EvalFlags.AllowConcatenate */) === 0) {
|
|
11511
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12200
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11512
12201
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.concatenateContext(), errorNode);
|
|
11513
12202
|
}
|
|
11514
|
-
return classType;
|
|
12203
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11515
12204
|
}
|
|
11516
12205
|
if (!typeArgs || typeArgs.length === 0) {
|
|
11517
12206
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.concatenateTypeArgsMissing(), errorNode);
|
|
@@ -11707,7 +12396,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11707
12396
|
// If no type arguments are provided, the resulting type
|
|
11708
12397
|
// depends on whether we're evaluating a type annotation or
|
|
11709
12398
|
// we're in some other context.
|
|
11710
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12399
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11711
12400
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.unionTypeArgCount(), errorNode);
|
|
11712
12401
|
return types_1.NeverType.createNever();
|
|
11713
12402
|
}
|
|
@@ -11741,7 +12430,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11741
12430
|
// is allowed if it's an unpacked TypeVarTuple or tuple. None is also allowed
|
|
11742
12431
|
// since it is used to define NoReturn in typeshed stubs).
|
|
11743
12432
|
if (types.length === 1 && !allowSingleTypeArg && !(0, typeUtils_1.isNoneInstance)(types[0])) {
|
|
11744
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12433
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11745
12434
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeArguments, localize_1.LocMessage.unionTypeArgCount(), errorNode);
|
|
11746
12435
|
}
|
|
11747
12436
|
isValidTypeForm = false;
|
|
@@ -11768,10 +12457,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11768
12457
|
// If no type arguments are provided, the resulting type
|
|
11769
12458
|
// depends on whether we're evaluating a type annotation or
|
|
11770
12459
|
// we're in some other context.
|
|
11771
|
-
if ((flags & (256 /* EvalFlags.TypeExpression */ | 262144 /* EvalFlags.NoNakedGeneric */)) !== 0) {
|
|
12460
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 262144 /* EvalFlags.NoNakedGeneric */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11772
12461
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.genericTypeArgMissing(), errorNode);
|
|
11773
12462
|
}
|
|
11774
|
-
return classType;
|
|
12463
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
12464
|
+
}
|
|
12465
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
12466
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.genericNotAllowed(), errorNode);
|
|
12467
|
+
return types_1.UnknownType.create();
|
|
11775
12468
|
}
|
|
11776
12469
|
const uniqueTypeVars = [];
|
|
11777
12470
|
if (typeArgs) {
|
|
@@ -12069,6 +12762,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12069
12762
|
}
|
|
12070
12763
|
return undefined;
|
|
12071
12764
|
}
|
|
12765
|
+
function cachedAssignmentTargetMayHaveDeclaredType(expression) {
|
|
12766
|
+
switch (expression.nodeType) {
|
|
12767
|
+
case 38 /* ParseNodeType.Name */: {
|
|
12768
|
+
const symbolWithScope = lookUpSymbolRecursive(expression, expression.d.value, /* honorCodeFlow */ true);
|
|
12769
|
+
return (!!symbolWithScope &&
|
|
12770
|
+
(symbolWithScope.symbol.hasTypedDeclarations() || symbolWithScope.scope.type === 3 /* ScopeType.Class */));
|
|
12771
|
+
}
|
|
12772
|
+
case 54 /* ParseNodeType.TypeAnnotation */:
|
|
12773
|
+
case 35 /* ParseNodeType.MemberAccess */:
|
|
12774
|
+
case 27 /* ParseNodeType.Index */:
|
|
12775
|
+
return true;
|
|
12776
|
+
case 52 /* ParseNodeType.Tuple */:
|
|
12777
|
+
return (expression.d.items.length > 0 &&
|
|
12778
|
+
!expression.d.items.some((item) => item.nodeType === 56 /* ParseNodeType.Unpack */) &&
|
|
12779
|
+
expression.d.items.every((item) => cachedAssignmentTargetMayHaveDeclaredType(item)));
|
|
12780
|
+
default:
|
|
12781
|
+
return false;
|
|
12782
|
+
}
|
|
12783
|
+
}
|
|
12072
12784
|
function evaluateTypesForAssignmentStatement(node) {
|
|
12073
12785
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
|
12074
12786
|
// If the entire statement has already been evaluated, don't
|
|
@@ -12092,6 +12804,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12092
12804
|
let rightHandType = readTypeCache(node.d.rightExpr, /* flags */ undefined);
|
|
12093
12805
|
let isIncomplete = false;
|
|
12094
12806
|
let expectedTypeDiagAddendum;
|
|
12807
|
+
let declaredType;
|
|
12808
|
+
let declaredTypeResolved = false;
|
|
12809
|
+
// A runtime-first query may have cached the RHS without its assignment
|
|
12810
|
+
// context. Re-evaluate it when the annotation expects a TypeForm so the
|
|
12811
|
+
// ordinary cache cannot suppress contextual validation and conversion.
|
|
12812
|
+
if (rightHandType && cachedAssignmentTargetMayHaveDeclaredType(node.d.leftExpr)) {
|
|
12813
|
+
declaredType = getDeclaredTypeForExpression(node.d.leftExpr, { method: 'set' });
|
|
12814
|
+
declaredTypeResolved = true;
|
|
12815
|
+
if (declaredType && expectedTypeWantsTypeForm(declaredType)) {
|
|
12816
|
+
rightHandType = undefined;
|
|
12817
|
+
}
|
|
12818
|
+
}
|
|
12095
12819
|
if (!rightHandType) {
|
|
12096
12820
|
// Special-case the typing.pyi file, which contains some special
|
|
12097
12821
|
// types that the type analyzer needs to interpret differently.
|
|
@@ -12146,7 +12870,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12146
12870
|
writeTypeCache(node.d.leftExpr.d.valueExpr, { type: typeAliasPlaceholder }, /* flags */ undefined);
|
|
12147
12871
|
}
|
|
12148
12872
|
}
|
|
12149
|
-
|
|
12873
|
+
if (!declaredTypeResolved) {
|
|
12874
|
+
declaredType = getDeclaredTypeForExpression(node.d.leftExpr, { method: 'set' });
|
|
12875
|
+
}
|
|
12150
12876
|
if (declaredType) {
|
|
12151
12877
|
const liveTypeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(node);
|
|
12152
12878
|
declaredType = (0, typeUtils_1.makeTypeVarsBound)(declaredType, liveTypeVarScopes);
|
|
@@ -12745,6 +13471,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12745
13471
|
if (slotsNames) {
|
|
12746
13472
|
classType.shared.localSlotsNames = slotsNames;
|
|
12747
13473
|
}
|
|
13474
|
+
classType.shared.hasNonEmptySlots = innerScope?.hasNonEmptySlots;
|
|
12748
13475
|
// Determine if the class should be a "pseudo-generic" class, characterized
|
|
12749
13476
|
// by having an __init__ method with parameters that lack type annotations.
|
|
12750
13477
|
// For such classes, we'll treat them as generic, with the type arguments provided
|
|
@@ -12814,6 +13541,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12814
13541
|
}
|
|
12815
13542
|
}
|
|
12816
13543
|
const effectiveMetaclass = computeEffectiveMetaclass(classType, node.d.name);
|
|
13544
|
+
const enumMemberSetMayBeDynamicallyModified = types_1.ClassType.isEnumClass(classType) &&
|
|
13545
|
+
(AnalyzerNodeInfo.getScope(node)?.hasPotentiallyDynamicSymbolTable ||
|
|
13546
|
+
classType.shared.mro.some((mroClass) => (0, types_1.isClass)(mroClass) && types_1.ClassType.isEnumMemberSetMayBeDynamicallyModified(mroClass)));
|
|
13547
|
+
if (enumMemberSetMayBeDynamicallyModified) {
|
|
13548
|
+
classType.shared.flags |= 67108864 /* ClassTypeFlags.EnumMemberSetMayBeDynamicallyModified */;
|
|
13549
|
+
}
|
|
13550
|
+
if (types_1.ClassType.isEnumClass(classType) &&
|
|
13551
|
+
(node.d.decorators.length > 0 ||
|
|
13552
|
+
enumMemberSetMayBeDynamicallyModified ||
|
|
13553
|
+
!(0, types_1.isInstantiableClass)(effectiveMetaclass) ||
|
|
13554
|
+
!types_1.ClassType.isBuiltIn(effectiveMetaclass, ['EnumMeta', 'EnumType']) ||
|
|
13555
|
+
classType.shared.mro.some((mroClass) => (0, types_1.isClass)(mroClass) &&
|
|
13556
|
+
(types_1.ClassType.isEnumMemberSetMayBeIncomplete(mroClass) ||
|
|
13557
|
+
(!types_1.ClassType.isBuiltIn(mroClass, 'Enum') &&
|
|
13558
|
+
types_1.ClassType.getSymbolTable(mroClass).has('_missing_')))))) {
|
|
13559
|
+
classType.shared.flags |= 33554432 /* ClassTypeFlags.EnumMemberSetMayBeIncomplete */;
|
|
13560
|
+
}
|
|
12817
13561
|
// Clear the "partially constructed" flag.
|
|
12818
13562
|
classType.shared.flags &= ~8192 /* ClassTypeFlags.PartiallyEvaluated */;
|
|
12819
13563
|
// Now determine the decorated type of the class.
|
|
@@ -12905,6 +13649,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12905
13649
|
synthesizeMethods();
|
|
12906
13650
|
}
|
|
12907
13651
|
else {
|
|
13652
|
+
if (types_1.ClassType.isDataClassGenerateSlots(classType)) {
|
|
13653
|
+
classType.shared.synthesizeDataClassSlotsDeferred = () => (0, dataClasses_1.synthesizeDataClassSlots)(evaluatorInterface, classType);
|
|
13654
|
+
}
|
|
12908
13655
|
classType.shared.synthesizeMethodsDeferred = () => {
|
|
12909
13656
|
delete classType.shared.synthesizeMethodsDeferred;
|
|
12910
13657
|
synthesizeMethods();
|
|
@@ -14998,9 +15745,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14998
15745
|
// within that tree. If the type cannot be determined (because it's part
|
|
14999
15746
|
// of a cyclical dependency), the function returns undefined.
|
|
15000
15747
|
function evaluateTypeForSubnode(subnode, callback) {
|
|
15748
|
+
return evaluateTypeForSubnodeWithCache(subnode, callback, readTypeCacheEntry);
|
|
15749
|
+
}
|
|
15750
|
+
function evaluateContextualTypeForSubnode(subnode, callback) {
|
|
15751
|
+
return evaluateTypeForSubnodeWithCache(subnode, callback, readContextualTypeCacheEntryForNode);
|
|
15752
|
+
}
|
|
15753
|
+
function evaluateTypeForSubnodeWithCache(subnode, callback, readCacheEntry) {
|
|
15001
15754
|
// If the type cache is already populated with a complete type,
|
|
15002
15755
|
// don't bother doing additional work.
|
|
15003
|
-
let cacheEntry =
|
|
15756
|
+
let cacheEntry = readCacheEntry(subnode);
|
|
15004
15757
|
if (cacheEntry && !cacheEntry.typeResult.isIncomplete) {
|
|
15005
15758
|
const typeResult = cacheEntry.typeResult;
|
|
15006
15759
|
// Handle the special case where a function or class is partially evaluated.
|
|
@@ -15014,7 +15767,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15014
15767
|
return typeResult;
|
|
15015
15768
|
}
|
|
15016
15769
|
callback();
|
|
15017
|
-
cacheEntry =
|
|
15770
|
+
cacheEntry = readCacheEntry(subnode);
|
|
15018
15771
|
if (cacheEntry) {
|
|
15019
15772
|
return cacheEntry.typeResult;
|
|
15020
15773
|
}
|
|
@@ -15128,7 +15881,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15128
15881
|
return { type: createClassVarType(classType, errorNode, typeArgs, flags) };
|
|
15129
15882
|
}
|
|
15130
15883
|
case 'Protocol': {
|
|
15131
|
-
if ((flags &
|
|
15884
|
+
if ((flags &
|
|
15885
|
+
(67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !==
|
|
15886
|
+
0) {
|
|
15132
15887
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.protocolNotAllowed(), errorNode);
|
|
15133
15888
|
}
|
|
15134
15889
|
typeArgs?.forEach((typeArg) => {
|
|
@@ -15143,7 +15898,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15143
15898
|
};
|
|
15144
15899
|
}
|
|
15145
15900
|
case 'TypedDict': {
|
|
15146
|
-
if ((flags &
|
|
15901
|
+
if ((flags &
|
|
15902
|
+
(67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !==
|
|
15903
|
+
0) {
|
|
15147
15904
|
const isInlinedTypedDict = AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.enableExperimentalFeatures &&
|
|
15148
15905
|
!!typeArgs;
|
|
15149
15906
|
if (!isInlinedTypedDict) {
|
|
@@ -15154,12 +15911,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15154
15911
|
break;
|
|
15155
15912
|
}
|
|
15156
15913
|
case 'Literal': {
|
|
15157
|
-
if ((flags &
|
|
15914
|
+
if ((flags &
|
|
15915
|
+
(67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !==
|
|
15916
|
+
0) {
|
|
15158
15917
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.literalNotAllowed(), errorNode);
|
|
15159
15918
|
}
|
|
15160
15919
|
isValidTypeForm = false;
|
|
15161
15920
|
break;
|
|
15162
15921
|
}
|
|
15922
|
+
case 'TypeAlias': {
|
|
15923
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
15924
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeAnnotationVariable(), errorNode);
|
|
15925
|
+
}
|
|
15926
|
+
isValidTypeForm = false;
|
|
15927
|
+
break;
|
|
15928
|
+
}
|
|
15163
15929
|
case 'Tuple': {
|
|
15164
15930
|
return {
|
|
15165
15931
|
type: createSpecialType(classType, typeArgs,
|
|
@@ -15269,7 +16035,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15269
16035
|
received: typeArgCount,
|
|
15270
16036
|
}), typeArgs[1].node);
|
|
15271
16037
|
}
|
|
15272
|
-
|
|
16038
|
+
let inlinedTypeDict = typeArgs[0].inlinedTypeDict;
|
|
16039
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
16040
|
+
inlinedTypeDict = types_1.TypeBase.cloneWithTypeForm(inlinedTypeDict, (0, typeUtils_1.convertToInstance)(inlinedTypeDict));
|
|
16041
|
+
}
|
|
16042
|
+
return { type: inlinedTypeDict };
|
|
15273
16043
|
}
|
|
15274
16044
|
else if (typeArgCount > typeParams.length) {
|
|
15275
16045
|
if (!types_1.ClassType.isPartiallyEvaluated(classType) && !types_1.ClassType.isTupleClass(classType)) {
|
|
@@ -15379,7 +16149,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15379
16149
|
return;
|
|
15380
16150
|
}
|
|
15381
16151
|
}
|
|
15382
|
-
const typeArgType = (
|
|
16152
|
+
const typeArgType = convertTypeArgToInstance(typeArgs[index].type, flags);
|
|
15383
16153
|
typeArgTypes.push(typeArgType);
|
|
15384
16154
|
constraints.setBounds(typeParam, typeArgType);
|
|
15385
16155
|
return;
|
|
@@ -17173,12 +17943,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17173
17943
|
// this function so we can analyze it separately without polluting
|
|
17174
17944
|
// the main type cache.
|
|
17175
17945
|
const prevTypeCache = returnTypeInferenceTypeCache;
|
|
17946
|
+
const prevTypeFormTypeCache = returnTypeInferenceTypeFormTypeCache;
|
|
17176
17947
|
returnTypeInferenceContextStack.push({
|
|
17177
17948
|
functionNode,
|
|
17178
17949
|
codeFlowAnalyzer: codeFlowEngine.createCodeFlowAnalyzer(),
|
|
17179
17950
|
});
|
|
17180
17951
|
try {
|
|
17181
17952
|
returnTypeInferenceTypeCache = new Map();
|
|
17953
|
+
returnTypeInferenceTypeFormTypeCache = new Map();
|
|
17182
17954
|
let allArgTypesAreUnknown = true;
|
|
17183
17955
|
functionNode.d.params.forEach((param, index) => {
|
|
17184
17956
|
if (param.d.name) {
|
|
@@ -17240,6 +18012,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17240
18012
|
finally {
|
|
17241
18013
|
returnTypeInferenceContextStack.pop();
|
|
17242
18014
|
returnTypeInferenceTypeCache = prevTypeCache;
|
|
18015
|
+
returnTypeInferenceTypeFormTypeCache = prevTypeFormTypeCache;
|
|
17243
18016
|
}
|
|
17244
18017
|
});
|
|
17245
18018
|
if (contextualReturnType) {
|
|
@@ -17386,6 +18159,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17386
18159
|
}
|
|
17387
18160
|
}
|
|
17388
18161
|
}
|
|
18162
|
+
// A class value normally remains unspecialized so it can be subscripted.
|
|
18163
|
+
// If every type parameter has an explicit default, apply those defaults
|
|
18164
|
+
// when comparing it against a type specialization. Classes with defaultless
|
|
18165
|
+
// parameters or defaults that resolve directly to Any or Unknown retain
|
|
18166
|
+
// their unspecialized behavior, so they don't degrade inference.
|
|
18167
|
+
if (types_1.TypeBase.isInstantiable(srcType) &&
|
|
18168
|
+
srcType.props?.typeForm &&
|
|
18169
|
+
!srcType.priv.typeArgs &&
|
|
18170
|
+
!srcType.priv.includeSubclasses &&
|
|
18171
|
+
srcType.shared.typeParams.length > 0 &&
|
|
18172
|
+
srcType.shared.typeParams.every((typeParam) => typeParam.shared.isDefaultExplicit)) {
|
|
18173
|
+
const specializedSrcType = (0, typeUtils_1.specializeWithDefaultTypeArgs)(srcType);
|
|
18174
|
+
const specializedTypeArgs = specializedSrcType.priv.typeArgs ??
|
|
18175
|
+
specializedSrcType.priv.tupleTypeArgs?.map((tupleTypeArg) => tupleTypeArg.type);
|
|
18176
|
+
const hasGradualTypeArg = specializedTypeArgs?.some((typeArg) => !!(0, typeUtils_1.containsAnyOrUnknown)(typeArg, /* recurse */ false) ||
|
|
18177
|
+
((0, types_1.isFunction)(typeArg) && types_1.FunctionType.isGradualCallableForm(typeArg)) ||
|
|
18178
|
+
((0, types_1.isUnpackedClass)(typeArg) && !!(0, typeUtils_1.containsAnyOrUnknown)(typeArg, /* recurse */ true)));
|
|
18179
|
+
if (hasGradualTypeArg === false) {
|
|
18180
|
+
srcType = specializedSrcType;
|
|
18181
|
+
}
|
|
18182
|
+
}
|
|
17389
18183
|
// Is it a structural type (i.e. a protocol)? If so, we need to
|
|
17390
18184
|
// perform a member-by-member check.
|
|
17391
18185
|
const inheritanceChain = [];
|
|
@@ -17778,6 +18572,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17778
18572
|
}
|
|
17779
18573
|
}
|
|
17780
18574
|
}
|
|
18575
|
+
// A subscripted runtime built-in such as list[int] is represented as its
|
|
18576
|
+
// precise class type, but it is also a types.GenericAlias object at runtime.
|
|
18577
|
+
if ((0, types_1.isClassInstance)(destType) &&
|
|
18578
|
+
types_1.ClassType.isBuiltIn(destType, 'GenericAlias') &&
|
|
18579
|
+
(0, types_1.isInstantiableClass)(srcType) &&
|
|
18580
|
+
!types_1.ClassType.isSpecialBuiltIn(srcType) &&
|
|
18581
|
+
!srcType.priv.aliasName &&
|
|
18582
|
+
srcType.shared.moduleName === 'builtins' &&
|
|
18583
|
+
srcType.priv.typeArgs !== undefined &&
|
|
18584
|
+
srcType.props?.typeForm &&
|
|
18585
|
+
classGetItemReturnsGenericAlias(srcType)) {
|
|
18586
|
+
return true;
|
|
18587
|
+
}
|
|
17781
18588
|
// If the source is a class-like type created by a call to NewType, treat it
|
|
17782
18589
|
// as a FunctionClass instance rather than an instantiable class for
|
|
17783
18590
|
// purposes of assignability. This reflects its actual runtime type.
|
|
@@ -17986,6 +18793,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17986
18793
|
}
|
|
17987
18794
|
return true;
|
|
17988
18795
|
}
|
|
18796
|
+
const isInvariant = (flags & 1 /* AssignTypeFlags.Invariant */) !== 0;
|
|
18797
|
+
srcType = expandEnumTypeForLiteralComparison(srcType, destType, /* concretizeTypeVars */ !isInvariant);
|
|
18798
|
+
if (isInvariant) {
|
|
18799
|
+
destType = expandEnumTypeForLiteralComparison(destType, srcType, /* concretizeTypeVars */ false);
|
|
18800
|
+
}
|
|
17989
18801
|
if ((0, types_1.isUnion)(destType)) {
|
|
17990
18802
|
// If both the source and dest are unions, use assignFromUnionType which has
|
|
17991
18803
|
// special-case logic to handle this case.
|
|
@@ -18094,7 +18906,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
18094
18906
|
if (types_1.ClassType.isBuiltIn(destType, 'TypeForm')) {
|
|
18095
18907
|
const destTypeArg = destType.priv.typeArgs && destType.priv.typeArgs.length > 0
|
|
18096
18908
|
? destType.priv.typeArgs[0]
|
|
18097
|
-
: types_1.
|
|
18909
|
+
: types_1.AnyType.create();
|
|
18098
18910
|
let srcTypeArg;
|
|
18099
18911
|
if ((0, types_1.isClassInstance)(concreteSrcType) && types_1.ClassType.isBuiltIn(concreteSrcType, 'type')) {
|
|
18100
18912
|
srcTypeArg = concreteSrcType;
|
|
@@ -18344,8 +19156,38 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
18344
19156
|
});
|
|
18345
19157
|
return isAssignable;
|
|
18346
19158
|
}
|
|
19159
|
+
function isTypeFormClass(type) {
|
|
19160
|
+
return (types_1.ClassType.isBuiltIn(type, 'TypeForm') ||
|
|
19161
|
+
(types_1.ClassType.isSpecialBuiltIn(type) &&
|
|
19162
|
+
(type.shared.name === 'TypeForm' || type.priv.aliasName === 'TypeForm')));
|
|
19163
|
+
}
|
|
19164
|
+
function isTypeFormType(type) {
|
|
19165
|
+
return (0, types_1.isClassInstance)(type) && isTypeFormClass(type);
|
|
19166
|
+
}
|
|
19167
|
+
function classGetItemReturnsGenericAlias(classType) {
|
|
19168
|
+
const member = (0, typeUtils_1.lookUpClassMember)(classType, '__class_getitem__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
|
|
19169
|
+
if (!member) {
|
|
19170
|
+
return false;
|
|
19171
|
+
}
|
|
19172
|
+
const memberType = getTypeOfMember(member);
|
|
19173
|
+
const functionReturnsGenericAlias = (functionType) => {
|
|
19174
|
+
const returnType = types_1.FunctionType.getEffectiveReturnType(functionType);
|
|
19175
|
+
return !!returnType && (0, types_1.isClassInstance)(returnType) && types_1.ClassType.isBuiltIn(returnType, 'GenericAlias');
|
|
19176
|
+
};
|
|
19177
|
+
if ((0, types_1.isFunction)(memberType)) {
|
|
19178
|
+
return functionReturnsGenericAlias(memberType);
|
|
19179
|
+
}
|
|
19180
|
+
if ((0, types_1.isOverloaded)(memberType)) {
|
|
19181
|
+
return types_1.OverloadedType.getOverloads(memberType).every(functionReturnsGenericAlias);
|
|
19182
|
+
}
|
|
19183
|
+
return false;
|
|
19184
|
+
}
|
|
19185
|
+
function expectedTypeRequiresTypeForm(expectedType) {
|
|
19186
|
+
return ((0, typeUtils_1.someSubtypes)(expectedType, isTypeFormType) &&
|
|
19187
|
+
!(0, typeUtils_1.someSubtypes)(expectedType, (subtype) => !isTypeFormType(subtype)));
|
|
19188
|
+
}
|
|
18347
19189
|
function expectedTypeWantsTypeForm(expectedType) {
|
|
18348
|
-
return (0, typeUtils_1.someSubtypes)(expectedType,
|
|
19190
|
+
return (0, typeUtils_1.someSubtypes)(expectedType, isTypeFormType);
|
|
18349
19191
|
}
|
|
18350
19192
|
// If the expected type is an explicit TypeForm type, see if the source
|
|
18351
19193
|
// type has an implicit TypeForm type that can be assigned to it. If so,
|
|
@@ -18386,9 +19228,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
18386
19228
|
if (resultType || !(0, types_1.isClassInstance)(subtype) || !types_1.ClassType.isBuiltIn(subtype, 'TypeForm')) {
|
|
18387
19229
|
return;
|
|
18388
19230
|
}
|
|
18389
|
-
const destTypeFormType = subtype.priv.typeArgs && subtype.priv.typeArgs.length > 0
|
|
18390
|
-
? subtype.priv.typeArgs[0]
|
|
18391
|
-
: types_1.UnknownType.create();
|
|
19231
|
+
const destTypeFormType = subtype.priv.typeArgs && subtype.priv.typeArgs.length > 0 ? subtype.priv.typeArgs[0] : types_1.AnyType.create();
|
|
18392
19232
|
if (assignType(destTypeFormType, srcTypeFormType)) {
|
|
18393
19233
|
resultType = types_1.ClassType.specialize(subtype, [srcTypeFormType]);
|
|
18394
19234
|
}
|
|
@@ -19657,6 +20497,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
19657
20497
|
if ((0, types_1.isUnknown)(assignedSubtype)) {
|
|
19658
20498
|
return assignedSubtype;
|
|
19659
20499
|
}
|
|
20500
|
+
// Preserve assignment narrowing when an enum literal is assigned
|
|
20501
|
+
// to its non-literal enum class. A single-member enum is equivalent
|
|
20502
|
+
// to its only literal, but the assigned value is still more precise.
|
|
20503
|
+
if ((0, types_1.isClassInstance)(assignedSubtype) &&
|
|
20504
|
+
assignedSubtype.priv.literalValue instanceof types_1.EnumLiteral &&
|
|
20505
|
+
(0, types_1.isClassInstance)(declaredSubtype) &&
|
|
20506
|
+
declaredSubtype.priv.literalValue === undefined &&
|
|
20507
|
+
types_1.ClassType.isSameGenericClass(assignedSubtype, declaredSubtype)) {
|
|
20508
|
+
return assignedSubtype;
|
|
20509
|
+
}
|
|
19660
20510
|
// If the two types are bidirectionally assignable, they are
|
|
19661
20511
|
// either equivalent (in which case it doesn't matter which
|
|
19662
20512
|
// one we choose) or one or both include gradual types (Any, etc.),
|