@zzzen/pyright-internal 1.2.0-dev.20261004 → 1.2.0-dev.20261018
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/binder.js +8 -0
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +0 -1
- package/dist/analyzer/checker.js +21 -42
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +75 -28
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +3 -2
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/operations.d.ts +2 -0
- package/dist/analyzer/operations.js +2 -1
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/overloadResultAdmission.js +115 -3
- package/dist/analyzer/overloadResultAdmission.js.map +1 -1
- package/dist/analyzer/overloadResultController.js +36 -10
- package/dist/analyzer/overloadResultController.js.map +1 -1
- package/dist/analyzer/overloadResultSelector.js +32 -12
- package/dist/analyzer/overloadResultSelector.js.map +1 -1
- package/dist/analyzer/parameterUtils.js +2 -1
- package/dist/analyzer/parameterUtils.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +1 -0
- package/dist/analyzer/parseTreeUtils.js +13 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +105 -35
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +3 -0
- package/dist/analyzer/program.js +34 -9
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.d.ts +2 -2
- package/dist/analyzer/properties.js +2 -2
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +3 -1
- package/dist/analyzer/protocols.js +24 -2
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.js +6 -2
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceEnumerator.d.ts +3 -1
- package/dist/analyzer/sourceEnumerator.js +30 -11
- package/dist/analyzer/sourceEnumerator.js.map +1 -1
- package/dist/analyzer/sourceMapper.d.ts +1 -0
- package/dist/analyzer/sourceMapper.js +10 -4
- package/dist/analyzer/sourceMapper.js.map +1 -1
- package/dist/analyzer/tuples.js +17 -6
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +419 -67
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
- package/dist/analyzer/typeEvaluatorTypes.js +4 -0
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +5 -1
- package/dist/analyzer/typeGuards.js +324 -99
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +32 -6
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeStubRenderer.d.ts +6 -1
- package/dist/analyzer/typeStubRenderer.js +19 -12
- package/dist/analyzer/typeStubRenderer.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +1 -0
- package/dist/analyzer/typeUtils.js +15 -1
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +2 -1
- package/dist/analyzer/typedDicts.js +49 -10
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +2 -1
- package/dist/analyzer/types.js +9 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +9 -0
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/windowsProcessTree.json +252 -33
- package/dist/tests/cacheManager.test.js +19 -15
- package/dist/tests/cacheManager.test.js.map +1 -1
- package/dist/tests/checker.test.js +50 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/config.test.js +126 -0
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/constraintSolver.test.d.ts +1 -0
- package/dist/tests/constraintSolver.test.js +39 -0
- package/dist/tests/constraintSolver.test.js.map +1 -0
- package/dist/tests/fourslash/hover.typedDict.get.fourslash.js +11 -0
- package/dist/tests/fourslash/hover.typedDict.get.fourslash.js.map +1 -1
- package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js +16 -0
- package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js.map +1 -0
- package/dist/tests/mypyPrimerAnalysis.test.js +67 -11
- package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
- package/dist/tests/overloadResultController.test.js +379 -1
- package/dist/tests/overloadResultController.test.js.map +1 -1
- package/dist/tests/signatureHelp.test.js +34 -0
- package/dist/tests/signatureHelp.test.js.map +1 -1
- package/dist/tests/sourceEnumeratorSymlink.test.js +98 -13
- package/dist/tests/sourceEnumeratorSymlink.test.js.map +1 -1
- package/dist/tests/sourceMapperUtils.test.js +143 -0
- package/dist/tests/sourceMapperUtils.test.js.map +1 -1
- package/dist/tests/typeEquality.test.js +85 -2
- package/dist/tests/typeEquality.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +47 -3
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +23 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +1 -1
- package/dist/tests/typeEvaluator6.test.js +83 -1
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +32 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +15 -1
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/package.json +3 -3
|
@@ -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):
|
|
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
|
|
431
|
+
const classTypeInfo = getIsInstanceClassTypes(evaluator, arg1Type, arg1Expr);
|
|
420
432
|
const isIncomplete = !!callTypeResult.isIncomplete || !!arg1TypeResult.isIncomplete;
|
|
421
|
-
if (
|
|
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
|
-
|
|
460
|
-
const
|
|
461
|
-
if (
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
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
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
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 (
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
-
|
|
519
|
-
|
|
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 (
|
|
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,
|
|
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
|
|
875
|
-
//
|
|
876
|
-
//
|
|
877
|
-
//
|
|
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
|
|
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
|
-
|
|
1003
|
+
classType = subtype;
|
|
899
1004
|
}
|
|
900
1005
|
else if ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstantiable(subtype)) {
|
|
901
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1030
|
+
const addClassTypesRecursive = (type, isAmbiguous, isUnboundedEntry, recursionCount, expression) => {
|
|
919
1031
|
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
920
1032
|
return;
|
|
921
1033
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
});
|
|
933
|
-
}
|
|
1087
|
+
else {
|
|
1088
|
+
addClassTypesToList([subtype], isAmbiguousType, isUnboundedEntry);
|
|
1089
|
+
}
|
|
1090
|
+
});
|
|
934
1091
|
};
|
|
935
|
-
(
|
|
936
|
-
|
|
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 &&
|
|
1081
|
-
|
|
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"
|
|
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);
|