@zzzen/pyright-internal 1.2.0-dev.20261004 → 1.2.0-dev.20261018

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/analyzer/binder.js +8 -0
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +0 -1
  4. package/dist/analyzer/checker.js +21 -42
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/codeFlowEngine.js +75 -28
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/constraintSolver.js +3 -2
  9. package/dist/analyzer/constraintSolver.js.map +1 -1
  10. package/dist/analyzer/operations.d.ts +2 -0
  11. package/dist/analyzer/operations.js +2 -1
  12. package/dist/analyzer/operations.js.map +1 -1
  13. package/dist/analyzer/overloadResultAdmission.js +115 -3
  14. package/dist/analyzer/overloadResultAdmission.js.map +1 -1
  15. package/dist/analyzer/overloadResultController.js +36 -10
  16. package/dist/analyzer/overloadResultController.js.map +1 -1
  17. package/dist/analyzer/overloadResultSelector.js +32 -12
  18. package/dist/analyzer/overloadResultSelector.js.map +1 -1
  19. package/dist/analyzer/parameterUtils.js +2 -1
  20. package/dist/analyzer/parameterUtils.js.map +1 -1
  21. package/dist/analyzer/parseTreeUtils.d.ts +1 -0
  22. package/dist/analyzer/parseTreeUtils.js +13 -0
  23. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  24. package/dist/analyzer/patternMatching.js +105 -35
  25. package/dist/analyzer/patternMatching.js.map +1 -1
  26. package/dist/analyzer/program.d.ts +3 -0
  27. package/dist/analyzer/program.js +34 -9
  28. package/dist/analyzer/program.js.map +1 -1
  29. package/dist/analyzer/properties.d.ts +2 -2
  30. package/dist/analyzer/properties.js +2 -2
  31. package/dist/analyzer/properties.js.map +1 -1
  32. package/dist/analyzer/protocols.d.ts +3 -1
  33. package/dist/analyzer/protocols.js +24 -2
  34. package/dist/analyzer/protocols.js.map +1 -1
  35. package/dist/analyzer/service.js +6 -2
  36. package/dist/analyzer/service.js.map +1 -1
  37. package/dist/analyzer/sourceEnumerator.d.ts +3 -1
  38. package/dist/analyzer/sourceEnumerator.js +30 -11
  39. package/dist/analyzer/sourceEnumerator.js.map +1 -1
  40. package/dist/analyzer/sourceMapper.d.ts +1 -0
  41. package/dist/analyzer/sourceMapper.js +10 -4
  42. package/dist/analyzer/sourceMapper.js.map +1 -1
  43. package/dist/analyzer/tuples.js +17 -6
  44. package/dist/analyzer/tuples.js.map +1 -1
  45. package/dist/analyzer/typeEvaluator.js +419 -67
  46. package/dist/analyzer/typeEvaluator.js.map +1 -1
  47. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
  48. package/dist/analyzer/typeEvaluatorTypes.js +4 -0
  49. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  50. package/dist/analyzer/typeGuards.d.ts +5 -1
  51. package/dist/analyzer/typeGuards.js +324 -99
  52. package/dist/analyzer/typeGuards.js.map +1 -1
  53. package/dist/analyzer/typePrinter.js +32 -6
  54. package/dist/analyzer/typePrinter.js.map +1 -1
  55. package/dist/analyzer/typeStubRenderer.d.ts +6 -1
  56. package/dist/analyzer/typeStubRenderer.js +19 -12
  57. package/dist/analyzer/typeStubRenderer.js.map +1 -1
  58. package/dist/analyzer/typeUtils.d.ts +1 -0
  59. package/dist/analyzer/typeUtils.js +15 -1
  60. package/dist/analyzer/typeUtils.js.map +1 -1
  61. package/dist/analyzer/typedDicts.d.ts +2 -1
  62. package/dist/analyzer/typedDicts.js +49 -10
  63. package/dist/analyzer/typedDicts.js.map +1 -1
  64. package/dist/analyzer/types.d.ts +2 -1
  65. package/dist/analyzer/types.js +9 -0
  66. package/dist/analyzer/types.js.map +1 -1
  67. package/dist/common/configOptions.d.ts +1 -0
  68. package/dist/common/configOptions.js +9 -0
  69. package/dist/common/configOptions.js.map +1 -1
  70. package/dist/common/windowsProcessTree.json +252 -33
  71. package/dist/tests/cacheManager.test.js +19 -15
  72. package/dist/tests/cacheManager.test.js.map +1 -1
  73. package/dist/tests/checker.test.js +50 -0
  74. package/dist/tests/checker.test.js.map +1 -1
  75. package/dist/tests/config.test.js +126 -0
  76. package/dist/tests/config.test.js.map +1 -1
  77. package/dist/tests/constraintSolver.test.d.ts +1 -0
  78. package/dist/tests/constraintSolver.test.js +39 -0
  79. package/dist/tests/constraintSolver.test.js.map +1 -0
  80. package/dist/tests/fourslash/hover.typedDict.get.fourslash.js +11 -0
  81. package/dist/tests/fourslash/hover.typedDict.get.fourslash.js.map +1 -1
  82. package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.d.ts +1 -0
  83. package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js +16 -0
  84. package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js.map +1 -0
  85. package/dist/tests/mypyPrimerAnalysis.test.js +67 -11
  86. package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
  87. package/dist/tests/overloadResultController.test.js +379 -1
  88. package/dist/tests/overloadResultController.test.js.map +1 -1
  89. package/dist/tests/signatureHelp.test.js +34 -0
  90. package/dist/tests/signatureHelp.test.js.map +1 -1
  91. package/dist/tests/sourceEnumeratorSymlink.test.js +98 -13
  92. package/dist/tests/sourceEnumeratorSymlink.test.js.map +1 -1
  93. package/dist/tests/sourceMapperUtils.test.js +143 -0
  94. package/dist/tests/sourceMapperUtils.test.js.map +1 -1
  95. package/dist/tests/typeEquality.test.js +85 -2
  96. package/dist/tests/typeEquality.test.js.map +1 -1
  97. package/dist/tests/typeEvaluator1.test.js +47 -3
  98. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  99. package/dist/tests/typeEvaluator3.test.js +23 -0
  100. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  101. package/dist/tests/typeEvaluator5.test.js +1 -1
  102. package/dist/tests/typeEvaluator6.test.js +83 -1
  103. package/dist/tests/typeEvaluator6.test.js.map +1 -1
  104. package/dist/tests/typeEvaluator7.test.js +32 -0
  105. package/dist/tests/typeEvaluator7.test.js.map +1 -1
  106. package/dist/tests/typeEvaluator8.test.js +15 -1
  107. package/dist/tests/typeEvaluator8.test.js.map +1 -1
  108. package/package.json +3 -3
@@ -332,7 +332,8 @@ export declare const enum AssignTypeFlags {
332
332
  AllowIsinstanceSpecialForms = 16384,
333
333
  SkipSelfClsParamCheck = 32768,
334
334
  AllowProtocolClassSource = 65536,
335
- DisallowExtraKwargsForTd = 131072
335
+ DisallowExtraKwargsForTd = 131072,
336
+ RejectCyclicLowerBound = 262144
336
337
  }
337
338
  export interface TypeEvaluator {
338
339
  runWithCancellationToken<T>(token: CancellationToken, callback: () => T): T;
@@ -197,5 +197,9 @@ var AssignTypeFlags;
197
197
  // When assigning callables, should a kwargs with an unpacked TypedDict
198
198
  // disallow additional named arguments if it does not have extraItems?
199
199
  AssignTypeFlags[AssignTypeFlags["DisallowExtraKwargsForTd"] = 131072] = "DisallowExtraKwargsForTd";
200
+ // Reject a cyclic TypeVar lower bound even when no constraint tracker
201
+ // records it. Overload consistency validation uses this when comparing
202
+ // return types.
203
+ AssignTypeFlags[AssignTypeFlags["RejectCyclicLowerBound"] = 262144] = "RejectCyclicLowerBound";
200
204
  })(AssignTypeFlags || (exports.AssignTypeFlags = AssignTypeFlags = {}));
201
205
  //# sourceMappingURL=typeEvaluatorTypes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"typeEvaluatorTypes.js","sourceRoot":"","sources":["../../../../../src/analyzer/typeEvaluatorTypes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typeEvaluatorTypes.js","sourceRoot":"","sources":["../../../../../src/analyzer/typeEvaluatorTypes.ts"],"names":[],"mappings":"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"}
@@ -6,9 +6,13 @@ export interface TypeNarrowingResult {
6
6
  type: Type;
7
7
  isIncomplete: boolean;
8
8
  }
9
+ export interface IsInstanceClassTypeInfo {
10
+ classTypes: (ClassType | TypeVarType | FunctionType)[];
11
+ negativeClassTypes: (ClassType | TypeVarType | FunctionType)[];
12
+ }
9
13
  export type TypeNarrowingCallback = (type: Type) => TypeNarrowingResult | undefined;
10
14
  export declare function getTypeNarrowingCallback(evaluator: TypeEvaluator, reference: ExpressionNode, testExpression: ExpressionNode, isPositiveTest: boolean, nodeInfo: AnalyzerNodeInfoAccessor, recursionCount?: number): TypeNarrowingCallback | undefined;
11
- export declare function getIsInstanceClassTypes(evaluator: TypeEvaluator, argType: Type): (ClassType | TypeVarType | FunctionType)[] | undefined;
15
+ export declare function getIsInstanceClassTypes(evaluator: TypeEvaluator, argType: Type, argExpr: ExpressionNode): IsInstanceClassTypeInfo | undefined;
12
16
  export declare function narrowTypeForInstanceOrSubclass(evaluator: TypeEvaluator, type: Type, filterTypes: Type[], isInstanceCheck: boolean, isTypeIsCheck: boolean, isPositiveTest: boolean, errorNode: ExpressionNode, nodeInfo: AnalyzerNodeInfoAccessor): import("./types").UnboundType | UnknownType | AnyType | FunctionType | OverloadedType | ClassType | import("./types").ModuleType | TypeVarType | import("./types").OverloadResultType | import("./types").NeverType | import("./types").UnionType;
13
17
  export declare function getElementTypeForContainerNarrowing(containerType: Type): Type | undefined;
14
18
  export declare function narrowTypeForContainerElementType(evaluator: TypeEvaluator, referenceType: Type, elementType: Type): Type;
@@ -58,6 +58,8 @@ const analyzerNodeInfo_1 = require("./analyzerNodeInfo");
58
58
  const constraintSolver_1 = require("./constraintSolver");
59
59
  const constraintTracker_1 = require("./constraintTracker");
60
60
  const enums_1 = require("./enums");
61
+ const operations_1 = require("./operations");
62
+ const parameterUtils_1 = require("./parameterUtils");
61
63
  const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
62
64
  const scopeUtils_1 = require("./scopeUtils");
63
65
  const symbol_1 = require("./symbol");
@@ -250,6 +252,16 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
250
252
  };
251
253
  };
252
254
  }
255
+ // Look for X == <class> or X != <class>.
256
+ if ((0, types_1.isInstantiableClass)(rightType)) {
257
+ return (type) => {
258
+ return {
259
+ type: narrowTypeForClassComparison(evaluator, type, rightType, adjIsPositiveTest,
260
+ /* isIsOperator */ false),
261
+ isIncomplete: !!rightTypeResult.isIncomplete,
262
+ };
263
+ };
264
+ }
253
265
  }
254
266
  // Look for X[<literal>] == <literal> or X[<literal>] != <literal>
255
267
  if (testExpression.d.leftExpr.nodeType === 27 /* ParseNodeType.Index */ &&
@@ -416,9 +428,12 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
416
428
  const isInstanceCheck = types_1.FunctionType.isBuiltIn(callType, 'isinstance');
417
429
  const arg1TypeResult = evaluator.getTypeOfExpression(arg1Expr, 536871546 /* EvalFlags.IsInstanceArgDefaults */);
418
430
  const arg1Type = arg1TypeResult.type;
419
- const classTypeList = getIsInstanceClassTypes(evaluator, arg1Type);
431
+ const classTypeInfo = getIsInstanceClassTypes(evaluator, arg1Type, arg1Expr);
420
432
  const isIncomplete = !!callTypeResult.isIncomplete || !!arg1TypeResult.isIncomplete;
421
- if (classTypeList) {
433
+ if (classTypeInfo) {
434
+ const classTypeList = isPositiveTest
435
+ ? classTypeInfo.classTypes
436
+ : classTypeInfo.negativeClassTypes;
422
437
  return (type) => {
423
438
  return {
424
439
  type: narrowTypeForInstanceOrSubclass(evaluator, type, classTypeList, isInstanceCheck,
@@ -456,82 +471,155 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
456
471
  }
457
472
  }
458
473
  // Look for a TypeGuard function.
459
- if (testExpression.d.args.length >= 1) {
460
- const arg0Expr = testExpression.d.args[0].d.valueExpr;
461
- if (isMatchingExpressionOrWalrusRhs(evaluator, reference, arg0Expr)) {
462
- // Does this look like it's a custom type guard function?
463
- let isPossiblyTypeGuard = false;
464
- const isFunctionReturnTypeGuard = (type) => {
465
- const returnType = type.shared.declaredReturnType;
466
- if (!returnType) {
467
- return false;
468
- }
469
- if ((0, types_1.isClassInstance)(returnType)) {
470
- return types_1.ClassType.isBuiltIn(returnType, ['TypeGuard', 'TypeIs']);
474
+ const isFunctionReturnTypeGuard = (type) => {
475
+ const returnType = type.shared.declaredReturnType;
476
+ if (!returnType) {
477
+ return false;
478
+ }
479
+ if ((0, types_1.isClassInstance)(returnType)) {
480
+ return types_1.ClassType.isBuiltIn(returnType, ['TypeGuard', 'TypeIs']);
481
+ }
482
+ if ((0, types_1.isUnion)(returnType)) {
483
+ let isAllGuards = true;
484
+ (0, typeUtils_1.doForEachSubtype)(returnType, (subtype) => {
485
+ if (!(0, types_1.isClassInstance)(subtype) || !types_1.ClassType.isBuiltIn(subtype, ['TypeGuard', 'TypeIs'])) {
486
+ isAllGuards = false;
471
487
  }
472
- if ((0, types_1.isUnion)(returnType)) {
473
- let isAllGuards = true;
474
- (0, typeUtils_1.doForEachSubtype)(returnType, (subtype) => {
475
- if (!(0, types_1.isClassInstance)(subtype) || !types_1.ClassType.isBuiltIn(subtype, ['TypeGuard', 'TypeIs'])) {
476
- isAllGuards = false;
477
- }
478
- });
479
- return isAllGuards;
480
- }
481
- return false;
482
- };
483
- const callTypeResult = evaluator.getTypeOfExpression(testExpression.d.leftExpr, 2 /* EvalFlags.CallBaseDefaults */);
484
- const callType = callTypeResult.type;
485
- if ((0, types_1.isFunction)(callType) && isFunctionReturnTypeGuard(callType)) {
486
- isPossiblyTypeGuard = true;
487
- }
488
- else if ((0, types_1.isOverloaded)(callType) &&
489
- types_1.OverloadedType.getOverloads(callType).some((o) => isFunctionReturnTypeGuard(o))) {
490
- isPossiblyTypeGuard = true;
491
- }
492
- else if ((0, types_1.isClassInstance)(callType)) {
493
- isPossiblyTypeGuard = true;
488
+ });
489
+ return isAllGuards;
490
+ }
491
+ return false;
492
+ };
493
+ // Reject unrelated references before evaluating the callee.
494
+ if (testExpression.d.args.some((arg) => isMatchingExpressionOrWalrusRhs(evaluator, reference, arg.d.valueExpr))) {
495
+ const callTypeResult = evaluator.getTypeOfExpression(testExpression.d.leftExpr, 2 /* EvalFlags.CallBaseDefaults */);
496
+ const callType = callTypeResult.type;
497
+ let isPossiblyTypeGuard = false;
498
+ if ((0, types_1.isFunction)(callType)) {
499
+ isPossiblyTypeGuard = isFunctionReturnTypeGuard(callType);
500
+ }
501
+ else if ((0, types_1.isOverloaded)(callType)) {
502
+ isPossiblyTypeGuard = types_1.OverloadedType.getOverloads(callType).some(isFunctionReturnTypeGuard);
503
+ }
504
+ else if ((0, types_1.isClassInstance)(callType)) {
505
+ // A callable object's __call__ may be overloaded, a property or have
506
+ // an inferred return type, so rely on the evaluated call below.
507
+ isPossiblyTypeGuard = true;
508
+ }
509
+ if (isPossiblyTypeGuard) {
510
+ const functionReturnTypeResult = evaluator.getTypeOfExpression(testExpression);
511
+ const functionReturnType = functionReturnTypeResult.type;
512
+ let typeGuardType;
513
+ let isStrictTypeGuard = false;
514
+ if ((0, types_1.isClassInstance)(functionReturnType) &&
515
+ types_1.ClassType.isBuiltIn(functionReturnType, ['TypeGuard', 'TypeIs']) &&
516
+ functionReturnType.priv.typeArgs &&
517
+ functionReturnType.priv.typeArgs.length > 0) {
518
+ isStrictTypeGuard = types_1.ClassType.isBuiltIn(functionReturnType, 'TypeIs');
519
+ typeGuardType = functionReturnType.priv.typeArgs[0];
494
520
  }
495
- if (isPossiblyTypeGuard) {
496
- // Evaluate the type guard call expression.
497
- const functionReturnTypeResult = evaluator.getTypeOfExpression(testExpression);
498
- const functionReturnType = functionReturnTypeResult.type;
499
- let typeGuardType;
500
- let isStrictTypeGuard = false;
501
- if ((0, types_1.isClassInstance)(functionReturnType) &&
502
- types_1.ClassType.isBuiltIn(functionReturnType, ['TypeGuard', 'TypeIs']) &&
503
- functionReturnType.priv.typeArgs &&
504
- functionReturnType.priv.typeArgs.length > 0) {
505
- isStrictTypeGuard = types_1.ClassType.isBuiltIn(functionReturnType, 'TypeIs');
506
- typeGuardType = functionReturnType.priv.typeArgs[0];
521
+ else if ((0, types_1.isUnion)(functionReturnType)) {
522
+ const typeGuardSubtypes = [];
523
+ let isAllGuards = true;
524
+ (0, typeUtils_1.doForEachSubtype)(functionReturnType, (subtype) => {
525
+ if ((0, types_1.isClassInstance)(subtype) &&
526
+ types_1.ClassType.isBuiltIn(subtype, ['TypeGuard', 'TypeIs']) &&
527
+ subtype.priv.typeArgs &&
528
+ subtype.priv.typeArgs.length > 0) {
529
+ typeGuardSubtypes.push(subtype);
530
+ }
531
+ else {
532
+ isAllGuards = false;
533
+ }
534
+ });
535
+ if (isAllGuards && typeGuardSubtypes.length > 0) {
536
+ // A union of type guards cannot be strict in the negative case because at runtime
537
+ // only one arm of the overload/union is selected. Treating it as strict would
538
+ // unsoundly eliminate types in the negative branch.
539
+ isStrictTypeGuard = false;
540
+ typeGuardType = (0, types_1.combineTypes)(typeGuardSubtypes.map((subtype) => subtype.priv.typeArgs[0]));
507
541
  }
508
- else if ((0, types_1.isUnion)(functionReturnType)) {
509
- const typeGuardSubtypes = [];
510
- let isAllGuards = true;
511
- (0, typeUtils_1.doForEachSubtype)(functionReturnType, (subtype) => {
512
- if ((0, types_1.isClassInstance)(subtype) &&
513
- types_1.ClassType.isBuiltIn(subtype, ['TypeGuard', 'TypeIs']) &&
514
- subtype.priv.typeArgs &&
515
- subtype.priv.typeArgs.length > 0) {
516
- typeGuardSubtypes.push(subtype);
542
+ }
543
+ if (typeGuardType) {
544
+ // Map only guard-returning calls. Ordinary callable predicates
545
+ // do not need their virtual parameter lists expanded.
546
+ const getTargetArgExpr = (fnType) => {
547
+ // Callable-valued attributes can have binding metadata without a method receiver.
548
+ const isUnbound = fnType.shared.methodClass !== undefined &&
549
+ !types_1.FunctionType.isStaticMethod(fnType) &&
550
+ fnType.priv.strippedFirstParamType === undefined;
551
+ const targetIndex = isUnbound ? 1 : 0;
552
+ const getPositionalArgExpr = () => {
553
+ // Unpacking before the guarded position obscures its argument expression.
554
+ let positionalIndex = 0;
555
+ for (const arg of testExpression.d.args) {
556
+ if (arg.d.name) {
557
+ continue;
558
+ }
559
+ if (arg.d.argCategory !== 0 /* ArgCategory.Simple */) {
560
+ return undefined;
561
+ }
562
+ if (positionalIndex === targetIndex) {
563
+ return arg.d.valueExpr;
564
+ }
565
+ positionalIndex++;
517
566
  }
518
- else {
519
- isAllGuards = false;
567
+ return undefined;
568
+ };
569
+ // Simple leading parameters bind positionally without expanding the rest of the signature.
570
+ const firstParam = fnType.shared.parameters[0];
571
+ const targetParam = fnType.shared.parameters[targetIndex];
572
+ if (firstParam?.category === 0 /* ParamCategory.Simple */ &&
573
+ firstParam.name &&
574
+ targetParam?.category === 0 /* ParamCategory.Simple */ &&
575
+ targetParam.name) {
576
+ const positionalArgExpr = getPositionalArgExpr();
577
+ if (positionalArgExpr) {
578
+ return positionalArgExpr;
520
579
  }
521
- });
522
- if (isAllGuards && typeGuardSubtypes.length > 0) {
523
- // A union of type guards cannot be strict in the negative case because at runtime
524
- // only one arm of the overload/union is selected. Treating it as strict would
525
- // unsoundly eliminate types in the negative branch.
526
- isStrictTypeGuard = false;
527
- typeGuardType = (0, types_1.combineTypes)(typeGuardSubtypes.map((subtype) => subtype.priv.typeArgs[0]));
528
580
  }
581
+ const paramDetails = (0, parameterUtils_1.getParamListDetails)(fnType);
582
+ if (targetIndex >= paramDetails.params.length) {
583
+ return undefined;
584
+ }
585
+ const target = paramDetails.params[targetIndex];
586
+ if (target.param.category !== 0 /* ParamCategory.Simple */ &&
587
+ target.param.category !== 1 /* ParamCategory.ArgsList */) {
588
+ return undefined;
589
+ }
590
+ if ((target.kind === parameterUtils_1.ParamKind.Standard || target.kind === parameterUtils_1.ParamKind.Keyword) &&
591
+ target.param.name) {
592
+ const kwArg = testExpression.d.args.find((arg) => arg.d.argCategory === 0 /* ArgCategory.Simple */ &&
593
+ arg.d.name?.d.value === target.param.name);
594
+ if (kwArg) {
595
+ return kwArg.d.valueExpr;
596
+ }
597
+ }
598
+ if (target.kind === parameterUtils_1.ParamKind.Keyword) {
599
+ return undefined;
600
+ }
601
+ return getPositionalArgExpr();
602
+ };
603
+ let arg0Expr;
604
+ const overloadsUsed = functionReturnTypeResult.overloadsUsedForCall;
605
+ if (overloadsUsed && overloadsUsed.length > 0) {
606
+ arg0Expr = getTargetArgExpr(overloadsUsed[0]);
607
+ for (let i = 1; arg0Expr && i < overloadsUsed.length; i++) {
608
+ if (getTargetArgExpr(overloadsUsed[i]) !== arg0Expr) {
609
+ arg0Expr = undefined;
610
+ break;
611
+ }
612
+ }
613
+ }
614
+ else if ((0, types_1.isFunction)(callType)) {
615
+ arg0Expr = getTargetArgExpr(callType);
529
616
  }
530
- if (typeGuardType) {
617
+ if (arg0Expr && isMatchingExpressionOrWalrusRhs(evaluator, reference, arg0Expr)) {
531
618
  const isIncomplete = !!callTypeResult.isIncomplete || !!functionReturnTypeResult.isIncomplete;
619
+ const guardType = typeGuardType;
532
620
  return (type) => {
533
621
  return {
534
- type: narrowTypeForUserDefinedTypeGuard(evaluator, type, typeGuardType, isPositiveTest, isStrictTypeGuard, testExpression, nodeInfo),
622
+ type: narrowTypeForUserDefinedTypeGuard(evaluator, type, guardType, isPositiveTest, isStrictTypeGuard, testExpression, nodeInfo),
535
623
  isIncomplete,
536
624
  };
537
625
  };
@@ -871,23 +959,40 @@ function narrowTypeForIsEllipsis(evaluator, node, type, isPositiveTest) {
871
959
  }
872
960
  return result;
873
961
  }
874
- // The "isinstance" and "issubclass" calls support two forms - a simple form
875
- // that accepts a single class, and a more complex form that accepts a tuple
876
- // of classes (including arbitrarily-nested tuples). This method determines
877
- // which form and returns a list of classes or undefined.
878
- function getIsInstanceClassTypes(evaluator, argType) {
962
+ // The "isinstance" and "issubclass" calls accept classes, runtime unions,
963
+ // and arbitrarily-nested tuples of these. This method extracts possible
964
+ // classes and guaranteed negative filters,
965
+ // or undefined if the filter contains a non-class type.
966
+ function getIsInstanceClassTypes(evaluator, argType, argExpr) {
879
967
  let foundNonClassType = false;
880
- const classTypeList = [];
968
+ const classTypes = [];
969
+ const negativeClassTypes = [];
881
970
  // Create a helper function that returns a list of class types or
882
971
  // undefined if any of the types are not valid.
883
- const addClassTypesToList = (types) => {
972
+ const addClassTypesToList = (types, isAmbiguous, isUnboundedEntry) => {
884
973
  types.forEach((subtype) => {
885
974
  if ((0, types_1.isClass)(subtype)) {
886
975
  subtype = (0, typeUtils_1.specializeWithUnknownTypeArgs)(subtype, evaluator.getTupleClassType());
887
976
  if ((0, types_1.isInstantiableClass)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'Callable')) {
888
977
  subtype = (0, typeUtils_1.convertToInstantiable)((0, typeUtils_1.getUnknownTypeForCallable)());
889
978
  }
979
+ else if (types_1.TypeBase.isInstance(subtype) && types_1.ClassType.isBuiltIn(subtype, 'type')) {
980
+ if (subtype.priv.typeArgs && subtype.priv.typeArgs.length > 0) {
981
+ const typeArg = subtype.priv.typeArgs[0];
982
+ if ((0, types_1.isAnyOrUnknown)(typeArg)) {
983
+ foundNonClassType = true;
984
+ return;
985
+ }
986
+ if ((0, types_1.isInstantiableClass)(typeArg)) {
987
+ subtype = types_1.ClassType.cloneIncludeSubclasses(typeArg);
988
+ }
989
+ else if ((0, types_1.isClassInstance)(typeArg)) {
990
+ subtype = types_1.ClassType.cloneAsInstantiable(typeArg);
991
+ }
992
+ }
993
+ }
890
994
  }
995
+ let classType;
891
996
  if ((0, types_1.isInstantiableClass)(subtype)) {
892
997
  // If this is a reference to a class that has type promotions (e.g.
893
998
  // float or complex), remove the promotions for purposes of the
@@ -895,49 +1000,112 @@ function getIsInstanceClassTypes(evaluator, argType) {
895
1000
  if (!subtype.priv.includeSubclasses && subtype.priv.includePromotions) {
896
1001
  subtype = types_1.ClassType.cloneRemoveTypePromotions(subtype);
897
1002
  }
898
- classTypeList.push(subtype);
1003
+ classType = subtype;
899
1004
  }
900
1005
  else if ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstantiable(subtype)) {
901
- classTypeList.push(subtype);
1006
+ classType = subtype;
902
1007
  }
903
1008
  else if ((0, typeUtils_1.isNoneTypeClass)(subtype)) {
904
1009
  (0, debug_1.assert)((0, types_1.isInstantiableClass)(subtype));
905
- classTypeList.push(subtype);
1010
+ classType = subtype;
906
1011
  }
907
1012
  else if ((0, types_1.isFunction)(subtype) &&
908
1013
  subtype.shared.parameters.length === 2 &&
909
1014
  subtype.shared.parameters[0].category === 1 /* ParamCategory.ArgsList */ &&
910
1015
  subtype.shared.parameters[1].category === 2 /* ParamCategory.KwargsDict */) {
911
- classTypeList.push(subtype);
1016
+ classType = subtype;
912
1017
  }
913
1018
  else {
914
1019
  foundNonClassType = true;
1020
+ return;
1021
+ }
1022
+ classTypes.push(classType);
1023
+ // Unbounded entries may be absent, and alternative class objects
1024
+ // are not all guaranteed to participate in the runtime check.
1025
+ if (!isUnboundedEntry && !isAmbiguous) {
1026
+ negativeClassTypes.push(classType);
915
1027
  }
916
1028
  });
917
1029
  };
918
- const addClassTypesRecursive = (type, recursionCount = 0) => {
1030
+ const addClassTypesRecursive = (type, isAmbiguous, isUnboundedEntry, recursionCount, expression) => {
919
1031
  if (recursionCount > types_1.maxTypeRecursionCount) {
920
1032
  return;
921
1033
  }
922
- if ((0, types_1.isClass)(type) && types_1.TypeBase.isInstance(type) && (0, typeUtils_1.isTupleClass)(type)) {
923
- if (type.priv.tupleTypeArgs) {
924
- type.priv.tupleTypeArgs.forEach((tupleEntry) => {
925
- addClassTypesRecursive(tupleEntry.type, recursionCount + 1);
926
- });
1034
+ // A runtime union checks both operands, but either operand can itself
1035
+ // be an alternative class object. Keep their certainty separate.
1036
+ if ((0, types_1.isUnion)(type) &&
1037
+ expression?.nodeType === 7 /* ParseNodeType.BinaryOperation */ &&
1038
+ expression.d.operator === 6 /* OperatorType.BitwiseOr */) {
1039
+ const leftType = evaluator.getCachedType(expression.d.leftExpr);
1040
+ const rightType = evaluator.getCachedType(expression.d.rightExpr);
1041
+ if (leftType &&
1042
+ rightType &&
1043
+ !(0, operations_1.customMetaclassSupportsMethod)(leftType, '__or__') &&
1044
+ !(0, operations_1.customMetaclassSupportsMethod)(rightType, '__ror__')) {
1045
+ // Match the union evaluator's normalization of None operands to NoneType.
1046
+ const adjustedLeftType = (0, typeUtils_1.isNoneInstance)(leftType)
1047
+ ? (0, typeUtils_1.convertToInstantiable)(evaluator.getNoneType())
1048
+ : leftType;
1049
+ const adjustedRightType = (0, typeUtils_1.isNoneInstance)(rightType)
1050
+ ? (0, typeUtils_1.convertToInstantiable)(evaluator.getNoneType())
1051
+ : rightType;
1052
+ addClassTypesRecursive(adjustedLeftType, isAmbiguous, isUnboundedEntry, recursionCount, expression.d.leftExpr);
1053
+ addClassTypesRecursive(adjustedRightType, isAmbiguous, isUnboundedEntry, recursionCount, expression.d.rightExpr);
1054
+ return;
1055
+ }
1056
+ }
1057
+ const isRuntimeUnion = type.props?.specialForm && types_1.ClassType.isBuiltIn(type.props.specialForm, 'UnionType');
1058
+ const isAmbiguousType = isAmbiguous || ((0, types_1.isUnion)(type) && !isRuntimeUnion);
1059
+ (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
1060
+ if ((0, types_1.isClassInstance)(subtype) && (0, typeUtils_1.isTupleClass)(subtype)) {
1061
+ if (subtype.priv.tupleTypeArgs) {
1062
+ let entryExpressions;
1063
+ if (expression?.nodeType === 52 /* ParseNodeType.Tuple */) {
1064
+ const expressions = [];
1065
+ expression.d.items.forEach((item) => {
1066
+ if (item.nodeType !== 56 /* ParseNodeType.Unpack */) {
1067
+ expressions.push(item);
1068
+ return;
1069
+ }
1070
+ const unpackedType = evaluator.getCachedType(item.d.expr);
1071
+ const entryCount = unpackedType && (0, types_1.isClassInstance)(unpackedType) && (0, typeUtils_1.isTupleClass)(unpackedType)
1072
+ ? unpackedType.priv.tupleTypeArgs?.length ?? 1
1073
+ : 1;
1074
+ for (let index = 0; index < entryCount; index++) {
1075
+ expressions.push(undefined);
1076
+ }
1077
+ });
1078
+ if (expressions.length === subtype.priv.tupleTypeArgs.length) {
1079
+ entryExpressions = expressions;
1080
+ }
1081
+ }
1082
+ subtype.priv.tupleTypeArgs.forEach((tupleEntry, index) => {
1083
+ addClassTypesRecursive(tupleEntry.type, isAmbiguousType, isUnboundedEntry || tupleEntry.isUnbounded, recursionCount + 1, entryExpressions?.[index]);
1084
+ });
1085
+ }
927
1086
  }
928
- }
929
- else {
930
- (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
931
- addClassTypesToList([subtype]);
932
- });
933
- }
1087
+ else {
1088
+ addClassTypesToList([subtype], isAmbiguousType, isUnboundedEntry);
1089
+ }
1090
+ });
934
1091
  };
935
- (0, typeUtils_1.doForEachSubtype)(argType, (subtype) => {
936
- addClassTypesRecursive(subtype);
937
- });
938
- return foundNonClassType ? undefined : classTypeList;
1092
+ addClassTypesRecursive(argType, /* isAmbiguous */ false, /* isUnboundedEntry */ false, 0, argExpr);
1093
+ return foundNonClassType ? undefined : { classTypes, negativeClassTypes };
939
1094
  }
940
1095
  function narrowTypeForInstanceOrSubclass(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest, errorNode, nodeInfo) {
1096
+ if (!isInstanceCheck && !isTypeIsCheck && !isPositiveTest) {
1097
+ // A custom subclass check can reject even the exact same final class.
1098
+ // Preserve the existing narrowing policy for non-final classes, including ABCs.
1099
+ filterTypes = filterTypes.filter((filterType) => {
1100
+ const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
1101
+ return (!(0, types_1.isInstantiableClass)(concreteFilterType) ||
1102
+ !types_1.ClassType.isFinal(concreteFilterType) ||
1103
+ !(0, operations_1.customMetaclassSupportsMethod)(concreteFilterType, '__subclasscheck__'));
1104
+ });
1105
+ }
1106
+ if (!isPositiveTest && filterTypes.length === 0) {
1107
+ return type;
1108
+ }
941
1109
  // First try with intersection types disallowed.
942
1110
  const narrowedType = narrowTypeForInstanceOrSubclassInternal(evaluator, type, filterTypes, isInstanceCheck, isTypeIsCheck, isPositiveTest,
943
1111
  /* allowIntersections */ false, errorNode, nodeInfo);
@@ -1077,8 +1245,10 @@ function narrowTypeForInstance(evaluator, type, filterTypes, isTypeIsCheck, isPo
1077
1245
  // note this case specially so we don't do any narrowing, which
1078
1246
  // will generate false positives.
1079
1247
  if (filterIsSuperclass) {
1080
- if (!isTypeIsCheck && concreteFilterType.priv.includeSubclasses) {
1081
- // If the filter type includes subclasses, we can't eliminate
1248
+ if (!isTypeIsCheck &&
1249
+ concreteFilterType.priv.includeSubclasses &&
1250
+ !types_1.ClassType.isFinal(concreteFilterType)) {
1251
+ // If the filter type includes subclasses and is not final, we can't eliminate
1082
1252
  // this type in the negative direction. We'll relax this for
1083
1253
  // TypeIs checks.
1084
1254
  isClassRelationshipIndeterminate = true;
@@ -1869,11 +2039,63 @@ function narrowTypeForTypeIs(evaluator, type, classTypes, isPositiveTest) {
1869
2039
  });
1870
2040
  return (0, types_1.combineTypes)(typesToCombine);
1871
2041
  }
2042
+ function hasUnresolvedMetaclassInMro(classType) {
2043
+ return classType.shared.mro.some((baseClass) => !(0, types_1.isInstantiableClass)(baseClass) || !!(baseClass.shared.flags & 134217728 /* ClassTypeFlags.HasUnresolvedMetaclass */));
2044
+ }
2045
+ // Determines whether an equality comparison ("==" or "!=") involving the
2046
+ // specified class object is guaranteed to have identity semantics. This
2047
+ // requires that the class is statically closed (it cannot be a subclass
2048
+ // with a different metaclass), is not generic (specialized aliases compare
2049
+ // by value), and its metaclass does not override "__eq__" or "__ne__".
2050
+ function hasIdentityEqualitySemantics(classType, metaclassEqualityResults) {
2051
+ if (classType.priv.includeSubclasses && !types_1.ClassType.isFinal(classType)) {
2052
+ return false;
2053
+ }
2054
+ if (classType.shared.typeParams.length > 0) {
2055
+ return false;
2056
+ }
2057
+ const metaclass = classType.shared.effectiveMetaclass;
2058
+ if (!metaclass ||
2059
+ !(0, types_1.isInstantiableClass)(metaclass) ||
2060
+ hasUnresolvedMetaclassInMro(classType) ||
2061
+ hasUnresolvedMetaclassInMro(metaclass)) {
2062
+ return false;
2063
+ }
2064
+ if (types_1.ClassType.isBuiltIn(metaclass, 'type')) {
2065
+ return true;
2066
+ }
2067
+ // Cloned metaclasses share method definitions, but the class-specific checks above cannot be shared.
2068
+ const cachedResult = metaclassEqualityResults.get(metaclass.shared);
2069
+ if (cachedResult !== undefined) {
2070
+ return cachedResult;
2071
+ }
2072
+ const result = !(0, operations_1.customMetaclassSupportsMethod)(classType, '__eq__') && !(0, operations_1.customMetaclassSupportsMethod)(classType, '__ne__');
2073
+ metaclassEqualityResults.set(metaclass.shared, result);
2074
+ return result;
2075
+ }
1872
2076
  // Attempts to narrow a type based on a comparison with a class using "is" or
1873
- // "is not". This pattern is sometimes used for sentinels.
1874
- function narrowTypeForClassComparison(evaluator, referenceType, classType, isPositiveTest) {
2077
+ // "is not", or "==" or "!=".
2078
+ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPositiveTest, isIsOperator = true) {
2079
+ // Limit reuse to this invocation so results cannot outlive the evaluation that established them.
2080
+ const metaclassEqualityResults = isIsOperator ? undefined : new Map();
2081
+ if (metaclassEqualityResults && !hasIdentityEqualitySemantics(classType, metaclassEqualityResults)) {
2082
+ return referenceType;
2083
+ }
1875
2084
  return (0, typeUtils_1.mapSubtypes)(referenceType, (subtype) => {
2085
+ // Multiple class constraints expand to a union with distinct conditions, which equality cannot narrow.
2086
+ if (metaclassEqualityResults &&
2087
+ (0, types_1.isTypeVar)(subtype) &&
2088
+ !subtype.shared.recursiveAlias &&
2089
+ subtype.shared.constraints.length > 1 &&
2090
+ subtype.shared.constraints.every(types_1.isClassInstance)) {
2091
+ return subtype;
2092
+ }
1876
2093
  let concreteSubtype = evaluator.makeTopLevelTypeVarsConcrete(subtype);
2094
+ if (metaclassEqualityResults &&
2095
+ (!(0, types_1.isInstantiableClass)(concreteSubtype) ||
2096
+ !hasIdentityEqualitySemantics(concreteSubtype, metaclassEqualityResults))) {
2097
+ return subtype;
2098
+ }
1877
2099
  if (isPositiveTest) {
1878
2100
  if ((0, types_1.isClassInstance)(concreteSubtype) &&
1879
2101
  types_1.TypeBase.isInstance(subtype) &&
@@ -1888,6 +2110,9 @@ function narrowTypeForClassComparison(evaluator, referenceType, classType, isPos
1888
2110
  }
1889
2111
  if ((0, types_1.isClass)(concreteSubtype)) {
1890
2112
  if (types_1.TypeBase.isInstance(concreteSubtype)) {
2113
+ if (!isIsOperator) {
2114
+ return subtype;
2115
+ }
1891
2116
  return types_1.ClassType.isBuiltIn(concreteSubtype, 'object') ? classType : undefined;
1892
2117
  }
1893
2118
  const isSuperType = isFilterSuperclass(subtype, concreteSubtype, classType, classType);