@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.
Files changed (56) hide show
  1. package/dist/analyzer/analyzerNodeInfo.d.ts +4 -1
  2. package/dist/analyzer/analyzerNodeInfo.js +13 -0
  3. package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
  4. package/dist/analyzer/binder.js +88 -1
  5. package/dist/analyzer/binder.js.map +1 -1
  6. package/dist/analyzer/checker.d.ts +1 -0
  7. package/dist/analyzer/checker.js +71 -15
  8. package/dist/analyzer/checker.js.map +1 -1
  9. package/dist/analyzer/constraintSolver.js +47 -7
  10. package/dist/analyzer/constraintSolver.js.map +1 -1
  11. package/dist/analyzer/constructors.js +18 -8
  12. package/dist/analyzer/constructors.js.map +1 -1
  13. package/dist/analyzer/dataClasses.d.ts +1 -0
  14. package/dist/analyzer/dataClasses.js +98 -19
  15. package/dist/analyzer/dataClasses.js.map +1 -1
  16. package/dist/analyzer/decorators.js +18 -0
  17. package/dist/analyzer/decorators.js.map +1 -1
  18. package/dist/analyzer/scope.d.ts +3 -0
  19. package/dist/analyzer/scope.js +10 -0
  20. package/dist/analyzer/scope.js.map +1 -1
  21. package/dist/analyzer/symbol.d.ts +4 -1
  22. package/dist/analyzer/symbol.js +8 -0
  23. package/dist/analyzer/symbol.js.map +1 -1
  24. package/dist/analyzer/typeCacheUtils.d.ts +6 -2
  25. package/dist/analyzer/typeCacheUtils.js +16 -37
  26. package/dist/analyzer/typeCacheUtils.js.map +1 -1
  27. package/dist/analyzer/typeEvaluator.js +955 -105
  28. package/dist/analyzer/typeEvaluator.js.map +1 -1
  29. package/dist/analyzer/typeGuards.js +11 -8
  30. package/dist/analyzer/typeGuards.js.map +1 -1
  31. package/dist/analyzer/types.d.ts +11 -1
  32. package/dist/analyzer/types.js +48 -0
  33. package/dist/analyzer/types.js.map +1 -1
  34. package/dist/localization/localize.d.ts +6 -0
  35. package/dist/localization/localize.js +4 -0
  36. package/dist/localization/localize.js.map +1 -1
  37. package/dist/localization/package.nls.en-us.json +13 -0
  38. package/dist/tests/typeCacheUtils.test.d.ts +1 -0
  39. package/dist/tests/typeCacheUtils.test.js +69 -0
  40. package/dist/tests/typeCacheUtils.test.js.map +1 -0
  41. package/dist/tests/typeEvaluator3.test.js +8 -0
  42. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  43. package/dist/tests/typeEvaluator5.test.js +12 -0
  44. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  45. package/dist/tests/typeEvaluator6.test.js +33 -1
  46. package/dist/tests/typeEvaluator6.test.js.map +1 -1
  47. package/dist/tests/typeEvaluator7.test.js +37 -0
  48. package/dist/tests/typeEvaluator7.test.js.map +1 -1
  49. package/dist/tests/typeEvaluator8.test.js +318 -4
  50. package/dist/tests/typeEvaluator8.test.js.map +1 -1
  51. package/dist/tests/types.test.d.ts +1 -0
  52. package/dist/tests/types.test.js +63 -0
  53. package/dist/tests/types.test.js.map +1 -0
  54. package/dist/typeServer/typeGuards.js +4 -3
  55. package/dist/typeServer/typeGuards.js.map +1 -1
  56. 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
- const cacheEntry = readTypeCacheEntry(node);
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
- if (!typeResult.isIncomplete) {
309
- incompleteGenCount++;
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 = evaluateTypeForSubnode(node, () => {
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 evaluateTypeForSubnode(node, () => {
499
+ return evaluateContextualTypeForSubnode(node, () => {
445
500
  evaluateTypesForExpressionInContext(node);
446
501
  });
447
502
  }
448
503
  function getTypeResultForDecorator(node) {
449
- return evaluateTypeForSubnode(node, () => {
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
- return readTypeCache(node, 0 /* EvalFlags.None */);
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 = readTypeCacheEntry(node);
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 = speculativeTypeTracker.getSpeculativeType(node, inferenceContext?.expectedType);
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 && (flags & 1073741824 /* EvalFlags.TypeFormArg */) === 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 = (0, typeUtils_1.convertToInstance)(typeArgs[index].type);
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
- if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
5477
- if ((flags & 32768 /* EvalFlags.VarTypeAnnotation */) === 0) {
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
- // If we have, this information will be cached.
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
- if (!isTypeCached(item.d.valueExpr)) {
5570
- getTypeOfExpression(item.d.valueExpr, flags & 4 /* EvalFlags.ForwardRefs */);
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 &= ~1073741824 /* EvalFlags.TypeFormArg */;
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
- if (!isCyclicalTypeVarCall) {
6333
+ const isTypeFormCall = (0, types_1.isInstantiableClass)(baseTypeResult.type) && isTypeFormClass(baseTypeResult.type);
6334
+ if (!isCyclicalTypeVarCall && !isTypeFormCall) {
6195
6335
  argList.forEach((arg) => {
6196
- if (arg.valueExpression &&
6197
- arg.valueExpression.nodeType !== 48 /* ParseNodeType.StringList */ &&
6198
- !isTypeCached(arg.valueExpression)) {
6199
- getTypeOfExpression(arg.valueExpression);
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
- if (!(0, types_1.isTypeSame)(assertedType, arg0Type, {
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
- let overloadsUsedForCall = [];
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 || matchResults.unpackedArgOfUnknownLength) {
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], result.returnType)) {
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(result.returnType, dedupedMatchResults[dedupedIndex])) {
6771
- const anyOrUnknown = (0, typeUtils_1.containsAnyOrUnknown)(result.returnType, /* recurse */ false);
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(result.returnType);
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 (dedupedMatchResults.length > 1) {
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
- returnTypes.push(returnType);
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 = constraints ?? matchedOverloads[0].constraints;
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: finalCallResult.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
- // If all of the return types match, select the first one.
6852
- if ((0, typeUtils_1.areTypesSame)(matches.map((match) => match.returnType), { treatAnySameAsUnknown: true })) {
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
- const firstArgResults = matches[0].argResults;
6856
- if (!firstArgResults) {
6857
- return matches;
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 < firstArgResults.length; 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)(firstArgResults[i].argType)) {
6864
- const paramTypes = matches.map((match) => i < match.matchResults.argParams.length
6865
- ? match.matchResults.argParams[i].paramType
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 || matches.some((match) => match.argResults.length !== firstArgResults.length)) {
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
- if ((0, types_1.isAnyOrUnknown)(argResult.argType)) {
8730
- anyOrUnknownArg = anyOrUnknownArg
8731
- ? (0, typeUtils_1.preserveUnknown)(argResult.argType, anyOrUnknownArg)
8732
- : argResult.argType;
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 || typeArgs.length === 0) {
11289
- return types_1.ClassType.specialize(classType, [types_1.UnknownType.create()]);
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
- if (!typeArgs && (flags & 256 /* EvalFlags.TypeExpression */) === 0) {
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 & 256 /* EvalFlags.TypeExpression */) !== 0) {
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 & 256 /* EvalFlags.TypeExpression */) !== 0) {
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
- let declaredType = getDeclaredTypeForExpression(node.d.leftExpr, { method: 'set' });
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 = readTypeCacheEntry(subnode);
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 = readTypeCacheEntry(subnode);
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 & (67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */)) !== 0) {
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 & (67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */)) !== 0) {
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 & (67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */)) !== 0) {
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
- return { type: typeArgs[0].inlinedTypeDict };
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 = (0, typeUtils_1.convertToInstance)(typeArgs[index].type);
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.UnknownType.create();
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, (subtype) => (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'TypeForm'));
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.),