@zzzen/pyright-internal 1.2.0-dev.20261018 → 1.2.0-dev.20261101
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 +20 -9
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.js +4 -0
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +3 -3
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/dataClasses.js +14 -5
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/decorators.d.ts +1 -1
- package/dist/analyzer/decorators.js +22 -2
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/namedTuples.d.ts +2 -1
- package/dist/analyzer/namedTuples.js +63 -35
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.js +45 -1
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +2 -0
- package/dist/analyzer/parseTreeUtils.js +43 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +3 -1
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/sentinel.js +7 -1
- package/dist/analyzer/sentinel.js.map +1 -1
- package/dist/analyzer/sourceFile.js +13 -6
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/tupleComparison.d.ts +6 -0
- package/dist/analyzer/tupleComparison.js +731 -0
- package/dist/analyzer/tupleComparison.js.map +1 -0
- package/dist/analyzer/tuples.js +35 -4
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +232 -20
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
- package/dist/analyzer/typeEvaluatorTypes.js +2 -3
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +1 -0
- package/dist/analyzer/typeGuards.js +257 -41
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.js +3 -0
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +14 -0
- package/dist/analyzer/types.js +215 -10
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/processUtils.d.ts +6 -0
- package/dist/common/processUtils.js +56 -1
- package/dist/common/processUtils.js.map +1 -1
- package/dist/common/textEditTracker.js +1 -1
- package/dist/common/textEditTracker.js.map +1 -1
- package/dist/common/windowsProcessTree.d.ts +2 -0
- package/dist/common/windowsProcessTree.js +23 -0
- package/dist/common/windowsProcessTree.js.map +1 -1
- package/dist/common/windowsProcessTree.json +23 -3
- package/dist/languageServerBase.d.ts +3 -0
- package/dist/languageServerBase.js +44 -12
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.js +6 -6
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.js +3 -3
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameProvider.js +1 -1
- package/dist/languageService/renameProvider.js.map +1 -1
- package/dist/languageService/symbolIndexer.js +2 -2
- package/dist/languageService/symbolIndexer.js.map +1 -1
- package/dist/localization/localize.d.ts +2 -0
- package/dist/localization/localize.js +2 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +8 -0
- package/dist/parser/parseTreeTokenReuse.d.ts +34 -0
- package/dist/parser/parseTreeTokenReuse.js +897 -0
- package/dist/parser/parseTreeTokenReuse.js.map +1 -0
- package/dist/parser/tokenizer.d.ts +10 -1
- package/dist/parser/tokenizer.js +184 -130
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/tests/checker.test.js +8 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/fourSlashParser.test.js +35 -0
- package/dist/tests/fourSlashParser.test.js.map +1 -1
- package/dist/tests/harness/fourslash/fourSlashParser.js +14 -4
- package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -1
- package/dist/tests/languageServer.test.js +15 -0
- package/dist/tests/languageServer.test.js.map +1 -1
- package/dist/tests/lsp/languageServer.js +6 -6
- package/dist/tests/lsp/languageServer.js.map +1 -1
- package/dist/tests/mypyPrimerAnalysis.test.js +133 -0
- package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +3 -1
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +54 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +10 -3
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator6.test.js +35 -0
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +20 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +1291 -1
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/dist/tests/types.test.js +55 -0
- package/dist/tests/types.test.js.map +1 -1
- package/dist/typeServer/programWrapper.js +8 -2
- package/dist/typeServer/programWrapper.js.map +1 -1
- package/dist/typeServer/server.d.ts +12 -2
- package/dist/typeServer/server.js +97 -0
- package/dist/typeServer/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -16,7 +16,7 @@ import { SpeculativeModeOptions } from './typeCacheUtils';
|
|
|
16
16
|
import { PrintTypeFlags } from './typePrinter';
|
|
17
17
|
import { AnyType, ClassType, FunctionParam, FunctionType, OverloadedType, TupleTypeArg, Type, TypeCondition, TypeVarType, UnknownType, Variance } from './types';
|
|
18
18
|
import { ApplyTypeVarOptions, ClassMember, InferenceContext, MemberAccessFlags } from './typeUtils';
|
|
19
|
-
export
|
|
19
|
+
export { maxSubtypesForInferredType } from './types';
|
|
20
20
|
export declare const maxInferredContainerDepth = 8;
|
|
21
21
|
export declare const enum EvalFlags {
|
|
22
22
|
None = 0,
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.AssignTypeFlags = exports.Reachability = exports.EvalFlags = exports.maxInferredContainerDepth = exports.maxSubtypesForInferredType = void 0;
|
|
12
12
|
exports.ensureExpectedTypeCandidates = ensureExpectedTypeCandidates;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
exports.maxSubtypesForInferredType = 64;
|
|
13
|
+
var types_1 = require("./types");
|
|
14
|
+
Object.defineProperty(exports, "maxSubtypesForInferredType", { enumerable: true, get: function () { return types_1.maxSubtypesForInferredType; } });
|
|
16
15
|
// In certain loops, it's possible to construct arbitrarily-deep containers
|
|
17
16
|
// (tuples, lists, sets, or dicts) which can lead to infinite type analysis.
|
|
18
17
|
// This limits the depth.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typeEvaluatorTypes.js","sourceRoot":"","sources":["../../../../../src/analyzer/typeEvaluatorTypes.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;
|
|
1
|
+
{"version":3,"file":"typeEvaluatorTypes.js","sourceRoot":"","sources":["../../../../../src/analyzer/typeEvaluatorTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ export interface IsInstanceClassTypeInfo {
|
|
|
11
11
|
negativeClassTypes: (ClassType | TypeVarType | FunctionType)[];
|
|
12
12
|
}
|
|
13
13
|
export type TypeNarrowingCallback = (type: Type) => TypeNarrowingResult | undefined;
|
|
14
|
+
export declare function applyTypeNarrowingCallback(callback: TypeNarrowingCallback, type: Type): TypeNarrowingResult | undefined;
|
|
14
15
|
export declare function getTypeNarrowingCallback(evaluator: TypeEvaluator, reference: ExpressionNode, testExpression: ExpressionNode, isPositiveTest: boolean, nodeInfo: AnalyzerNodeInfoAccessor, recursionCount?: number): TypeNarrowingCallback | undefined;
|
|
15
16
|
export declare function getIsInstanceClassTypes(evaluator: TypeEvaluator, argType: Type, argExpr: ExpressionNode): IsInstanceClassTypeInfo | undefined;
|
|
16
17
|
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;
|
|
@@ -43,6 +43,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
43
43
|
};
|
|
44
44
|
})();
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.applyTypeNarrowingCallback = applyTypeNarrowingCallback;
|
|
46
47
|
exports.getTypeNarrowingCallback = getTypeNarrowingCallback;
|
|
47
48
|
exports.getIsInstanceClassTypes = getIsInstanceClassTypes;
|
|
48
49
|
exports.narrowTypeForInstanceOrSubclass = narrowTypeForInstanceOrSubclass;
|
|
@@ -66,6 +67,23 @@ const symbol_1 = require("./symbol");
|
|
|
66
67
|
const typedDicts_1 = require("./typedDicts");
|
|
67
68
|
const types_1 = require("./types");
|
|
68
69
|
const typeUtils_1 = require("./typeUtils");
|
|
70
|
+
function applyTypeNarrowingCallback(callback, type) {
|
|
71
|
+
const result = callback(type);
|
|
72
|
+
const baseType = (0, types_1.getInferredTupleLiteralBase)(type);
|
|
73
|
+
if (baseType === type) {
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
// Narrow both views at the flow boundary, not recursively within a guard.
|
|
77
|
+
// Independently established literals must survive mutable inference too.
|
|
78
|
+
const baseResult = callback(baseType);
|
|
79
|
+
if (!result && !baseResult) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
type: (0, types_1.retainInferredTupleLiterals)(result?.type ?? type, (0, types_1.getInferredTupleLiteralBase)(baseResult?.type ?? baseType)),
|
|
84
|
+
isIncomplete: !!result?.isIncomplete || !!baseResult?.isIncomplete,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
69
87
|
// Given a reference expression and a test expression, returns a callback that
|
|
70
88
|
// can be used to narrow the type described by the reference expression.
|
|
71
89
|
// If the specified flow node is not associated with the test expression,
|
|
@@ -135,37 +153,77 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
|
135
153
|
};
|
|
136
154
|
}
|
|
137
155
|
}
|
|
138
|
-
// Look for "type(X) is Y", "type(X) is not Y", "type(X) == Y" or "type(X) != Y"
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
156
|
+
// Look for "type(X) is Y", "type(X) is not Y", "type(X) == Y" or "type(X) != Y",
|
|
157
|
+
// as well as reverse forms "Y is type(X)", "Y is not type(X)", "Y == type(X)", "Y != type(X)".
|
|
158
|
+
let typeCallNode;
|
|
159
|
+
let otherExpr;
|
|
160
|
+
const isTypeCall = (expr, referenceExpr) => expr.nodeType === 9 /* ParseNodeType.Call */ &&
|
|
161
|
+
expr.d.args.length === 1 &&
|
|
162
|
+
expr.d.args[0].d.argCategory === 0 /* ArgCategory.Simple */ &&
|
|
163
|
+
(!referenceExpr ||
|
|
164
|
+
isMatchingExpressionOrWalrusRhs(evaluator, referenceExpr, expr.d.args[0].d.valueExpr)) &&
|
|
165
|
+
isTypeCallBase(evaluator.getTypeOfExpression(expr.d.leftExpr, 2 /* EvalFlags.CallBaseDefaults */).type);
|
|
166
|
+
// Either operand may be the call; pick the one whose argument matches the reference.
|
|
167
|
+
if (isTypeCall(testExpression.d.leftExpr, reference)) {
|
|
168
|
+
typeCallNode = testExpression.d.leftExpr;
|
|
169
|
+
otherExpr = testExpression.d.rightExpr;
|
|
170
|
+
}
|
|
171
|
+
else if (isTypeCall(testExpression.d.rightExpr, reference)) {
|
|
172
|
+
typeCallNode = testExpression.d.rightExpr;
|
|
173
|
+
otherExpr = testExpression.d.leftExpr;
|
|
174
|
+
}
|
|
175
|
+
if (typeCallNode && otherExpr) {
|
|
176
|
+
const otherResult = evaluator.getTypeOfExpression(otherExpr);
|
|
177
|
+
const classTypes = [];
|
|
178
|
+
let isClassType = true;
|
|
179
|
+
let classTypeVar;
|
|
180
|
+
if ((0, types_1.isTypeVar)(otherResult.type) && types_1.TypeBase.isInstantiable(otherResult.type)) {
|
|
181
|
+
classTypeVar = (0, typeUtils_1.convertToInstance)(otherResult.type);
|
|
182
|
+
}
|
|
183
|
+
else if ((0, types_1.isClassInstance)(otherResult.type) &&
|
|
184
|
+
types_1.ClassType.isBuiltIn(otherResult.type, 'type') &&
|
|
185
|
+
otherResult.type.priv.typeArgs?.length === 1 &&
|
|
186
|
+
(0, types_1.isTypeVar)(otherResult.type.priv.typeArgs[0])) {
|
|
187
|
+
classTypeVar = otherResult.type.priv.typeArgs[0];
|
|
188
|
+
}
|
|
189
|
+
evaluator.mapSubtypesExpandTypeVars(otherResult.type, /* options */ undefined, (expandedSubtype) => {
|
|
190
|
+
let instantiable;
|
|
191
|
+
if ((0, types_1.isClass)(expandedSubtype)) {
|
|
192
|
+
if ((0, types_1.isClassInstance)(expandedSubtype) &&
|
|
193
|
+
types_1.ClassType.isBuiltIn(expandedSubtype, 'type') &&
|
|
194
|
+
expandedSubtype.priv.typeArgs &&
|
|
195
|
+
expandedSubtype.priv.typeArgs.length > 0) {
|
|
196
|
+
const extracted = (0, typeUtils_1.convertToInstantiable)(expandedSubtype.priv.typeArgs[0],
|
|
197
|
+
/* includeSubclasses */ true);
|
|
198
|
+
if ((0, types_1.isInstantiableClass)(extracted)) {
|
|
199
|
+
instantiable = extracted;
|
|
166
200
|
}
|
|
167
201
|
}
|
|
202
|
+
else if ((0, types_1.isInstantiableClass)(expandedSubtype)) {
|
|
203
|
+
instantiable = expandedSubtype;
|
|
204
|
+
}
|
|
168
205
|
}
|
|
206
|
+
if (instantiable) {
|
|
207
|
+
classTypes.push(instantiable);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
isClassType = false;
|
|
211
|
+
}
|
|
212
|
+
return undefined;
|
|
213
|
+
});
|
|
214
|
+
if (isClassType && classTypes.length > 0) {
|
|
215
|
+
const allowLegacyEquality = !isOrIsNotOperator &&
|
|
216
|
+
typeCallNode === testExpression.d.leftExpr &&
|
|
217
|
+
(((0, types_1.isInstantiableClass)(otherResult.type) &&
|
|
218
|
+
!otherResult.type.priv.includeSubclasses &&
|
|
219
|
+
!otherResult.type.priv.isTypeArgExplicit) ||
|
|
220
|
+
isTypeCall(otherExpr));
|
|
221
|
+
return (type) => {
|
|
222
|
+
return {
|
|
223
|
+
type: narrowTypeForTypeIs(evaluator, type, classTypes, adjIsPositiveTest, isOrIsNotOperator, classTypeVar, allowLegacyEquality),
|
|
224
|
+
isIncomplete: !!otherResult.isIncomplete,
|
|
225
|
+
};
|
|
226
|
+
};
|
|
169
227
|
}
|
|
170
228
|
}
|
|
171
229
|
if (isOrIsNotOperator) {
|
|
@@ -1692,8 +1750,14 @@ function narrowTypeForContainerType(evaluator, referenceType, containerType, isP
|
|
|
1692
1750
|
!containerType.priv.tupleTypeArgs) {
|
|
1693
1751
|
return referenceType;
|
|
1694
1752
|
}
|
|
1695
|
-
// Determine which tuple types can be eliminated. Only "None"
|
|
1696
|
-
// literal types can be handled here.
|
|
1753
|
+
// Determine which tuple types can be eliminated. Only "None",
|
|
1754
|
+
// literal types, and final instantiable classes can be handled here.
|
|
1755
|
+
// Non-final instantiable classes (type[A]) cannot be eliminated in negative
|
|
1756
|
+
// tests because a subclass SubA(A) reaches the negative branch at runtime
|
|
1757
|
+
// (since SubA != A). Generic classes are also excluded because a
|
|
1758
|
+
// specialized class object like Box[int] is not the same runtime object
|
|
1759
|
+
// as Box. Classes that define or inherit __class_getitem__ are excluded
|
|
1760
|
+
// for the same reason.
|
|
1697
1761
|
const typesToEliminate = [];
|
|
1698
1762
|
containerType.priv.tupleTypeArgs.forEach((tupleEntry) => {
|
|
1699
1763
|
if (!tupleEntry.isUnbounded) {
|
|
@@ -1703,14 +1767,23 @@ function narrowTypeForContainerType(evaluator, referenceType, containerType, isP
|
|
|
1703
1767
|
else if ((0, types_1.isClassInstance)(tupleEntry.type) && (0, typeUtils_1.isLiteralType)(tupleEntry.type)) {
|
|
1704
1768
|
typesToEliminate.push(tupleEntry.type);
|
|
1705
1769
|
}
|
|
1770
|
+
else if ((0, types_1.isInstantiableClass)(tupleEntry.type) &&
|
|
1771
|
+
types_1.ClassType.isFinal(tupleEntry.type) &&
|
|
1772
|
+
tupleEntry.type.shared.typeParams.length === 0 &&
|
|
1773
|
+
!(0, typeUtils_1.lookUpClassMember)(tupleEntry.type, '__class_getitem__')) {
|
|
1774
|
+
typesToEliminate.push(tupleEntry.type);
|
|
1775
|
+
}
|
|
1706
1776
|
}
|
|
1707
1777
|
});
|
|
1708
1778
|
if (typesToEliminate.length === 0) {
|
|
1709
1779
|
return referenceType;
|
|
1710
1780
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1781
|
+
const canNarrowLiterals = typesToEliminate.some(types_1.isClassInstance);
|
|
1782
|
+
return (0, typeUtils_1.mapSubtypes)(referenceType, (unexpandedSubtype) => {
|
|
1783
|
+
const referenceSubtype = evaluator.makeTopLevelTypeVarsConcrete(unexpandedSubtype);
|
|
1784
|
+
if (canNarrowLiterals &&
|
|
1785
|
+
(0, types_1.isClassInstance)(referenceSubtype) &&
|
|
1786
|
+
referenceSubtype.priv.literalValue === undefined) {
|
|
1714
1787
|
// If we're able to enumerate all possible literal values
|
|
1715
1788
|
// (for bool or enum), we can eliminate all others in a negative test.
|
|
1716
1789
|
const allLiteralTypes = enumerateLiteralsForType(evaluator, referenceSubtype);
|
|
@@ -1721,7 +1794,7 @@ function narrowTypeForContainerType(evaluator, referenceType, containerType, isP
|
|
|
1721
1794
|
if (typesToEliminate.some((t) => (0, types_1.isTypeSame)(t, referenceSubtype))) {
|
|
1722
1795
|
return undefined;
|
|
1723
1796
|
}
|
|
1724
|
-
return
|
|
1797
|
+
return unexpandedSubtype;
|
|
1725
1798
|
});
|
|
1726
1799
|
}
|
|
1727
1800
|
function getElementTypeForContainerNarrowing(containerType) {
|
|
@@ -1991,36 +2064,172 @@ function narrowTypeForDiscriminatedFieldNoneComparison(evaluator, referenceType,
|
|
|
1991
2064
|
return subtype;
|
|
1992
2065
|
});
|
|
1993
2066
|
}
|
|
2067
|
+
function isTypeCallBase(callType) {
|
|
2068
|
+
return (0, types_1.isInstantiableClass)(callType) && types_1.ClassType.isBuiltIn(callType, 'type');
|
|
2069
|
+
}
|
|
2070
|
+
// Determines whether two classes have incompatible disjoint bases (PEP 800),
|
|
2071
|
+
// in which case no class can derive from both of them.
|
|
2072
|
+
function areDisjointBasesIncompatible(classType1, classType2) {
|
|
2073
|
+
const base1 = types_1.ClassType.getDisjointBase(classType1);
|
|
2074
|
+
const base2 = types_1.ClassType.getDisjointBase(classType2);
|
|
2075
|
+
return !!base1 && !!base2 && !types_1.ClassType.getMostDerivedDisjointBase([base1, base2]);
|
|
2076
|
+
}
|
|
2077
|
+
// Fill gradual holes without replacing facts inferred from the guarded value.
|
|
2078
|
+
function fillTypeGuardGradualArgs(input, hint, results, recursionCount = 0) {
|
|
2079
|
+
if (!hint || input === hint || recursionCount > types_1.maxTypeRecursionCount) {
|
|
2080
|
+
return input;
|
|
2081
|
+
}
|
|
2082
|
+
if ((0, types_1.isAnyOrUnknown)(input)) {
|
|
2083
|
+
return (0, types_1.isAnyOrUnknown)(hint) ? ((0, types_1.isAny)(hint) ? hint : input) : hint;
|
|
2084
|
+
}
|
|
2085
|
+
if (!(0, types_1.isClass)(input) || !(0, types_1.isClass)(hint) || !types_1.ClassType.isSameGenericClass(input, hint)) {
|
|
2086
|
+
return input;
|
|
2087
|
+
}
|
|
2088
|
+
let inputResults = results.get(input);
|
|
2089
|
+
const cachedResult = inputResults?.get(hint);
|
|
2090
|
+
if (cachedResult !== undefined) {
|
|
2091
|
+
return cachedResult;
|
|
2092
|
+
}
|
|
2093
|
+
if (!inputResults) {
|
|
2094
|
+
inputResults = new Map();
|
|
2095
|
+
results.set(input, inputResults);
|
|
2096
|
+
}
|
|
2097
|
+
// Bound recursive aliases and reuse shared argument graphs within this narrowing operation.
|
|
2098
|
+
inputResults.set(hint, input);
|
|
2099
|
+
const inputTuple = input.priv.tupleTypeArgs;
|
|
2100
|
+
const hintTuple = hint.priv.tupleTypeArgs;
|
|
2101
|
+
if (inputTuple || hintTuple) {
|
|
2102
|
+
if (!inputTuple ||
|
|
2103
|
+
!hintTuple ||
|
|
2104
|
+
inputTuple.length !== hintTuple.length ||
|
|
2105
|
+
inputTuple.some((arg, index) => arg.isUnbounded !== hintTuple[index].isUnbounded ||
|
|
2106
|
+
!!arg.isOptional !== !!hintTuple[index].isOptional)) {
|
|
2107
|
+
return input;
|
|
2108
|
+
}
|
|
2109
|
+
const tupleArgs = inputTuple.map((arg, index) => ({
|
|
2110
|
+
...arg,
|
|
2111
|
+
type: fillTypeGuardGradualArgs(arg.type, hintTuple[index].type, results, recursionCount + 1),
|
|
2112
|
+
}));
|
|
2113
|
+
const result = tupleArgs.every((arg, index) => arg.type === inputTuple[index].type)
|
|
2114
|
+
? input
|
|
2115
|
+
: (0, typeUtils_1.specializeTupleClass)(input, tupleArgs, input.priv.isTypeArgExplicit, input.priv.isUnpacked);
|
|
2116
|
+
inputResults.set(hint, result);
|
|
2117
|
+
return result;
|
|
2118
|
+
}
|
|
2119
|
+
const inputArgs = input.priv.typeArgs;
|
|
2120
|
+
const hintArgs = hint.priv.typeArgs;
|
|
2121
|
+
if (!inputArgs || !hintArgs || inputArgs.length !== hintArgs.length) {
|
|
2122
|
+
return input;
|
|
2123
|
+
}
|
|
2124
|
+
const typeArgs = inputArgs.map((arg, index) => fillTypeGuardGradualArgs(arg, hintArgs[index], results, recursionCount + 1));
|
|
2125
|
+
const result = typeArgs.every((arg, index) => arg === inputArgs[index])
|
|
2126
|
+
? input
|
|
2127
|
+
: types_1.ClassType.specialize(input, typeArgs, input.priv.isTypeArgExplicit);
|
|
2128
|
+
inputResults.set(hint, result);
|
|
2129
|
+
return result;
|
|
2130
|
+
}
|
|
1994
2131
|
// Attempts to narrow a type based on a "type(x) is y" or "type(x) is not y" check.
|
|
1995
|
-
function narrowTypeForTypeIs(evaluator, type, classTypes, isPositiveTest) {
|
|
2132
|
+
function narrowTypeForTypeIs(evaluator, type, classTypes, isPositiveTest, isIsOperator, classTypeVar, allowLegacyEquality) {
|
|
2133
|
+
const metaclassEqualityResults = isIsOperator ? undefined : new Map();
|
|
2134
|
+
const hasEqualitySemantics = allowLegacyEquality
|
|
2135
|
+
? hasDeclaredIdentityEqualitySemantics
|
|
2136
|
+
: hasIdentityEqualitySemantics;
|
|
2137
|
+
if (metaclassEqualityResults &&
|
|
2138
|
+
classTypes.some((classType) => !hasEqualitySemantics(classType, metaclassEqualityResults))) {
|
|
2139
|
+
return type;
|
|
2140
|
+
}
|
|
1996
2141
|
// We currently don't support narrowing in the negative direction
|
|
1997
2142
|
// when there are more than one class types.
|
|
1998
2143
|
if (!isPositiveTest && classTypes.length > 1) {
|
|
1999
2144
|
return type;
|
|
2000
2145
|
}
|
|
2146
|
+
// Retain the TypeVar rather than its expanded constraints so assignments and loop joins preserve correlation.
|
|
2147
|
+
if (isIsOperator && isPositiveTest && classTypeVar && (0, types_1.isAnyOrUnknown)(type)) {
|
|
2148
|
+
return classTypeVar;
|
|
2149
|
+
}
|
|
2150
|
+
let gradualArgResults;
|
|
2001
2151
|
const typesToCombine = classTypes.map((classType) => {
|
|
2002
2152
|
return evaluator.mapSubtypesExpandTypeVars(type,
|
|
2003
2153
|
/* options */ undefined, (subtype, unexpandedSubtype) => {
|
|
2004
2154
|
if ((0, types_1.isClassInstance)(subtype)) {
|
|
2005
|
-
const
|
|
2155
|
+
const isLiteral = subtype.priv.literalValue !== undefined;
|
|
2156
|
+
const instantiableSubtype = isLiteral
|
|
2157
|
+
? types_1.ClassType.cloneIncludeSubclasses(types_1.ClassType.cloneAsInstantiable(types_1.ClassType.cloneWithLiteral(subtype, undefined)),
|
|
2158
|
+
/* includeSubclasses */ false)
|
|
2159
|
+
: types_1.ClassType.cloneAsInstantiable(subtype);
|
|
2160
|
+
if (metaclassEqualityResults &&
|
|
2161
|
+
!hasEqualitySemantics(instantiableSubtype, metaclassEqualityResults)) {
|
|
2162
|
+
return unexpandedSubtype;
|
|
2163
|
+
}
|
|
2164
|
+
const matches = types_1.ClassType.isDerivedFrom(classType, instantiableSubtype);
|
|
2165
|
+
// A literal has an exact runtime class, not an arbitrary subclass.
|
|
2166
|
+
if (matches && isLiteral && !types_1.ClassType.isSameGenericClass(instantiableSubtype, classType)) {
|
|
2167
|
+
return isPositiveTest ? undefined : subtype;
|
|
2168
|
+
}
|
|
2006
2169
|
if (isPositiveTest) {
|
|
2007
2170
|
if (matches) {
|
|
2008
|
-
if (types_1.ClassType.isSameGenericClass(
|
|
2171
|
+
if (types_1.ClassType.isSameGenericClass(instantiableSubtype, classType)) {
|
|
2009
2172
|
return (0, typeUtils_1.addConditionToType)(subtype, (0, typeUtils_1.getTypeCondition)(classType));
|
|
2010
2173
|
}
|
|
2011
|
-
|
|
2174
|
+
let narrowedClass = classType;
|
|
2175
|
+
if (subtype.priv.typeArgs || subtype.priv.tupleTypeArgs) {
|
|
2176
|
+
if (classType.shared.typeParams.length > 0) {
|
|
2177
|
+
if ((0, typeUtils_1.containsAnyRecursive)(classType) ||
|
|
2178
|
+
!evaluator.assignType(subtype, types_1.ClassType.cloneAsInstance(classType))) {
|
|
2179
|
+
const genericClass = (0, typeUtils_1.selfSpecializeClass)(types_1.ClassType.specialize(classType, undefined));
|
|
2180
|
+
const constraints = new constraintTracker_1.ConstraintTracker();
|
|
2181
|
+
if (!evaluator.assignType(subtype, types_1.ClassType.cloneAsInstance(genericClass), undefined, constraints, 2 /* AssignTypeFlags.Contravariant */ |
|
|
2182
|
+
2048 /* AssignTypeFlags.PopulateExpectedType */ |
|
|
2183
|
+
4096 /* AssignTypeFlags.SkipPopulateUnknownExpectedType */)) {
|
|
2184
|
+
return (0, typeUtils_1.addConditionToType)(subtype, (0, typeUtils_1.getTypeCondition)(classType));
|
|
2185
|
+
}
|
|
2186
|
+
const specializedClass = evaluator.solveAndApplyConstraints(genericClass, constraints, {
|
|
2187
|
+
replaceUnsolved: {
|
|
2188
|
+
scopeIds: (0, typeUtils_1.getTypeVarScopeIds)(classType),
|
|
2189
|
+
useUnknown: true,
|
|
2190
|
+
tupleClassType: evaluator.getTupleClassType(),
|
|
2191
|
+
},
|
|
2192
|
+
});
|
|
2193
|
+
if (!(0, types_1.isInstantiableClass)(specializedClass)) {
|
|
2194
|
+
return (0, typeUtils_1.addConditionToType)(subtype, (0, typeUtils_1.getTypeCondition)(classType));
|
|
2195
|
+
}
|
|
2196
|
+
const results = (gradualArgResults ?? (gradualArgResults = new Map()));
|
|
2197
|
+
narrowedClass = types_1.ClassType.specialize(specializedClass, specializedClass.priv.typeArgs?.map((arg, index) => fillTypeGuardGradualArgs(arg, classType.priv.typeArgs?.[index], results)));
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
else if (!evaluator.assignType(subtype, types_1.ClassType.cloneAsInstance(classType))) {
|
|
2201
|
+
return classType.priv.includeSubclasses && !types_1.ClassType.isFinal(classType)
|
|
2202
|
+
? (0, typeUtils_1.addConditionToType)(subtype, (0, typeUtils_1.getTypeCondition)(classType))
|
|
2203
|
+
: undefined;
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
return (0, typeUtils_1.addConditionToType)(types_1.ClassType.cloneAsInstance(narrowedClass), subtype.props?.condition);
|
|
2012
2207
|
}
|
|
2013
2208
|
if (!classType.priv.includeSubclasses) {
|
|
2209
|
+
if (evaluator.assignType(subtype, types_1.ClassType.cloneAsInstance(classType))) {
|
|
2210
|
+
return (0, typeUtils_1.addConditionToType)(types_1.ClassType.cloneAsInstance(classType), (0, typeUtils_1.getTypeCondition)(subtype));
|
|
2211
|
+
}
|
|
2212
|
+
return undefined;
|
|
2213
|
+
}
|
|
2214
|
+
// A subclass of both the subtype and the class could satisfy the
|
|
2215
|
+
// comparison, so eliminate the subtype only if no such class can exist.
|
|
2216
|
+
if ((types_1.ClassType.isFinal(classType) ||
|
|
2217
|
+
isLiteral ||
|
|
2218
|
+
types_1.ClassType.isFinal(instantiableSubtype) ||
|
|
2219
|
+
areDisjointBasesIncompatible(instantiableSubtype, classType)) &&
|
|
2220
|
+
!evaluator.assignType(types_1.ClassType.cloneAsInstance(classType), subtype) &&
|
|
2221
|
+
!evaluator.assignType(subtype, types_1.ClassType.cloneAsInstance(classType))) {
|
|
2014
2222
|
return undefined;
|
|
2015
2223
|
}
|
|
2016
2224
|
if (!(0, types_1.isTypeVar)(unexpandedSubtype) || !types_1.TypeVarType.isSelf(unexpandedSubtype)) {
|
|
2017
2225
|
return (0, typeUtils_1.addConditionToType)(subtype, classType.props?.condition);
|
|
2018
2226
|
}
|
|
2019
2227
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
2228
|
+
// A final class has no subclasses, so it is treated as an exact class.
|
|
2229
|
+
if (!classType.priv.includeSubclasses || types_1.ClassType.isFinal(classType)) {
|
|
2230
|
+
// If the runtime class is exact and it matches, then
|
|
2022
2231
|
// we can eliminate it in the negative case.
|
|
2023
|
-
if (matches && types_1.ClassType.isFinal(
|
|
2232
|
+
if (matches && (isLiteral || types_1.ClassType.isFinal(instantiableSubtype))) {
|
|
2024
2233
|
return undefined;
|
|
2025
2234
|
}
|
|
2026
2235
|
// We can't eliminate the subtype in the negative
|
|
@@ -2030,6 +2239,9 @@ function narrowTypeForTypeIs(evaluator, type, classTypes, isPositiveTest) {
|
|
|
2030
2239
|
}
|
|
2031
2240
|
}
|
|
2032
2241
|
if ((0, types_1.isAnyOrUnknown)(subtype)) {
|
|
2242
|
+
if (metaclassEqualityResults && !allowLegacyEquality) {
|
|
2243
|
+
return subtype;
|
|
2244
|
+
}
|
|
2033
2245
|
return isPositiveTest
|
|
2034
2246
|
? types_1.ClassType.cloneAsInstance((0, typeUtils_1.addConditionToType)(classType, (0, typeUtils_1.getTypeCondition)(subtype)))
|
|
2035
2247
|
: subtype;
|
|
@@ -2054,6 +2266,10 @@ function hasIdentityEqualitySemantics(classType, metaclassEqualityResults) {
|
|
|
2054
2266
|
if (classType.shared.typeParams.length > 0) {
|
|
2055
2267
|
return false;
|
|
2056
2268
|
}
|
|
2269
|
+
return hasDeclaredIdentityEqualitySemantics(classType, metaclassEqualityResults);
|
|
2270
|
+
}
|
|
2271
|
+
// Legacy forward type(x) equality guards check declared metaclasses without closing subclass hierarchies.
|
|
2272
|
+
function hasDeclaredIdentityEqualitySemantics(classType, metaclassEqualityResults) {
|
|
2057
2273
|
const metaclass = classType.shared.effectiveMetaclass;
|
|
2058
2274
|
if (!metaclass ||
|
|
2059
2275
|
!(0, types_1.isInstantiableClass)(metaclass) ||
|