@zzzen/pyright-internal 1.2.0-dev.20261101 → 1.2.0-dev.20261108
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 +9 -3
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +12 -0
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +1 -1
- package/dist/analyzer/constructors.js +1 -1
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/decorators.d.ts +1 -1
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/functionTransform.d.ts +5 -0
- package/dist/analyzer/functionTransform.js +6 -3
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/missingBindingMetadata.d.ts +6 -0
- package/dist/analyzer/missingBindingMetadata.js +22 -0
- package/dist/analyzer/missingBindingMetadata.js.map +1 -0
- package/dist/analyzer/namedTuples.d.ts +4 -1
- package/dist/analyzer/namedTuples.js +1 -0
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/patternMatching.d.ts +5 -1
- package/dist/analyzer/patternMatching.js +3 -0
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +3 -0
- package/dist/analyzer/program.js +71 -1
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/tuples.d.ts +1 -1
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +1 -0
- package/dist/analyzer/typeCacheUtils.js +10 -0
- package/dist/analyzer/typeCacheUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator/boundMethodSpecialization.d.ts +15 -0
- package/dist/analyzer/typeEvaluator/boundMethodSpecialization.js +98 -0
- package/dist/analyzer/typeEvaluator/boundMethodSpecialization.js.map +1 -0
- package/dist/analyzer/typeEvaluator/classConstruction.d.ts +25 -0
- package/dist/analyzer/typeEvaluator/classConstruction.js +251 -0
- package/dist/analyzer/typeEvaluator/classConstruction.js.map +1 -0
- package/dist/analyzer/typeEvaluator/collectionInference.d.ts +41 -0
- package/dist/analyzer/typeEvaluator/collectionInference.js +695 -0
- package/dist/analyzer/typeEvaluator/collectionInference.js.map +1 -0
- package/dist/analyzer/typeEvaluator/diagnostics.d.ts +33 -0
- package/dist/analyzer/typeEvaluator/diagnostics.js +198 -0
- package/dist/analyzer/typeEvaluator/diagnostics.js.map +1 -0
- package/dist/analyzer/typeEvaluator/evaluatorCore.d.ts +80 -0
- package/dist/analyzer/typeEvaluator/evaluatorCore.js +1126 -0
- package/dist/analyzer/typeEvaluator/evaluatorCore.js.map +1 -0
- package/dist/analyzer/typeEvaluator/evaluatorNarrowing.d.ts +17 -0
- package/dist/analyzer/typeEvaluator/evaluatorNarrowing.js +370 -0
- package/dist/analyzer/typeEvaluator/evaluatorNarrowing.js.map +1 -0
- package/dist/analyzer/typeEvaluator/expressionEvaluation.d.ts +81 -0
- package/dist/analyzer/typeEvaluator/expressionEvaluation.js +1802 -0
- package/dist/analyzer/typeEvaluator/expressionEvaluation.js.map +1 -0
- package/dist/analyzer/typeEvaluator/flowAnalysis.d.ts +33 -0
- package/dist/analyzer/typeEvaluator/flowAnalysis.js +217 -0
- package/dist/analyzer/typeEvaluator/flowAnalysis.js.map +1 -0
- package/dist/analyzer/typeEvaluator/internals.d.ts +137 -0
- package/dist/analyzer/typeEvaluator/internals.js +10 -0
- package/dist/analyzer/typeEvaluator/internals.js.map +1 -0
- package/dist/analyzer/typeEvaluator/literalTypes.d.ts +3 -0
- package/dist/analyzer/typeEvaluator/literalTypes.js +52 -0
- package/dist/analyzer/typeEvaluator/literalTypes.js.map +1 -0
- package/dist/analyzer/typeEvaluator/memberResolution.d.ts +79 -0
- package/dist/analyzer/typeEvaluator/memberResolution.js +1007 -0
- package/dist/analyzer/typeEvaluator/memberResolution.js.map +1 -0
- package/dist/analyzer/typeEvaluator/overrideValidation.d.ts +15 -0
- package/dist/analyzer/typeEvaluator/overrideValidation.js +422 -0
- package/dist/analyzer/typeEvaluator/overrideValidation.js.map +1 -0
- package/dist/analyzer/typeEvaluator/returnTypeInference.d.ts +33 -0
- package/dist/analyzer/typeEvaluator/returnTypeInference.js +226 -0
- package/dist/analyzer/typeEvaluator/returnTypeInference.js.map +1 -0
- package/dist/analyzer/typeEvaluator/specialFormCreation.d.ts +39 -0
- package/dist/analyzer/typeEvaluator/specialFormCreation.js +1728 -0
- package/dist/analyzer/typeEvaluator/specialFormCreation.js.map +1 -0
- package/dist/analyzer/typeEvaluator/tupleUnpacking.d.ts +2 -0
- package/dist/analyzer/typeEvaluator/tupleUnpacking.js +36 -0
- package/dist/analyzer/typeEvaluator/tupleUnpacking.js.map +1 -0
- package/dist/analyzer/typeEvaluator/typeCompatibility.d.ts +36 -0
- package/dist/analyzer/typeEvaluator/typeCompatibility.js +1320 -0
- package/dist/analyzer/typeEvaluator/typeCompatibility.js.map +1 -0
- package/dist/analyzer/typeEvaluator/typeGuardNarrowing.d.ts +186 -0
- package/dist/analyzer/typeEvaluator/typeGuardNarrowing.js +1683 -0
- package/dist/analyzer/typeEvaluator/typeGuardNarrowing.js.map +1 -0
- package/dist/analyzer/typeEvaluator/typeVarHandling.d.ts +48 -0
- package/dist/analyzer/typeEvaluator/typeVarHandling.js +756 -0
- package/dist/analyzer/typeEvaluator/typeVarHandling.js.map +1 -0
- package/dist/analyzer/typeEvaluator.d.ts +3 -31
- package/dist/analyzer/typeEvaluator.js +5033 -13761
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +2 -2
- package/dist/analyzer/typeGuards.js +212 -1567
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.js +6 -2
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.js +111 -0
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/browser/browserConnection.d.ts +12 -0
- package/dist/browser/browserConnection.js +23 -0
- package/dist/browser/browserConnection.js.map +1 -0
- package/dist/browser/browserFileSystem.d.ts +73 -0
- package/dist/browser/browserFileSystem.js +578 -0
- package/dist/browser/browserFileSystem.js.map +1 -0
- package/dist/browser/browserHost.d.ts +4 -0
- package/dist/browser/browserHost.js +10 -0
- package/dist/browser/browserHost.js.map +1 -0
- package/dist/browser/browserProcess.d.ts +1 -0
- package/dist/browser/browserProcess.js +17 -0
- package/dist/browser/browserProcess.js.map +1 -0
- package/dist/browser/browserServer.d.ts +8 -0
- package/dist/browser/browserServer.js +32 -0
- package/dist/browser/browserServer.js.map +1 -0
- package/dist/browser/cancellation/common.d.ts +10 -0
- package/dist/browser/cancellation/common.js +114 -0
- package/dist/browser/cancellation/common.js.map +1 -0
- package/dist/browser/cancellation/objectURLReceiverStrategy.d.ts +5 -0
- package/dist/browser/cancellation/objectURLReceiverStrategy.js +37 -0
- package/dist/browser/cancellation/objectURLReceiverStrategy.js.map +1 -0
- package/dist/browser/cancellation/objectURLSenderStrategy.d.ts +7 -0
- package/dist/browser/cancellation/objectURLSenderStrategy.js +32 -0
- package/dist/browser/cancellation/objectURLSenderStrategy.js.map +1 -0
- package/dist/browser/worker.d.ts +1 -0
- package/dist/browser/worker.js +33 -0
- package/dist/browser/worker.js.map +1 -0
- package/dist/pyrightServer.d.ts +34 -0
- package/dist/pyrightServer.js +239 -0
- package/dist/pyrightServer.js.map +1 -0
- package/dist/server.d.ts +3 -23
- package/dist/server.js +12 -232
- package/dist/server.js.map +1 -1
- package/dist/tests/benchmarks/typeInferenceComparison.d.ts +1 -0
- package/dist/tests/benchmarks/typeInferenceComparison.js +1235 -0
- package/dist/tests/benchmarks/typeInferenceComparison.js.map +1 -0
- package/dist/tests/benchmarks/typeInferencePyrightEntry.d.ts +1 -0
- package/dist/tests/benchmarks/typeInferencePyrightEntry.js +53 -0
- package/dist/tests/benchmarks/typeInferencePyrightEntry.js.map +1 -0
- package/dist/tests/browserCancellation.test.d.ts +1 -0
- package/dist/tests/browserCancellation.test.js +63 -0
- package/dist/tests/browserCancellation.test.js.map +1 -0
- package/dist/tests/browserServer.test.d.ts +1 -0
- package/dist/tests/browserServer.test.js +177 -0
- package/dist/tests/browserServer.test.js.map +1 -0
- package/dist/tests/constraintSolver.test.js +45 -0
- package/dist/tests/constraintSolver.test.js.map +1 -1
- package/dist/tests/mypyPrimerAnalysis.test.js +15 -1
- package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
- package/dist/tests/typeCacheUtils.test.js +46 -0
- package/dist/tests/typeCacheUtils.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +75 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +4 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +32 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +394 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeUtils.test.js +28 -0
- package/dist/tests/typeUtils.test.js.map +1 -1
- package/dist/typeServer/stubGenerator.js +136 -3
- package/dist/typeServer/stubGenerator.js.map +1 -1
- package/dist/typeServer/typeServerConversionUtils.js +13 -0
- package/dist/typeServer/typeServerConversionUtils.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,1126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* evaluatorCore.ts
|
|
4
|
+
* Copyright (c) Microsoft Corporation.
|
|
5
|
+
* Licensed under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* evaluatorCore implementation, using evaluator-owned dependencies and state.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.createEvaluatorCore = createEvaluatorCore;
|
|
44
|
+
const collectionUtils_1 = require("../../common/collectionUtils");
|
|
45
|
+
const debug_1 = require("../../common/debug");
|
|
46
|
+
const diagnostic_1 = require("../../common/diagnostic");
|
|
47
|
+
const diagnosticRules_1 = require("../../common/diagnosticRules");
|
|
48
|
+
const localize_1 = require("../../localization/localize");
|
|
49
|
+
const constraintSolution_1 = require("../constraintSolution");
|
|
50
|
+
const constraintSolver_1 = require("../constraintSolver");
|
|
51
|
+
const constraintTracker_1 = require("../constraintTracker");
|
|
52
|
+
const constructors_1 = require("../constructors");
|
|
53
|
+
const decorators_1 = require("../decorators");
|
|
54
|
+
const ParseTreeUtils = __importStar(require("../parseTreeUtils"));
|
|
55
|
+
const ScopeUtils = __importStar(require("../scopeUtils"));
|
|
56
|
+
const symbolNameUtils_1 = require("../symbolNameUtils");
|
|
57
|
+
const symbolUtils_1 = require("../symbolUtils");
|
|
58
|
+
const tuples_1 = require("../tuples");
|
|
59
|
+
const types_1 = require("../types");
|
|
60
|
+
const typeUtils_1 = require("../typeUtils");
|
|
61
|
+
// Shared type-expression and specialization operations not yet isolated into narrower topics.
|
|
62
|
+
function createEvaluatorCore(contextDependencies) {
|
|
63
|
+
const { createSpecializedClassType, addDiagnostic, assignType, evaluatorInterface, getEffectiveTypeOfSymbol, getScopeForNode, getScopeIdForNode, getTypeOfBoundMember, getTypeOfExpression, getTypeOfExpressionExpectingType, inferReturnTypeIfNecessary, isTypeFormClass, isTypePromotionRelated, makeTopLevelTypeVarsConcrete, nodeInfo, printType, stripLiteralValue, suppressDiagnostics, validateCallArgs, } = contextDependencies;
|
|
64
|
+
function validateTypeIsInstantiable(typeResult, flags, node) {
|
|
65
|
+
// If the type is incomplete, don't log any diagnostics yet.
|
|
66
|
+
if (typeResult.isIncomplete) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if ((flags & 64 /* EvalFlags.NoTypeVarTuple */) !== 0) {
|
|
70
|
+
if ((0, types_1.isTypeVarTuple)(typeResult.type) && !typeResult.type.priv.isInUnion) {
|
|
71
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeVarTupleContext(), node);
|
|
72
|
+
typeResult.type = types_1.UnknownType.create();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if ((0, typeUtils_1.isEffectivelyInstantiable)(typeResult.type, { honorTypeVarBounds: true })) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Exempt ellipses.
|
|
79
|
+
if ((0, types_1.isClassInstance)(typeResult.type) && types_1.ClassType.isBuiltIn(typeResult.type, ['EllipsisType', 'ellipsis'])) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Emit these errors only if we know we're evaluating a type expression.
|
|
83
|
+
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
84
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
|
85
|
+
if ((0, types_1.isUnion)(typeResult.type)) {
|
|
86
|
+
(0, typeUtils_1.doForEachSubtype)(typeResult.type, (subtype) => {
|
|
87
|
+
if (!(0, typeUtils_1.isEffectivelyInstantiable)(subtype, { honorTypeVarBounds: true })) {
|
|
88
|
+
diag.addMessage(localize_1.LocAddendum.typeNotClass().format({ type: printType(subtype) }));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeExpectedClass().format({ type: printType(typeResult.type) }) + diag.getString(), node);
|
|
93
|
+
typeResult.type = types_1.UnknownType.create();
|
|
94
|
+
}
|
|
95
|
+
typeResult.typeErrors = true;
|
|
96
|
+
}
|
|
97
|
+
function solveAndApplyConstraints(type, constraints, applyOptions, solveOptions) {
|
|
98
|
+
const solution = (0, constraintSolver_1.solveConstraints)(evaluatorInterface, constraints, solveOptions);
|
|
99
|
+
return (0, typeUtils_1.applySolvedTypeVars)(type, solution, applyOptions);
|
|
100
|
+
}
|
|
101
|
+
function getBoundMagicMethod(classType, memberName, selfType, errorNode, diag, recursionCount = 0) {
|
|
102
|
+
const boundMethodResult = getTypeOfBoundMember(errorNode, classType, memberName,
|
|
103
|
+
/* usage */ undefined, diag, 16 /* MemberAccessFlags.SkipInstanceMembers */ | 512 /* MemberAccessFlags.SkipAttributeAccessOverride */, selfType, recursionCount);
|
|
104
|
+
if (!boundMethodResult || boundMethodResult.typeErrors) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
if ((0, types_1.isFunctionOrOverloaded)(boundMethodResult.type)) {
|
|
108
|
+
return boundMethodResult.type;
|
|
109
|
+
}
|
|
110
|
+
if ((0, types_1.isClassInstance)(boundMethodResult.type)) {
|
|
111
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
recursionCount++;
|
|
115
|
+
return getBoundMagicMethod(boundMethodResult.type, '__call__',
|
|
116
|
+
/* selfType */ undefined, errorNode, diag, recursionCount);
|
|
117
|
+
}
|
|
118
|
+
if ((0, types_1.isAnyOrUnknown)(boundMethodResult.type)) {
|
|
119
|
+
return (0, typeUtils_1.getUnknownTypeForCallable)();
|
|
120
|
+
}
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
function getTypeOfAwaitable(typeResult, errorNode) {
|
|
124
|
+
if (!contextDependencies.prefetched?.awaitableClass ||
|
|
125
|
+
!(0, types_1.isInstantiableClass)(contextDependencies.prefetched.awaitableClass) ||
|
|
126
|
+
contextDependencies.prefetched.awaitableClass.shared.typeParams.length !== 1) {
|
|
127
|
+
return { type: types_1.UnknownType.create(), isIncomplete: typeResult.isIncomplete };
|
|
128
|
+
}
|
|
129
|
+
const awaitableProtocolObj = types_1.ClassType.cloneAsInstance(contextDependencies.prefetched.awaitableClass);
|
|
130
|
+
const isIncomplete = !!typeResult.isIncomplete;
|
|
131
|
+
const type = (0, typeUtils_1.mapSubtypes)(typeResult.type, (subtype) => {
|
|
132
|
+
subtype = makeTopLevelTypeVarsConcrete(subtype);
|
|
133
|
+
if ((0, types_1.isAnyOrUnknown)(subtype)) {
|
|
134
|
+
return subtype;
|
|
135
|
+
}
|
|
136
|
+
const diag = errorNode ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
|
137
|
+
if ((0, types_1.isClassInstance)(subtype)) {
|
|
138
|
+
const constraints = new constraintTracker_1.ConstraintTracker();
|
|
139
|
+
if (assignType(awaitableProtocolObj, subtype, diag, constraints)) {
|
|
140
|
+
const specializedType = solveAndApplyConstraints(awaitableProtocolObj, constraints);
|
|
141
|
+
if ((0, types_1.isClass)(specializedType) &&
|
|
142
|
+
specializedType.priv.typeArgs &&
|
|
143
|
+
specializedType.priv.typeArgs.length > 0) {
|
|
144
|
+
return specializedType.priv.typeArgs[0];
|
|
145
|
+
}
|
|
146
|
+
return types_1.UnknownType.create();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (errorNode && !typeResult.isIncomplete) {
|
|
150
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeNotAwaitable().format({ type: printType(subtype) }) + diag?.getString(), errorNode);
|
|
151
|
+
}
|
|
152
|
+
return types_1.UnknownType.create();
|
|
153
|
+
});
|
|
154
|
+
return { type, isIncomplete };
|
|
155
|
+
}
|
|
156
|
+
function isTypeHashable(type) {
|
|
157
|
+
let isTypeHashable = true;
|
|
158
|
+
(0, typeUtils_1.doForEachSubtype)(makeTopLevelTypeVarsConcrete(type), (subtype) => {
|
|
159
|
+
if ((0, types_1.isClassInstance)(subtype)) {
|
|
160
|
+
// Assume the class is hashable.
|
|
161
|
+
let isObjectHashable = true;
|
|
162
|
+
// Have we already computed and cached the hashability?
|
|
163
|
+
if (subtype.shared.isInstanceHashable !== undefined) {
|
|
164
|
+
isObjectHashable = subtype.shared.isInstanceHashable;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const hashMember = (0, typeUtils_1.lookUpObjectMember)(subtype, '__hash__', 4 /* MemberAccessFlags.SkipObjectBaseClass */);
|
|
168
|
+
if (hashMember && hashMember.isTypeDeclared) {
|
|
169
|
+
const decls = hashMember.symbol.getTypedDeclarations();
|
|
170
|
+
const synthesizedType = hashMember.symbol.getSynthesizedType();
|
|
171
|
+
// Handle the case where the type is synthesized (used for
|
|
172
|
+
// dataclasses).
|
|
173
|
+
if (synthesizedType) {
|
|
174
|
+
isObjectHashable = !(0, typeUtils_1.isNoneInstance)(synthesizedType.type);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
// Assume that if '__hash__' is declared as a variable, it is
|
|
178
|
+
// not hashable. If it's declared as a function, it is. We'll
|
|
179
|
+
// skip evaluating its full type because that's not needed in
|
|
180
|
+
// this case.
|
|
181
|
+
if (decls.every((decl) => decl.type === 1 /* DeclarationType.Variable */)) {
|
|
182
|
+
isObjectHashable = false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Cache the hashability for next time.
|
|
187
|
+
subtype.shared.isInstanceHashable = isObjectHashable;
|
|
188
|
+
}
|
|
189
|
+
if (!isObjectHashable) {
|
|
190
|
+
isTypeHashable = false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
return isTypeHashable;
|
|
195
|
+
}
|
|
196
|
+
function getTypedDictClassType() {
|
|
197
|
+
return contextDependencies.prefetched?.typedDictPrivateClass &&
|
|
198
|
+
(0, types_1.isInstantiableClass)(contextDependencies.prefetched.typedDictPrivateClass)
|
|
199
|
+
? contextDependencies.prefetched.typedDictPrivateClass
|
|
200
|
+
: undefined;
|
|
201
|
+
}
|
|
202
|
+
function getTupleClassType() {
|
|
203
|
+
return contextDependencies.prefetched?.tupleClass &&
|
|
204
|
+
(0, types_1.isInstantiableClass)(contextDependencies.prefetched.tupleClass)
|
|
205
|
+
? contextDependencies.prefetched.tupleClass
|
|
206
|
+
: undefined;
|
|
207
|
+
}
|
|
208
|
+
function getDictClassType() {
|
|
209
|
+
return contextDependencies.prefetched?.dictClass &&
|
|
210
|
+
(0, types_1.isInstantiableClass)(contextDependencies.prefetched.dictClass)
|
|
211
|
+
? contextDependencies.prefetched.dictClass
|
|
212
|
+
: undefined;
|
|
213
|
+
}
|
|
214
|
+
function getStrClassType() {
|
|
215
|
+
return contextDependencies.prefetched?.strClass && (0, types_1.isInstantiableClass)(contextDependencies.prefetched.strClass)
|
|
216
|
+
? contextDependencies.prefetched.strClass
|
|
217
|
+
: undefined;
|
|
218
|
+
}
|
|
219
|
+
function getObjectType() {
|
|
220
|
+
return contextDependencies.prefetched?.objectClass
|
|
221
|
+
? (0, typeUtils_1.convertToInstance)(contextDependencies.prefetched.objectClass)
|
|
222
|
+
: types_1.UnknownType.create();
|
|
223
|
+
}
|
|
224
|
+
function getNoneType() {
|
|
225
|
+
return contextDependencies.prefetched?.noneTypeClass
|
|
226
|
+
? (0, typeUtils_1.convertToInstance)(contextDependencies.prefetched.noneTypeClass)
|
|
227
|
+
: types_1.UnknownType.create();
|
|
228
|
+
}
|
|
229
|
+
function getUnionClassType() {
|
|
230
|
+
return contextDependencies.prefetched?.unionTypeClass ?? types_1.UnknownType.create();
|
|
231
|
+
}
|
|
232
|
+
function getTypeClassType() {
|
|
233
|
+
if (contextDependencies.prefetched?.typeClass &&
|
|
234
|
+
(0, types_1.isInstantiableClass)(contextDependencies.prefetched.typeClass)) {
|
|
235
|
+
return contextDependencies.prefetched.typeClass;
|
|
236
|
+
}
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
function verifyRaiseExceptionType(node, allowNone) {
|
|
240
|
+
const baseExceptionType = getBuiltInType(node, 'BaseException');
|
|
241
|
+
const exceptionType = getTypeOfExpression(node).type;
|
|
242
|
+
// Validate that the argument of "raise" is an exception object or class.
|
|
243
|
+
// If it is a class, validate that the class's constructor accepts zero
|
|
244
|
+
// arguments.
|
|
245
|
+
if (exceptionType && baseExceptionType && (0, types_1.isInstantiableClass)(baseExceptionType)) {
|
|
246
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
|
247
|
+
(0, typeUtils_1.doForEachSubtype)(exceptionType, (subtype) => {
|
|
248
|
+
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
|
249
|
+
if ((0, types_1.isAnyOrUnknown)(concreteSubtype) || (0, types_1.isNever)(concreteSubtype)) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (allowNone && (0, typeUtils_1.isNoneInstance)(concreteSubtype)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if ((0, types_1.isInstantiableClass)(concreteSubtype) && concreteSubtype.priv.literalValue === undefined) {
|
|
256
|
+
if (!(0, typeUtils_1.derivesFromClassRecursive)(concreteSubtype, baseExceptionType, /* ignoreUnknown */ false)) {
|
|
257
|
+
diag.addMessage(localize_1.LocMessage.exceptionTypeIncorrect().format({
|
|
258
|
+
type: printType(subtype),
|
|
259
|
+
}));
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
let callResult;
|
|
263
|
+
suppressDiagnostics(node, () => {
|
|
264
|
+
callResult = (0, constructors_1.validateConstructorArgs)(evaluatorInterface, node, [], concreteSubtype,
|
|
265
|
+
/* skipUnknownArgCheck */ false,
|
|
266
|
+
/* inferenceContext */ undefined);
|
|
267
|
+
});
|
|
268
|
+
if (callResult && callResult.argumentErrors) {
|
|
269
|
+
diag.addMessage(localize_1.LocMessage.exceptionTypeNotInstantiable().format({
|
|
270
|
+
type: printType(subtype),
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else if ((0, types_1.isClassInstance)(concreteSubtype)) {
|
|
276
|
+
if (!(0, typeUtils_1.derivesFromClassRecursive)(types_1.ClassType.cloneAsInstantiable(concreteSubtype), baseExceptionType,
|
|
277
|
+
/* ignoreUnknown */ false)) {
|
|
278
|
+
diag.addMessage(localize_1.LocMessage.exceptionTypeIncorrect().format({
|
|
279
|
+
type: printType(subtype),
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
diag.addMessage(localize_1.LocMessage.exceptionTypeIncorrect().format({
|
|
285
|
+
type: printType(subtype),
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
if (!diag.isEmpty()) {
|
|
290
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.expectedExceptionClass() + diag.getString(), node);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function isSymbolValidTypeExpression(type, includesVarDecl) {
|
|
295
|
+
// Verify that the name does not refer to a (non type alias) variable.
|
|
296
|
+
if (!includesVarDecl || type.props?.typeAliasInfo) {
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
if ((0, typeUtils_1.isTypeAliasPlaceholder)(type)) {
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
if ((0, types_1.isTypeVar)(type)) {
|
|
303
|
+
if (type.props?.specialForm || type.props?.typeAliasInfo) {
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// Exempts class types that are created by calling NewType, NamedTuple, etc.
|
|
308
|
+
if ((0, types_1.isClass)(type) && !type.priv.includeSubclasses && types_1.ClassType.isValidTypeAliasClass(type)) {
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
if ((0, typeUtils_1.isSentinelLiteral)(type)) {
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
function convertSpecialFormToRuntimeValue(type, flags, convertModule = false) {
|
|
317
|
+
const exemptFlags = 256 /* EvalFlags.TypeExpression */ | 128 /* EvalFlags.InstantiableType */ | 33554432 /* EvalFlags.NoConvertSpecialForm */;
|
|
318
|
+
if ((flags & exemptFlags) !== 0) {
|
|
319
|
+
return type;
|
|
320
|
+
}
|
|
321
|
+
if (convertModule &&
|
|
322
|
+
(0, types_1.isModule)(type) &&
|
|
323
|
+
contextDependencies.prefetched?.moduleTypeClass &&
|
|
324
|
+
(0, types_1.isInstantiableClass)(contextDependencies.prefetched.moduleTypeClass)) {
|
|
325
|
+
return types_1.ClassType.cloneAsInstance(contextDependencies.prefetched.moduleTypeClass);
|
|
326
|
+
}
|
|
327
|
+
// Isinstance treats traditional (non-PEP 695) type aliases that are unions
|
|
328
|
+
// as tuples of classes rather than unions.
|
|
329
|
+
if ((flags & 536870912 /* EvalFlags.IsinstanceArg */) !== 0) {
|
|
330
|
+
if ((0, types_1.isUnion)(type) && type.props?.typeAliasInfo && !type.props.typeAliasInfo.shared.isTypeAliasType) {
|
|
331
|
+
return type;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (!type.props?.specialForm) {
|
|
335
|
+
return type;
|
|
336
|
+
}
|
|
337
|
+
// If this is a type alias and we are not supposed to specialize it, return it as is.
|
|
338
|
+
if ((flags & 2 /* EvalFlags.NoSpecialize */) !== 0 && type.props?.typeAliasInfo) {
|
|
339
|
+
// Special-case TypeAliasType which should be converted in this case.
|
|
340
|
+
if (!types_1.ClassType.isBuiltIn(type.props.specialForm, 'TypeAliasType')) {
|
|
341
|
+
return type;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (type.props?.typeForm) {
|
|
345
|
+
return types_1.TypeBase.cloneWithTypeForm(type.props.specialForm, type.props.typeForm);
|
|
346
|
+
}
|
|
347
|
+
return type.props.specialForm;
|
|
348
|
+
}
|
|
349
|
+
function reportMissingTypeArgs(node, type, flags) {
|
|
350
|
+
if ((flags & 2 /* EvalFlags.NoSpecialize */) !== 0) {
|
|
351
|
+
return type;
|
|
352
|
+
}
|
|
353
|
+
// Is this a generic class that needs to be specialized?
|
|
354
|
+
if ((0, types_1.isInstantiableClass)(type)) {
|
|
355
|
+
if ((flags & 128 /* EvalFlags.InstantiableType */) !== 0 && (flags & 512 /* EvalFlags.AllowMissingTypeArgs */) === 0) {
|
|
356
|
+
if (!type.props?.typeAliasInfo && !isTypeFormClass(type) && (0, typeUtils_1.requiresTypeArgs)(type)) {
|
|
357
|
+
if (!type.priv.typeArgs || !type.priv.isTypeArgExplicit) {
|
|
358
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.LocMessage.typeArgsMissingForClass().format({
|
|
359
|
+
name: type.priv.aliasName || type.shared.name,
|
|
360
|
+
}), node);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (!type.priv.typeArgs) {
|
|
365
|
+
type = createSpecializedClassType(type, /* typeArgs */ undefined, flags, node)?.type;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// Is this a generic type alias that needs to be specialized?
|
|
369
|
+
if ((flags & 128 /* EvalFlags.InstantiableType */) !== 0) {
|
|
370
|
+
type = specializeTypeAliasWithDefaults(type, node);
|
|
371
|
+
}
|
|
372
|
+
return type;
|
|
373
|
+
}
|
|
374
|
+
function specializeTypeAliasWithDefaults(type, errorNode) {
|
|
375
|
+
// Is this a type alias?
|
|
376
|
+
const aliasInfo = type.props?.typeAliasInfo;
|
|
377
|
+
if (!aliasInfo) {
|
|
378
|
+
return type;
|
|
379
|
+
}
|
|
380
|
+
// Is this a generic type alias that needs specializing?
|
|
381
|
+
if (!aliasInfo.shared.typeParams || aliasInfo.shared.typeParams.length === 0 || aliasInfo.typeArgs) {
|
|
382
|
+
return type;
|
|
383
|
+
}
|
|
384
|
+
let reportDiag = false;
|
|
385
|
+
const defaultTypeArgs = [];
|
|
386
|
+
const constraints = new constraintTracker_1.ConstraintTracker();
|
|
387
|
+
aliasInfo.shared.typeParams.forEach((param) => {
|
|
388
|
+
if (!param.shared.isDefaultExplicit) {
|
|
389
|
+
reportDiag = true;
|
|
390
|
+
}
|
|
391
|
+
let defaultType;
|
|
392
|
+
if (param.shared.isDefaultExplicit || (0, types_1.isParamSpec)(param)) {
|
|
393
|
+
defaultType = solveAndApplyConstraints(param, constraints, {
|
|
394
|
+
replaceUnsolved: {
|
|
395
|
+
scopeIds: [aliasInfo.shared.typeVarScopeId],
|
|
396
|
+
tupleClassType: getTupleClassType(),
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
else if ((0, types_1.isTypeVarTuple)(param) &&
|
|
401
|
+
contextDependencies.prefetched?.tupleClass &&
|
|
402
|
+
(0, types_1.isInstantiableClass)(contextDependencies.prefetched.tupleClass)) {
|
|
403
|
+
defaultType = (0, tuples_1.makeTupleObject)(evaluatorInterface, [{ type: types_1.UnknownType.create(), isUnbounded: true }],
|
|
404
|
+
/* isUnpacked */ true);
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
defaultType = types_1.UnknownType.create();
|
|
408
|
+
}
|
|
409
|
+
defaultTypeArgs.push(defaultType);
|
|
410
|
+
constraints.setBounds(param, defaultType);
|
|
411
|
+
});
|
|
412
|
+
if (reportDiag && errorNode) {
|
|
413
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.LocMessage.typeArgsMissingForAlias().format({
|
|
414
|
+
name: aliasInfo.shared.name,
|
|
415
|
+
}), errorNode);
|
|
416
|
+
}
|
|
417
|
+
type = types_1.TypeBase.cloneForTypeAlias(solveAndApplyConstraints(type, constraints, {
|
|
418
|
+
replaceUnsolved: {
|
|
419
|
+
scopeIds: [aliasInfo.shared.typeVarScopeId],
|
|
420
|
+
tupleClassType: getTupleClassType(),
|
|
421
|
+
},
|
|
422
|
+
}), { ...aliasInfo, typeArgs: defaultTypeArgs });
|
|
423
|
+
return type;
|
|
424
|
+
}
|
|
425
|
+
function buildTupleTypesList(entryTypeResults, stripLiterals, convertModule) {
|
|
426
|
+
const entryTypes = [];
|
|
427
|
+
for (const typeResult of entryTypeResults) {
|
|
428
|
+
let possibleUnpackedTuple;
|
|
429
|
+
if (typeResult.unpackedType) {
|
|
430
|
+
possibleUnpackedTuple = typeResult.unpackedType;
|
|
431
|
+
}
|
|
432
|
+
else if ((0, types_1.isUnpacked)(typeResult.type)) {
|
|
433
|
+
possibleUnpackedTuple = typeResult.type;
|
|
434
|
+
}
|
|
435
|
+
// Is this an unpacked tuple? If so, we can append the individual
|
|
436
|
+
// unpacked entries onto the new tuple. If it's not an upacked tuple
|
|
437
|
+
// but some other iterator (e.g. a List), we won't know the number of
|
|
438
|
+
// items, so we'll need to leave the Tuple open-ended.
|
|
439
|
+
if (possibleUnpackedTuple &&
|
|
440
|
+
(0, types_1.isClassInstance)(possibleUnpackedTuple) &&
|
|
441
|
+
possibleUnpackedTuple.priv.tupleTypeArgs) {
|
|
442
|
+
const typeArgs = possibleUnpackedTuple.priv.tupleTypeArgs;
|
|
443
|
+
if (!typeArgs) {
|
|
444
|
+
entryTypes.push({ type: types_1.UnknownType.create(), isUnbounded: true });
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
(0, collectionUtils_1.appendArray)(entryTypes, typeArgs);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
else if ((0, types_1.isNever)(typeResult.type) && typeResult.isIncomplete && !typeResult.unpackedType) {
|
|
451
|
+
entryTypes.push({ type: types_1.UnknownType.create(/* isIncomplete */ true), isUnbounded: false });
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
let entryType = convertSpecialFormToRuntimeValue(typeResult.type, 0 /* EvalFlags.None */, convertModule);
|
|
455
|
+
entryType = stripLiterals ? (0, typeUtils_1.stripTypeForm)(stripLiteralValue(entryType)) : entryType;
|
|
456
|
+
entryTypes.push({ type: entryType, isUnbounded: !!typeResult.unpackedType });
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// If there are multiple unbounded entries, combine all of them into a single
|
|
460
|
+
// unbounded entry to avoid violating the invariant that there can be at most
|
|
461
|
+
// one unbounded entry in a tuple.
|
|
462
|
+
if (entryTypes.filter((t) => t.isUnbounded).length > 1) {
|
|
463
|
+
const firstUnboundedEntryIndex = entryTypes.findIndex((t) => t.isUnbounded);
|
|
464
|
+
const removedEntries = entryTypes.splice(firstUnboundedEntryIndex);
|
|
465
|
+
entryTypes.push({ type: (0, types_1.combineTypes)(removedEntries.map((t) => t.type)), isUnbounded: true });
|
|
466
|
+
}
|
|
467
|
+
return entryTypes;
|
|
468
|
+
}
|
|
469
|
+
function convertNodeToArg(node) {
|
|
470
|
+
return {
|
|
471
|
+
argCategory: node.d.argCategory,
|
|
472
|
+
name: node.d.name,
|
|
473
|
+
valueExpression: node.d.valueExpr,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
// Include all arguments even when the error node isn't a call, as in __init_subclass__ validation.
|
|
477
|
+
function getSpeculativeNodeForCall(errorNode) {
|
|
478
|
+
// If the error node is within an arg, expand to include the parent of the arg list.
|
|
479
|
+
const argParent = ParseTreeUtils.getParentNodeOfType(errorNode, 1 /* ParseNodeType.Argument */);
|
|
480
|
+
if (argParent?.parent) {
|
|
481
|
+
return argParent.parent;
|
|
482
|
+
}
|
|
483
|
+
// If the error node is the name in a class declaration, expand to include the class node.
|
|
484
|
+
if (errorNode.nodeType === 38 /* ParseNodeType.Name */ &&
|
|
485
|
+
errorNode.parent?.nodeType === 10 /* ParseNodeType.Class */ &&
|
|
486
|
+
errorNode.parent.d.name === errorNode) {
|
|
487
|
+
return errorNode.parent;
|
|
488
|
+
}
|
|
489
|
+
return errorNode;
|
|
490
|
+
}
|
|
491
|
+
function getAbstractSymbolInfo(classType, symbolName) {
|
|
492
|
+
const isProtocolClass = types_1.ClassType.isProtocolClass(classType);
|
|
493
|
+
const symbol = types_1.ClassType.getSymbolTable(classType).get(symbolName);
|
|
494
|
+
if (!symbol) {
|
|
495
|
+
return undefined;
|
|
496
|
+
}
|
|
497
|
+
// Ignore instance variables. Also, ignore named tuple members, which are
|
|
498
|
+
// modeled in pyright as instance variables, but their runtime implementation
|
|
499
|
+
// uses a descriptor object.
|
|
500
|
+
if (!symbol.isClassMember() && !symbol.isNamedTupleMemberMember()) {
|
|
501
|
+
return undefined;
|
|
502
|
+
}
|
|
503
|
+
const lastDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(symbol);
|
|
504
|
+
if (!lastDecl) {
|
|
505
|
+
return undefined;
|
|
506
|
+
}
|
|
507
|
+
// Handle protocol variables specially.
|
|
508
|
+
if (isProtocolClass && lastDecl.type === 1 /* DeclarationType.Variable */) {
|
|
509
|
+
// If none of the declarations involve assignments, assume it's
|
|
510
|
+
// not implemented in the protocol.
|
|
511
|
+
const allDecls = symbol.getDeclarations();
|
|
512
|
+
if (!allDecls.some((decl) => decl.type === 1 /* DeclarationType.Variable */ && !!decl.inferredTypeSource)) {
|
|
513
|
+
return { symbol, symbolName, classType, hasImplementation: false };
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (lastDecl.type !== 5 /* DeclarationType.Function */) {
|
|
517
|
+
return undefined;
|
|
518
|
+
}
|
|
519
|
+
let isAbstract = false;
|
|
520
|
+
const lastFunctionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, lastDecl.node,
|
|
521
|
+
/* isInClass */ true, nodeInfo);
|
|
522
|
+
if ((lastFunctionInfo.flags & 8 /* FunctionTypeFlags.AbstractMethod */) !== 0) {
|
|
523
|
+
isAbstract = true;
|
|
524
|
+
}
|
|
525
|
+
const isStubFile = nodeInfo.getFileInfo(lastDecl.node).isStubFile;
|
|
526
|
+
// In an overloaded method, the first overload can also be marked abstract.
|
|
527
|
+
// In stub files, there is no implementation, so this is the only way to mark
|
|
528
|
+
// an overloaded method as abstract.
|
|
529
|
+
const firstDecl = symbol.getDeclarations()[0];
|
|
530
|
+
let firstFunctionInfo;
|
|
531
|
+
if (firstDecl !== lastDecl && firstDecl.type === 5 /* DeclarationType.Function */) {
|
|
532
|
+
firstFunctionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, firstDecl.node,
|
|
533
|
+
/* isInClass */ true, nodeInfo);
|
|
534
|
+
if ((firstFunctionInfo.flags & 8 /* FunctionTypeFlags.AbstractMethod */) !== 0) {
|
|
535
|
+
isAbstract = true;
|
|
536
|
+
}
|
|
537
|
+
// If there's no implementation, assume it's unimplemented.
|
|
538
|
+
if (isProtocolClass && (lastFunctionInfo.flags & 256 /* FunctionTypeFlags.Overloaded */) !== 0) {
|
|
539
|
+
// If this is a protocol class method defined in a stub file and
|
|
540
|
+
// it's not marked abstract, assume it's not abstract and implemented.
|
|
541
|
+
if (isProtocolClass && !isAbstract && isStubFile) {
|
|
542
|
+
return undefined;
|
|
543
|
+
}
|
|
544
|
+
return { symbol, symbolName, classType, hasImplementation: false };
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
// In a non-protocol class, if the method isn't explicitly marked abstract,
|
|
548
|
+
// then it's not abstract.
|
|
549
|
+
if (!isProtocolClass && !isAbstract) {
|
|
550
|
+
return undefined;
|
|
551
|
+
}
|
|
552
|
+
const hasImplementation = !ParseTreeUtils.isSuiteEmpty(lastDecl.node.d.suite) && !methodAlwaysRaisesNotImplemented(lastDecl);
|
|
553
|
+
// If this is a protocol class, the method isn't explicitly marked
|
|
554
|
+
// as abstract, and there is an implementation, then it's a default
|
|
555
|
+
// implementation, and it's not considered abstract. If it's in a stub
|
|
556
|
+
// file, assume it's implemented in this case.
|
|
557
|
+
if (isProtocolClass && !isAbstract) {
|
|
558
|
+
if (hasImplementation || isStubFile) {
|
|
559
|
+
return undefined;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return { symbol, symbolName, classType, hasImplementation };
|
|
563
|
+
}
|
|
564
|
+
function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, constraints, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
|
565
|
+
const callDiag = new diagnostic_1.DiagnosticAddendum();
|
|
566
|
+
const callMethodResult = getTypeOfBoundMember(errorNode, expandedCallType, '__call__',
|
|
567
|
+
/* usage */ undefined, callDiag, 16 /* MemberAccessFlags.SkipInstanceMembers */ | 512 /* MemberAccessFlags.SkipAttributeAccessOverride */,
|
|
568
|
+
/* selfType */ undefined, recursionCount);
|
|
569
|
+
const callMethodType = callMethodResult?.type;
|
|
570
|
+
if (!callMethodType || callMethodResult.typeErrors) {
|
|
571
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.objectNotCallable().format({
|
|
572
|
+
type: printType(expandedCallType),
|
|
573
|
+
}) + callDiag.getString(), errorNode);
|
|
574
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
|
575
|
+
}
|
|
576
|
+
const callResult = validateCallArgs(errorNode, argList, { type: callMethodType }, constraints, skipUnknownArgCheck, inferenceContext, recursionCount);
|
|
577
|
+
let returnType = callResult.returnType ?? types_1.UnknownType.create();
|
|
578
|
+
if ((0, types_1.isTypeVar)(unexpandedCallType) &&
|
|
579
|
+
types_1.TypeBase.isInstantiable(unexpandedCallType) &&
|
|
580
|
+
(0, types_1.isClass)(expandedCallType) &&
|
|
581
|
+
types_1.ClassType.isBuiltIn(expandedCallType, 'type')) {
|
|
582
|
+
// Handle the case where a type[T] is being called. We presume this
|
|
583
|
+
// will instantiate an object of type T.
|
|
584
|
+
returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
|
|
585
|
+
}
|
|
586
|
+
return {
|
|
587
|
+
returnType,
|
|
588
|
+
argumentErrors: callResult.argumentErrors,
|
|
589
|
+
overloadsUsedForCall: callResult.overloadsUsedForCall,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
function adjustCallableReturnType(callNode, returnType, liveTypeVarScopes) {
|
|
593
|
+
if (!(0, types_1.isFunction)(returnType)) {
|
|
594
|
+
return returnType;
|
|
595
|
+
}
|
|
596
|
+
// What type variables are referenced in the callable return type? Do not include any live type variables.
|
|
597
|
+
const typeParams = (0, typeUtils_1.getTypeVarArgsRecursive)(returnType).filter((t) => !liveTypeVarScopes.some((scopeId) => t.priv.scopeId === scopeId));
|
|
598
|
+
// If there are no unsolved type variables, we're done. If there are
|
|
599
|
+
// unsolved type variables, rescope them to the callable.
|
|
600
|
+
if (typeParams.length === 0) {
|
|
601
|
+
return returnType;
|
|
602
|
+
}
|
|
603
|
+
inferReturnTypeIfNecessary(returnType);
|
|
604
|
+
// Create a new scope ID based on the caller's position. This
|
|
605
|
+
// will guarantee uniqueness. If another caller uses the same
|
|
606
|
+
// call and arguments, the type vars will not conflict.
|
|
607
|
+
const newScopeId = getScopeIdForNode(callNode);
|
|
608
|
+
const solution = new constraintSolution_1.ConstraintSolution();
|
|
609
|
+
const newTypeParams = typeParams.map((typeVar) => {
|
|
610
|
+
const newTypeParam = types_1.TypeVarType.cloneForScopeId(typeVar, newScopeId, typeVar.priv.scopeName, 1 /* TypeVarScopeType.Function */);
|
|
611
|
+
solution.setType(typeVar, newTypeParam);
|
|
612
|
+
return newTypeParam;
|
|
613
|
+
});
|
|
614
|
+
return (0, typeUtils_1.applySolvedTypeVars)(types_1.FunctionType.cloneWithNewTypeVarScopeId(returnType, newScopeId,
|
|
615
|
+
/* constructorTypeVarScopeId */ undefined, newTypeParams), solution);
|
|
616
|
+
}
|
|
617
|
+
function getFunctionFullName(functionNode, moduleName, functionName) {
|
|
618
|
+
const nameParts = [functionName];
|
|
619
|
+
let curNode = functionNode;
|
|
620
|
+
// Walk the parse tree looking for classes or functions.
|
|
621
|
+
while (curNode) {
|
|
622
|
+
curNode = ParseTreeUtils.getEnclosingClassOrFunction(curNode);
|
|
623
|
+
if (curNode) {
|
|
624
|
+
nameParts.push(curNode.d.name.d.value);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
nameParts.push(moduleName);
|
|
628
|
+
return nameParts.reverse().join('.');
|
|
629
|
+
}
|
|
630
|
+
function reportPossibleUnknownAssignment(diagLevel, rule, target, type, errorNode, ignoreEmptyContainers) {
|
|
631
|
+
// Don't bother if the feature is disabled.
|
|
632
|
+
if (diagLevel === 'none') {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
const nameValue = target.d.value;
|
|
636
|
+
// Sometimes variables contain an "unbound" type if they're
|
|
637
|
+
// assigned only within conditional statements. Remove this
|
|
638
|
+
// to avoid confusion.
|
|
639
|
+
const simplifiedType = (0, types_1.removeUnbound)(type);
|
|
640
|
+
if ((0, types_1.isUnknown)(simplifiedType)) {
|
|
641
|
+
addDiagnostic(rule, localize_1.LocMessage.typeUnknown().format({ name: nameValue }), errorNode);
|
|
642
|
+
}
|
|
643
|
+
else if ((0, typeUtils_1.isPartlyUnknown)(simplifiedType)) {
|
|
644
|
+
// If ignoreEmptyContainers is true, don't report the problem for
|
|
645
|
+
// empty containers (lists or dictionaries). We'll report the problem
|
|
646
|
+
// only if the assigned value is used later.
|
|
647
|
+
if (!ignoreEmptyContainers || !(0, types_1.isClassInstance)(type) || !type.priv.isEmptyContainer) {
|
|
648
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
|
649
|
+
diagAddendum.addMessage(localize_1.LocAddendum.typeOfSymbol().format({
|
|
650
|
+
name: nameValue,
|
|
651
|
+
type: printType(simplifiedType, { expandTypeAlias: true }),
|
|
652
|
+
}));
|
|
653
|
+
addDiagnostic(rule, localize_1.LocMessage.typePartiallyUnknown().format({ name: nameValue }) + diagAddendum.getString(), errorNode);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
function cloneBuiltinObjectWithLiteral(node, builtInName, value) {
|
|
658
|
+
const type = getBuiltInObject(node, builtInName);
|
|
659
|
+
if ((0, types_1.isClassInstance)(type)) {
|
|
660
|
+
return types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneRemoveTypePromotions(type), value);
|
|
661
|
+
}
|
|
662
|
+
return types_1.UnknownType.create();
|
|
663
|
+
}
|
|
664
|
+
function adjustParamAnnotatedType(param, type) {
|
|
665
|
+
// PEP 484 indicates that if a parameter has a default value of 'None'
|
|
666
|
+
// the type checker should assume that the type is optional (i.e. a union
|
|
667
|
+
// of the specified type and 'None'). Skip this step if the type is already
|
|
668
|
+
// optional to avoid losing alias names when combining the types.
|
|
669
|
+
if (param.d.defaultValue?.nodeType === 14 /* ParseNodeType.Constant */ &&
|
|
670
|
+
param.d.defaultValue.d.constType === 27 /* KeywordType.None */ &&
|
|
671
|
+
!(0, typeUtils_1.isOptionalType)(type) &&
|
|
672
|
+
!nodeInfo.getFileInfo(param).diagnosticRuleSet.strictParameterNoneValue) {
|
|
673
|
+
return (0, types_1.combineTypes)([type, getNoneType()]);
|
|
674
|
+
}
|
|
675
|
+
return type;
|
|
676
|
+
}
|
|
677
|
+
function inferParamTypeFromDefaultValue(paramValueExpr) {
|
|
678
|
+
const defaultValueType = getTypeOfExpression(paramValueExpr, 1 /* EvalFlags.ConvertEllipsisToAny */).type;
|
|
679
|
+
let inferredParamType;
|
|
680
|
+
// Is the default value a "None", a sentinel, or an instance of some private
|
|
681
|
+
// class (one whose name starts with an underscore)? If so, we will assume
|
|
682
|
+
// that the value is a singleton sentinel. The actual supported type is
|
|
683
|
+
// going to be a union of this type and Unknown.
|
|
684
|
+
if ((0, typeUtils_1.isNoneInstance)(defaultValueType) ||
|
|
685
|
+
(0, typeUtils_1.isSentinelLiteral)(defaultValueType) ||
|
|
686
|
+
((0, types_1.isClassInstance)(defaultValueType) && (0, symbolNameUtils_1.isPrivateOrProtectedName)(defaultValueType.shared.name))) {
|
|
687
|
+
inferredParamType = (0, types_1.combineTypes)([defaultValueType, types_1.UnknownType.create()]);
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
let skipInference = false;
|
|
691
|
+
if ((0, types_1.isFunctionOrOverloaded)(defaultValueType)) {
|
|
692
|
+
// Do not infer parameter types that use a lambda or another function as a
|
|
693
|
+
// default value. We're likely to generate false positives in this case.
|
|
694
|
+
// It's not clear whether parameters should be positional-only or not.
|
|
695
|
+
skipInference = true;
|
|
696
|
+
}
|
|
697
|
+
else if ((0, types_1.isClassInstance)(defaultValueType) &&
|
|
698
|
+
types_1.ClassType.isBuiltIn(defaultValueType, ['tuple', 'list', 'set', 'dict'])) {
|
|
699
|
+
// Do not infer certain types like tuple because it's likely to be
|
|
700
|
+
// more restrictive (narrower) than intended.
|
|
701
|
+
skipInference = true;
|
|
702
|
+
}
|
|
703
|
+
if (!skipInference) {
|
|
704
|
+
inferredParamType = convertSpecialFormToRuntimeValue(defaultValueType, 0 /* EvalFlags.None */,
|
|
705
|
+
/* convertModule */ true);
|
|
706
|
+
inferredParamType = (0, typeUtils_1.stripTypeForm)(inferredParamType);
|
|
707
|
+
inferredParamType = stripLiteralValue(inferredParamType);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
if (inferredParamType) {
|
|
711
|
+
const fileInfo = nodeInfo.getFileInfo(paramValueExpr);
|
|
712
|
+
if (fileInfo.isInPyTypedPackage && !fileInfo.isStubFile) {
|
|
713
|
+
inferredParamType = types_1.TypeBase.cloneForAmbiguousType(inferredParamType);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return inferredParamType;
|
|
717
|
+
}
|
|
718
|
+
function transformVariadicParamType(node, paramCategory, type) {
|
|
719
|
+
switch (paramCategory) {
|
|
720
|
+
case 0 /* ParamCategory.Simple */: {
|
|
721
|
+
return type;
|
|
722
|
+
}
|
|
723
|
+
case 1 /* ParamCategory.ArgsList */: {
|
|
724
|
+
if ((0, types_1.isParamSpec)(type) && type.priv.paramSpecAccess) {
|
|
725
|
+
return type;
|
|
726
|
+
}
|
|
727
|
+
if ((0, types_1.isUnpackedClass)(type)) {
|
|
728
|
+
return types_1.ClassType.cloneForPacked(type);
|
|
729
|
+
}
|
|
730
|
+
return (0, tuples_1.makeTupleObject)(evaluatorInterface, [{ type, isUnbounded: !(0, types_1.isTypeVarTuple)(type) }]);
|
|
731
|
+
}
|
|
732
|
+
case 2 /* ParamCategory.KwargsDict */: {
|
|
733
|
+
// Leave a ParamSpec alone.
|
|
734
|
+
if ((0, types_1.isParamSpec)(type) && type.priv.paramSpecAccess) {
|
|
735
|
+
return type;
|
|
736
|
+
}
|
|
737
|
+
// Is this an unpacked TypedDict? If so, return its packed version.
|
|
738
|
+
if ((0, types_1.isClassInstance)(type) && types_1.ClassType.isTypedDictClass(type) && type.priv.isUnpacked) {
|
|
739
|
+
return types_1.ClassType.cloneForPacked(type);
|
|
740
|
+
}
|
|
741
|
+
// Wrap the type in a dict with str keys.
|
|
742
|
+
const dictType = getBuiltInType(node, 'dict');
|
|
743
|
+
const strType = getBuiltInObject(node, 'str');
|
|
744
|
+
if ((0, types_1.isInstantiableClass)(dictType) && (0, types_1.isClassInstance)(strType)) {
|
|
745
|
+
return types_1.ClassType.cloneAsInstance(types_1.ClassType.specialize(dictType, [strType, type]));
|
|
746
|
+
}
|
|
747
|
+
return types_1.UnknownType.create();
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
function methodAlwaysRaisesNotImplemented(functionDecl) {
|
|
752
|
+
if (!functionDecl ||
|
|
753
|
+
!functionDecl.isMethod ||
|
|
754
|
+
functionDecl.returnStatements ||
|
|
755
|
+
functionDecl.yieldStatements ||
|
|
756
|
+
!functionDecl.raiseStatements) {
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
const statements = functionDecl.node.d.suite.d.statements;
|
|
760
|
+
if (statements.some((statement) => statement.nodeType !== 47 /* ParseNodeType.StatementList */)) {
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
for (const raiseStatement of functionDecl.raiseStatements) {
|
|
764
|
+
if (!raiseStatement.d.expr || raiseStatement.d.fromExpr) {
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
const raiseType = getTypeOfExpression(raiseStatement.d.expr).type;
|
|
768
|
+
const classType = (0, types_1.isInstantiableClass)(raiseType)
|
|
769
|
+
? raiseType
|
|
770
|
+
: (0, types_1.isClassInstance)(raiseType)
|
|
771
|
+
? raiseType
|
|
772
|
+
: undefined;
|
|
773
|
+
if (!classType || !(0, typeUtils_1.derivesFromStdlibClass)(classType, 'NotImplementedError')) {
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
function getTypeOfArgExpectingType(arg, options) {
|
|
780
|
+
if (arg.typeResult) {
|
|
781
|
+
return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
|
|
782
|
+
}
|
|
783
|
+
// If there was no defined type provided, there should always
|
|
784
|
+
// be a value expression from which we can retrieve the type.
|
|
785
|
+
(0, debug_1.assert)(arg.valueExpression !== undefined);
|
|
786
|
+
return getTypeOfExpressionExpectingType(arg.valueExpression, options);
|
|
787
|
+
}
|
|
788
|
+
function getBuiltInType(node, name) {
|
|
789
|
+
const scope = getScopeForNode(node);
|
|
790
|
+
if (scope) {
|
|
791
|
+
const builtInScope = ScopeUtils.getBuiltInScope(scope);
|
|
792
|
+
const nameType = builtInScope.lookUpSymbol(name);
|
|
793
|
+
if (nameType) {
|
|
794
|
+
return getEffectiveTypeOfSymbol(nameType);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
return types_1.UnknownType.create();
|
|
798
|
+
}
|
|
799
|
+
function getBuiltInObject(node, name, typeArgs) {
|
|
800
|
+
const nameType = getBuiltInType(node, name);
|
|
801
|
+
if ((0, types_1.isInstantiableClass)(nameType)) {
|
|
802
|
+
let classType = nameType;
|
|
803
|
+
if (typeArgs) {
|
|
804
|
+
classType = types_1.ClassType.specialize(classType, typeArgs);
|
|
805
|
+
}
|
|
806
|
+
return types_1.ClassType.cloneAsInstance(classType);
|
|
807
|
+
}
|
|
808
|
+
return nameType;
|
|
809
|
+
}
|
|
810
|
+
function isUnambiguousInference(symbol, decl, inferredType) {
|
|
811
|
+
const nonSlotsDecls = symbol.getDeclarations().filter((decl) => {
|
|
812
|
+
return decl.type !== 1 /* DeclarationType.Variable */ || !decl.isInferenceAllowedInPyTyped;
|
|
813
|
+
});
|
|
814
|
+
// Any symbol with more than one assignment is considered ambiguous.
|
|
815
|
+
if (nonSlotsDecls.length > 1) {
|
|
816
|
+
return false;
|
|
817
|
+
}
|
|
818
|
+
if (decl.type !== 1 /* DeclarationType.Variable */) {
|
|
819
|
+
return false;
|
|
820
|
+
}
|
|
821
|
+
// If there are no non-slots declarations, don't mark the inferred type as ambiguous.
|
|
822
|
+
if (nonSlotsDecls.length === 0) {
|
|
823
|
+
return true;
|
|
824
|
+
}
|
|
825
|
+
// TypeVar definitions don't require a declaration.
|
|
826
|
+
if ((0, types_1.isTypeVar)(inferredType)) {
|
|
827
|
+
return true;
|
|
828
|
+
}
|
|
829
|
+
let assignmentNode;
|
|
830
|
+
const parentNode = decl.node.parent;
|
|
831
|
+
if (parentNode) {
|
|
832
|
+
// Is this a simple assignment (x = y) or an assignment of an instance variable (self.x = y)?
|
|
833
|
+
if (parentNode.nodeType === 3 /* ParseNodeType.Assignment */) {
|
|
834
|
+
assignmentNode = parentNode;
|
|
835
|
+
}
|
|
836
|
+
else if (parentNode.nodeType === 35 /* ParseNodeType.MemberAccess */ &&
|
|
837
|
+
parentNode.parent?.nodeType === 3 /* ParseNodeType.Assignment */) {
|
|
838
|
+
assignmentNode = parentNode.parent;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
if (!assignmentNode) {
|
|
842
|
+
return false;
|
|
843
|
+
}
|
|
844
|
+
const assignedType = getTypeOfExpression(assignmentNode.d.rightExpr).type;
|
|
845
|
+
// Assume that literal values will always result in the same inferred type.
|
|
846
|
+
if ((0, types_1.isClassInstance)(assignedType) && (0, typeUtils_1.isLiteralType)(assignedType)) {
|
|
847
|
+
return true;
|
|
848
|
+
}
|
|
849
|
+
// If the assignment is a simple name corresponding to an unambiguous
|
|
850
|
+
// type, we'll assume the resulting variable will receive the same
|
|
851
|
+
// unambiguous type.
|
|
852
|
+
if (assignmentNode.d.rightExpr.nodeType === 38 /* ParseNodeType.Name */ && !types_1.TypeBase.isAmbiguous(assignedType)) {
|
|
853
|
+
return true;
|
|
854
|
+
}
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
function isSpecialFormClass(classType, flags) {
|
|
858
|
+
if ((flags & 16384 /* AssignTypeFlags.AllowIsinstanceSpecialForms */) !== 0) {
|
|
859
|
+
return false;
|
|
860
|
+
}
|
|
861
|
+
return types_1.ClassType.isSpecialFormClass(classType);
|
|
862
|
+
}
|
|
863
|
+
function isTypeSubsumedByOtherType(type, otherType, allowAnyToSubsume, recursionCount = 0) {
|
|
864
|
+
const concreteType = makeTopLevelTypeVarsConcrete(type);
|
|
865
|
+
const otherSubtypes = (0, types_1.isUnion)(otherType) ? otherType.priv.subtypes : [otherType];
|
|
866
|
+
for (const otherSubtype of otherSubtypes) {
|
|
867
|
+
if ((0, types_1.isTypeSame)(otherSubtype, type)) {
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
if ((0, types_1.isAnyOrUnknown)(otherSubtype)) {
|
|
871
|
+
if (allowAnyToSubsume) {
|
|
872
|
+
return true;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
else if (isProperSubtype(otherSubtype, concreteType, recursionCount)) {
|
|
876
|
+
return true;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
function isProperSubtype(destType, srcType, recursionCount) {
|
|
882
|
+
// If the destType has a condition, don't consider the srcType a proper subtype.
|
|
883
|
+
if (destType.props?.condition) {
|
|
884
|
+
return false;
|
|
885
|
+
}
|
|
886
|
+
// Shortcut the check if either type is Any or Unknown.
|
|
887
|
+
if ((0, types_1.isAnyOrUnknown)(destType) || (0, types_1.isAnyOrUnknown)(srcType)) {
|
|
888
|
+
return true;
|
|
889
|
+
}
|
|
890
|
+
// Shortcut the check if either type is a class whose hierarchy contains an unknown type.
|
|
891
|
+
if ((0, types_1.isClass)(destType) && destType.shared.mro.some((mro) => (0, types_1.isAnyOrUnknown)(mro))) {
|
|
892
|
+
return true;
|
|
893
|
+
}
|
|
894
|
+
if ((0, types_1.isClass)(srcType) && srcType.shared.mro.some((mro) => (0, types_1.isAnyOrUnknown)(mro))) {
|
|
895
|
+
return true;
|
|
896
|
+
}
|
|
897
|
+
return (assignType(destType, srcType,
|
|
898
|
+
/* diag */ undefined,
|
|
899
|
+
/* constraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount) &&
|
|
900
|
+
!assignType(srcType, destType,
|
|
901
|
+
/* diag */ undefined,
|
|
902
|
+
/* constraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount));
|
|
903
|
+
}
|
|
904
|
+
function isTypeComparable(leftType, rightType, assumeIsOperator = false) {
|
|
905
|
+
if ((0, types_1.isAnyOrUnknown)(leftType) || (0, types_1.isAnyOrUnknown)(rightType)) {
|
|
906
|
+
return true;
|
|
907
|
+
}
|
|
908
|
+
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
|
909
|
+
return false;
|
|
910
|
+
}
|
|
911
|
+
if ((0, types_1.isModule)(leftType) || (0, types_1.isModule)(rightType)) {
|
|
912
|
+
return (0, types_1.isTypeSame)(leftType, rightType, { ignoreConditions: true });
|
|
913
|
+
}
|
|
914
|
+
const isLeftCallable = (0, types_1.isFunctionOrOverloaded)(leftType);
|
|
915
|
+
const isRightCallable = (0, types_1.isFunctionOrOverloaded)(rightType);
|
|
916
|
+
// If either type is a function, assume that it may be comparable. The other
|
|
917
|
+
// operand might be a callable object, an 'object' instance, etc. We could
|
|
918
|
+
// make this more precise for specific cases (e.g. if the other operand is
|
|
919
|
+
// None or a literal or an instance of a nominal class that doesn't override
|
|
920
|
+
// __call__ and is marked final, etc.), but coming up with a comprehensive
|
|
921
|
+
// list is probably not feasible.
|
|
922
|
+
if (isLeftCallable || isRightCallable) {
|
|
923
|
+
return true;
|
|
924
|
+
}
|
|
925
|
+
if ((0, types_1.isInstantiableClass)(leftType) || ((0, types_1.isClassInstance)(leftType) && types_1.ClassType.isBuiltIn(leftType, 'type'))) {
|
|
926
|
+
if ((0, types_1.isInstantiableClass)(rightType) ||
|
|
927
|
+
((0, types_1.isClassInstance)(rightType) && types_1.ClassType.isBuiltIn(rightType, 'type'))) {
|
|
928
|
+
const genericLeftType = types_1.ClassType.specialize(leftType, /* typeArgs */ undefined);
|
|
929
|
+
const genericRightType = types_1.ClassType.specialize(rightType, /* typeArgs */ undefined);
|
|
930
|
+
if (assignType(genericLeftType, genericRightType) || assignType(genericRightType, genericLeftType)) {
|
|
931
|
+
return true;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
// Does the class have an operator overload for eq?
|
|
935
|
+
const metaclass = leftType.shared.effectiveMetaclass;
|
|
936
|
+
if (metaclass && (0, types_1.isClass)(metaclass)) {
|
|
937
|
+
if ((0, typeUtils_1.lookUpClassMember)(metaclass, '__eq__', 4 /* MemberAccessFlags.SkipObjectBaseClass */)) {
|
|
938
|
+
return true;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return false;
|
|
942
|
+
}
|
|
943
|
+
if ((0, types_1.isClassInstance)(leftType)) {
|
|
944
|
+
if ((0, types_1.isClass)(rightType)) {
|
|
945
|
+
const genericLeftType = types_1.ClassType.specialize(leftType, /* typeArgs */ undefined);
|
|
946
|
+
const genericRightType = types_1.ClassType.specialize(rightType, /* typeArgs */ undefined);
|
|
947
|
+
if (assignType(genericLeftType, genericRightType) || assignType(genericRightType, genericLeftType)) {
|
|
948
|
+
return true;
|
|
949
|
+
}
|
|
950
|
+
// Check for the "is None" or "is not None" case.
|
|
951
|
+
if (assumeIsOperator && (0, typeUtils_1.isNoneInstance)(rightType)) {
|
|
952
|
+
if ((0, typeUtils_1.isNoneInstance)(leftType)) {
|
|
953
|
+
return true;
|
|
954
|
+
}
|
|
955
|
+
// The LHS could be a protocol or 'object', in which case None is
|
|
956
|
+
// potentially comparable to it. In other cases, None is not comparable
|
|
957
|
+
// because the types are disjoint.
|
|
958
|
+
return assignType(leftType, rightType);
|
|
959
|
+
}
|
|
960
|
+
// Assume that if the types are disjoint and built-in classes that they
|
|
961
|
+
// will never be comparable.
|
|
962
|
+
if (types_1.ClassType.isBuiltIn(leftType) && types_1.ClassType.isBuiltIn(rightType) && types_1.TypeBase.isInstance(rightType)) {
|
|
963
|
+
// We need to be careful with bool and int literals because
|
|
964
|
+
// they are comparable under certain circumstances.
|
|
965
|
+
let boolType;
|
|
966
|
+
let intType;
|
|
967
|
+
if (types_1.ClassType.isBuiltIn(leftType, 'bool') && types_1.ClassType.isBuiltIn(rightType, 'int')) {
|
|
968
|
+
boolType = leftType;
|
|
969
|
+
intType = rightType;
|
|
970
|
+
}
|
|
971
|
+
else if (types_1.ClassType.isBuiltIn(rightType, 'bool') && types_1.ClassType.isBuiltIn(leftType, 'int')) {
|
|
972
|
+
boolType = rightType;
|
|
973
|
+
intType = leftType;
|
|
974
|
+
}
|
|
975
|
+
if (boolType && intType) {
|
|
976
|
+
const intVal = intType.priv?.literalValue;
|
|
977
|
+
if (intVal === undefined) {
|
|
978
|
+
return true;
|
|
979
|
+
}
|
|
980
|
+
if (intVal !== 0 && intVal !== 1) {
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
const boolVal = boolType.priv?.literalValue;
|
|
984
|
+
if (boolVal === undefined) {
|
|
985
|
+
return true;
|
|
986
|
+
}
|
|
987
|
+
return boolVal === (intVal === 1);
|
|
988
|
+
}
|
|
989
|
+
// Distinct bytes-like classes support cross-type equality regardless
|
|
990
|
+
// of disableBytesTypePromotions. Don't apply this to the same class:
|
|
991
|
+
// different bytes literals must remain disjoint.
|
|
992
|
+
if (!assumeIsOperator &&
|
|
993
|
+
!types_1.ClassType.isSameGenericClass(leftType, rightType) &&
|
|
994
|
+
isTypePromotionRelated(leftType, rightType)) {
|
|
995
|
+
return true;
|
|
996
|
+
}
|
|
997
|
+
return false;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
// Does the class have an operator overload for eq?
|
|
1001
|
+
const eqMethod = (0, typeUtils_1.lookUpClassMember)(types_1.ClassType.cloneAsInstantiable(leftType), '__eq__', 4 /* MemberAccessFlags.SkipObjectBaseClass */);
|
|
1002
|
+
if (eqMethod) {
|
|
1003
|
+
// If this is a synthesized method for a dataclass, we can assume
|
|
1004
|
+
// that other dataclass types will not be comparable.
|
|
1005
|
+
if (types_1.ClassType.isDataClass(leftType) && eqMethod.symbol.getSynthesizedType()) {
|
|
1006
|
+
return false;
|
|
1007
|
+
}
|
|
1008
|
+
return true;
|
|
1009
|
+
}
|
|
1010
|
+
return false;
|
|
1011
|
+
}
|
|
1012
|
+
return true;
|
|
1013
|
+
}
|
|
1014
|
+
function isFinalVariable(symbol) {
|
|
1015
|
+
return symbol.getDeclarations().some((decl) => isFinalVariableDeclaration(decl));
|
|
1016
|
+
}
|
|
1017
|
+
function isFinalVariableDeclaration(decl) {
|
|
1018
|
+
return decl.type === 1 /* DeclarationType.Variable */ && !!decl.isFinal;
|
|
1019
|
+
}
|
|
1020
|
+
function isLegalTypeAliasExpressionForm(node, allowStrLiteral) {
|
|
1021
|
+
switch (node.nodeType) {
|
|
1022
|
+
case 0 /* ParseNodeType.Error */:
|
|
1023
|
+
case 55 /* ParseNodeType.UnaryOperation */:
|
|
1024
|
+
case 4 /* ParseNodeType.AssignmentExpression */:
|
|
1025
|
+
case 54 /* ParseNodeType.TypeAnnotation */:
|
|
1026
|
+
case 6 /* ParseNodeType.Await */:
|
|
1027
|
+
case 51 /* ParseNodeType.Ternary */:
|
|
1028
|
+
case 56 /* ParseNodeType.Unpack */:
|
|
1029
|
+
case 52 /* ParseNodeType.Tuple */:
|
|
1030
|
+
case 9 /* ParseNodeType.Call */:
|
|
1031
|
+
case 11 /* ParseNodeType.Comprehension */:
|
|
1032
|
+
case 46 /* ParseNodeType.Slice */:
|
|
1033
|
+
case 60 /* ParseNodeType.Yield */:
|
|
1034
|
+
case 61 /* ParseNodeType.YieldFrom */:
|
|
1035
|
+
case 33 /* ParseNodeType.Lambda */:
|
|
1036
|
+
case 40 /* ParseNodeType.Number */:
|
|
1037
|
+
case 18 /* ParseNodeType.Dictionary */:
|
|
1038
|
+
case 34 /* ParseNodeType.List */:
|
|
1039
|
+
case 45 /* ParseNodeType.Set */:
|
|
1040
|
+
return false;
|
|
1041
|
+
case 48 /* ParseNodeType.StringList */:
|
|
1042
|
+
case 49 /* ParseNodeType.String */:
|
|
1043
|
+
return allowStrLiteral;
|
|
1044
|
+
case 14 /* ParseNodeType.Constant */:
|
|
1045
|
+
return node.d.constType === 27 /* KeywordType.None */;
|
|
1046
|
+
case 7 /* ParseNodeType.BinaryOperation */:
|
|
1047
|
+
return (node.d.operator === 6 /* OperatorType.BitwiseOr */ &&
|
|
1048
|
+
isLegalTypeAliasExpressionForm(node.d.leftExpr, /* allowStrLiteral */ true) &&
|
|
1049
|
+
isLegalTypeAliasExpressionForm(node.d.rightExpr, /* allowStrLiteral */ true));
|
|
1050
|
+
case 27 /* ParseNodeType.Index */:
|
|
1051
|
+
return isLegalTypeAliasExpressionForm(node.d.leftExpr, allowStrLiteral);
|
|
1052
|
+
case 35 /* ParseNodeType.MemberAccess */:
|
|
1053
|
+
return isLegalTypeAliasExpressionForm(node.d.leftExpr, allowStrLiteral);
|
|
1054
|
+
}
|
|
1055
|
+
return true;
|
|
1056
|
+
}
|
|
1057
|
+
function isPossibleTypeDictFactoryCall(decl) {
|
|
1058
|
+
if (decl.type !== 1 /* DeclarationType.Variable */ ||
|
|
1059
|
+
!decl.node.parent ||
|
|
1060
|
+
decl.node.parent.nodeType !== 3 /* ParseNodeType.Assignment */ ||
|
|
1061
|
+
decl.node.parent.d.rightExpr?.nodeType !== 9 /* ParseNodeType.Call */) {
|
|
1062
|
+
return false;
|
|
1063
|
+
}
|
|
1064
|
+
const callLeftNode = decl.node.parent.d.rightExpr.d.leftExpr;
|
|
1065
|
+
// Use a simple heuristic to determine whether this is potentially
|
|
1066
|
+
// a call to the TypedDict call. This avoids the expensive (and potentially
|
|
1067
|
+
// recursive) call to getTypeOfExpression in cases where it's not needed.
|
|
1068
|
+
if ((callLeftNode.nodeType === 38 /* ParseNodeType.Name */ && callLeftNode.d.value) === 'TypedDict' ||
|
|
1069
|
+
(callLeftNode.nodeType === 35 /* ParseNodeType.MemberAccess */ &&
|
|
1070
|
+
callLeftNode.d.member.d.value === 'TypedDict' &&
|
|
1071
|
+
callLeftNode.d.leftExpr.nodeType === 38 /* ParseNodeType.Name */)) {
|
|
1072
|
+
// See if this is a call to TypedDict. We want to support
|
|
1073
|
+
// recursive type references in a TypedDict call.
|
|
1074
|
+
const callType = getTypeOfExpression(callLeftNode, 2 /* EvalFlags.CallBaseDefaults */).type;
|
|
1075
|
+
if ((0, types_1.isInstantiableClass)(callType) && types_1.ClassType.isBuiltIn(callType, 'TypedDict')) {
|
|
1076
|
+
return true;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
return false;
|
|
1080
|
+
}
|
|
1081
|
+
return {
|
|
1082
|
+
validateTypeIsInstantiable,
|
|
1083
|
+
solveAndApplyConstraints,
|
|
1084
|
+
getBoundMagicMethod,
|
|
1085
|
+
getTypeOfAwaitable,
|
|
1086
|
+
isTypeHashable,
|
|
1087
|
+
getTypedDictClassType,
|
|
1088
|
+
getTupleClassType,
|
|
1089
|
+
getDictClassType,
|
|
1090
|
+
getStrClassType,
|
|
1091
|
+
getObjectType,
|
|
1092
|
+
getNoneType,
|
|
1093
|
+
getUnionClassType,
|
|
1094
|
+
getTypeClassType,
|
|
1095
|
+
verifyRaiseExceptionType,
|
|
1096
|
+
isSymbolValidTypeExpression,
|
|
1097
|
+
convertSpecialFormToRuntimeValue,
|
|
1098
|
+
reportMissingTypeArgs,
|
|
1099
|
+
specializeTypeAliasWithDefaults,
|
|
1100
|
+
buildTupleTypesList,
|
|
1101
|
+
convertNodeToArg,
|
|
1102
|
+
getSpeculativeNodeForCall,
|
|
1103
|
+
getAbstractSymbolInfo,
|
|
1104
|
+
validateCallForClassInstance,
|
|
1105
|
+
adjustCallableReturnType,
|
|
1106
|
+
getFunctionFullName,
|
|
1107
|
+
reportPossibleUnknownAssignment,
|
|
1108
|
+
cloneBuiltinObjectWithLiteral,
|
|
1109
|
+
adjustParamAnnotatedType,
|
|
1110
|
+
inferParamTypeFromDefaultValue,
|
|
1111
|
+
transformVariadicParamType,
|
|
1112
|
+
methodAlwaysRaisesNotImplemented,
|
|
1113
|
+
getTypeOfArgExpectingType,
|
|
1114
|
+
getBuiltInType,
|
|
1115
|
+
getBuiltInObject,
|
|
1116
|
+
isUnambiguousInference,
|
|
1117
|
+
isSpecialFormClass,
|
|
1118
|
+
isTypeSubsumedByOtherType,
|
|
1119
|
+
isTypeComparable,
|
|
1120
|
+
isFinalVariable,
|
|
1121
|
+
isFinalVariableDeclaration,
|
|
1122
|
+
isLegalTypeAliasExpressionForm,
|
|
1123
|
+
isPossibleTypeDictFactoryCall,
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
//# sourceMappingURL=evaluatorCore.js.map
|