@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,756 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* typeVarHandling.ts
|
|
4
|
+
* Copyright (c) Microsoft Corporation.
|
|
5
|
+
* Licensed under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* typeVarHandling implementation, using evaluator-owned dependencies and state.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createTypeVarHandling = createTypeVarHandling;
|
|
11
|
+
const debug_1 = require("../../common/debug");
|
|
12
|
+
const diagnosticRules_1 = require("../../common/diagnosticRules");
|
|
13
|
+
const pythonVersion_1 = require("../../common/pythonVersion");
|
|
14
|
+
const uri_1 = require("../../common/uri/uri");
|
|
15
|
+
const localize_1 = require("../../localization/localize");
|
|
16
|
+
const constraintTracker_1 = require("../constraintTracker");
|
|
17
|
+
const tuples_1 = require("../tuples");
|
|
18
|
+
const types_1 = require("../types");
|
|
19
|
+
const typeUtils_1 = require("../typeUtils");
|
|
20
|
+
// Builds and specializes type variables and ParamSpecs; scoped evaluation stays in the evaluator.
|
|
21
|
+
function createTypeVarHandling(context) {
|
|
22
|
+
const { addDiagnostic, assignClassToSelf, assignType, createSelfType, createTypeFormType, getBuiltInType, getObjectType, getTupleClassType, getTypeOfExpressionExpectingType, getTypeVarScopesForNode, isSymbolValidTypeExpression, isTypeFormClass, nodeInfo, rejectBareSpecialFormInTypeForm, solveAndApplyConstraints, specializeTypeAliasWithDefaults, typePromotions, updateUsageVariancesRecursive, } = context;
|
|
23
|
+
function expandTypedKwargs(functionType) {
|
|
24
|
+
const kwargsIndex = functionType.shared.parameters.findIndex((param) => param.category === 2 /* ParamCategory.KwargsDict */);
|
|
25
|
+
if (kwargsIndex < 0) {
|
|
26
|
+
return functionType;
|
|
27
|
+
}
|
|
28
|
+
(0, debug_1.assert)(kwargsIndex === functionType.shared.parameters.length - 1);
|
|
29
|
+
const kwargsType = types_1.FunctionType.getParamType(functionType, kwargsIndex);
|
|
30
|
+
if (!(0, types_1.isClassInstance)(kwargsType) || !types_1.ClassType.isTypedDictClass(kwargsType) || !kwargsType.priv.isUnpacked) {
|
|
31
|
+
return functionType;
|
|
32
|
+
}
|
|
33
|
+
const tdEntries = kwargsType.priv.typedDictNarrowedEntries ?? kwargsType.shared.typedDictEntries?.knownItems;
|
|
34
|
+
if (!tdEntries) {
|
|
35
|
+
return functionType;
|
|
36
|
+
}
|
|
37
|
+
const newFunction = types_1.FunctionType.clone(functionType);
|
|
38
|
+
newFunction.shared.parameters.splice(kwargsIndex);
|
|
39
|
+
if (newFunction.priv.specializedTypes) {
|
|
40
|
+
newFunction.priv.specializedTypes.parameterTypes.splice(kwargsIndex);
|
|
41
|
+
}
|
|
42
|
+
const kwSeparatorIndex = functionType.shared.parameters.findIndex((param) => param.category === 1 /* ParamCategory.ArgsList */);
|
|
43
|
+
// Add a keyword separator if necessary.
|
|
44
|
+
if (kwSeparatorIndex < 0 && tdEntries.size > 0) {
|
|
45
|
+
types_1.FunctionType.addKeywordOnlyParamSeparator(newFunction);
|
|
46
|
+
}
|
|
47
|
+
tdEntries.forEach((tdEntry, name) => {
|
|
48
|
+
// A TypedDict entry type may carry the TypedDict's own type parameters (e.g. an unpacked
|
|
49
|
+
// generic TypedDict `**kwargs: Unpack[TD[int]]`), so specialize each entry against the
|
|
50
|
+
// (possibly generic) TypedDict instance. Specializing an already-concrete type is a
|
|
51
|
+
// no-op, so this is safe for non-generic TypedDicts.
|
|
52
|
+
const specializedValueType = (0, typeUtils_1.partiallySpecializeType)(tdEntry.valueType, kwargsType,
|
|
53
|
+
/* typeClassType */ undefined);
|
|
54
|
+
types_1.FunctionType.addParam(newFunction, types_1.FunctionParam.create(0 /* ParamCategory.Simple */, specializedValueType, types_1.FunctionParamFlags.TypeDeclared, name, tdEntry.isRequired ? undefined : specializedValueType));
|
|
55
|
+
});
|
|
56
|
+
const extraItemsType = kwargsType.shared.typedDictEntries?.extraItems?.valueType;
|
|
57
|
+
if (extraItemsType && !(0, types_1.isNever)(extraItemsType)) {
|
|
58
|
+
// Specialized for the same reason as the per-entry types above. This PEP 728
|
|
59
|
+
// `extra_items` branch uses the identical mechanism and is intentionally not
|
|
60
|
+
// separately tested.
|
|
61
|
+
const specializedExtraItemsType = (0, typeUtils_1.partiallySpecializeType)(extraItemsType, kwargsType,
|
|
62
|
+
/* typeClassType */ undefined);
|
|
63
|
+
types_1.FunctionType.addParam(newFunction, types_1.FunctionParam.create(2 /* ParamCategory.KwargsDict */, specializedExtraItemsType, types_1.FunctionParamFlags.TypeDeclared, 'kwargs'));
|
|
64
|
+
}
|
|
65
|
+
return newFunction;
|
|
66
|
+
}
|
|
67
|
+
function expandPromotionTypes(node, type, excludeBytes = false) {
|
|
68
|
+
return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
|
69
|
+
if (!(0, types_1.isClass)(subtype) || !subtype.priv.includePromotions || subtype.priv.literalValue !== undefined) {
|
|
70
|
+
return subtype;
|
|
71
|
+
}
|
|
72
|
+
if (excludeBytes && types_1.ClassType.isBuiltIn(subtype, 'bytes')) {
|
|
73
|
+
return subtype;
|
|
74
|
+
}
|
|
75
|
+
const typesToCombine = [types_1.ClassType.cloneRemoveTypePromotions(subtype)];
|
|
76
|
+
const promotionTypeNames = typePromotions.get(subtype.shared.fullName);
|
|
77
|
+
if (promotionTypeNames) {
|
|
78
|
+
for (const promotionTypeName of promotionTypeNames) {
|
|
79
|
+
const nameSplit = promotionTypeName.split('.');
|
|
80
|
+
let promotionSubtype = getBuiltInType(node, nameSplit[nameSplit.length - 1]);
|
|
81
|
+
if (promotionSubtype && (0, types_1.isInstantiableClass)(promotionSubtype)) {
|
|
82
|
+
promotionSubtype = types_1.ClassType.cloneRemoveTypePromotions(promotionSubtype);
|
|
83
|
+
if ((0, types_1.isClassInstance)(subtype)) {
|
|
84
|
+
promotionSubtype = types_1.ClassType.cloneAsInstance(promotionSubtype);
|
|
85
|
+
}
|
|
86
|
+
promotionSubtype = (0, typeUtils_1.addConditionToType)(promotionSubtype, subtype.props?.condition);
|
|
87
|
+
typesToCombine.push(promotionSubtype);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return (0, types_1.combineTypes)(typesToCombine);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function makeTopLevelTypeVarsConcrete(type, makeParamSpecsConcrete = false, conditionFilter) {
|
|
95
|
+
type = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(type);
|
|
96
|
+
return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
|
97
|
+
if ((0, types_1.isParamSpec)(subtype)) {
|
|
98
|
+
if (subtype.priv.paramSpecAccess === 'args') {
|
|
99
|
+
return (0, tuples_1.makeTupleObject)(context, [{ type: getObjectType(), isUnbounded: true }]);
|
|
100
|
+
}
|
|
101
|
+
else if (subtype.priv.paramSpecAccess === 'kwargs') {
|
|
102
|
+
if (context.prefetched?.dictClass &&
|
|
103
|
+
(0, types_1.isInstantiableClass)(context.prefetched.dictClass) &&
|
|
104
|
+
context.prefetched?.strClass &&
|
|
105
|
+
(0, types_1.isInstantiableClass)(context.prefetched.strClass)) {
|
|
106
|
+
return types_1.ClassType.cloneAsInstance(types_1.ClassType.specialize(context.prefetched.dictClass, [
|
|
107
|
+
(0, typeUtils_1.convertToInstance)(context.prefetched.strClass),
|
|
108
|
+
getObjectType(),
|
|
109
|
+
]));
|
|
110
|
+
}
|
|
111
|
+
return types_1.UnknownType.create();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// If this is a function that contains only a ParamSpec (no additional
|
|
115
|
+
// parameters), convert it to a concrete type of (*args: Unknown, **kwargs: Unknown).
|
|
116
|
+
if (makeParamSpecsConcrete && (0, types_1.isFunction)(subtype)) {
|
|
117
|
+
const convertedType = (0, typeUtils_1.simplifyFunctionToParamSpec)(subtype);
|
|
118
|
+
if ((0, types_1.isParamSpec)(convertedType)) {
|
|
119
|
+
return types_1.ParamSpecType.getUnknown();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if ((0, types_1.isTypeVarTuple)(subtype)) {
|
|
123
|
+
// If it's in a union, convert to type or object.
|
|
124
|
+
if (subtype.priv.isInUnion) {
|
|
125
|
+
if (types_1.TypeBase.isInstantiable(subtype)) {
|
|
126
|
+
if (context.prefetched?.typeClass && (0, types_1.isInstantiableClass)(context.prefetched.typeClass)) {
|
|
127
|
+
return context.prefetched.typeClass;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
return getObjectType();
|
|
132
|
+
}
|
|
133
|
+
return types_1.AnyType.create();
|
|
134
|
+
}
|
|
135
|
+
// Fall back to "*tuple[object, ...]".
|
|
136
|
+
return (0, tuples_1.makeTupleObject)(context, [{ type: getObjectType(), isUnbounded: true }], /* isUnpacked */ true);
|
|
137
|
+
}
|
|
138
|
+
if ((0, types_1.isTypeVar)(subtype)) {
|
|
139
|
+
// If this is a recursive type alias placeholder
|
|
140
|
+
// that hasn't yet been resolved, return it as is.
|
|
141
|
+
if (subtype.shared.recursiveAlias) {
|
|
142
|
+
return subtype;
|
|
143
|
+
}
|
|
144
|
+
if (types_1.TypeVarType.hasConstraints(subtype)) {
|
|
145
|
+
const typesToCombine = [];
|
|
146
|
+
// Expand the list of constrained subtypes, filtering out any that are
|
|
147
|
+
// disallowed by the conditionFilter.
|
|
148
|
+
subtype.shared.constraints.forEach((constraintType, constraintIndex) => {
|
|
149
|
+
if (conditionFilter) {
|
|
150
|
+
const typeVarName = types_1.TypeVarType.getNameWithScope(subtype);
|
|
151
|
+
const applicableConstraint = conditionFilter.find((filter) => filter.typeVar.priv.nameWithScope === typeVarName);
|
|
152
|
+
// If this type variable is being constrained to a single index,
|
|
153
|
+
// don't include the other indices.
|
|
154
|
+
if (applicableConstraint && applicableConstraint.constraintIndex !== constraintIndex) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (types_1.TypeBase.isInstantiable(subtype)) {
|
|
159
|
+
constraintType = (0, typeUtils_1.convertToInstantiable)(constraintType);
|
|
160
|
+
}
|
|
161
|
+
typesToCombine.push((0, typeUtils_1.addConditionToType)(constraintType, [{ typeVar: subtype, constraintIndex }]));
|
|
162
|
+
});
|
|
163
|
+
return (0, types_1.combineTypes)(typesToCombine);
|
|
164
|
+
}
|
|
165
|
+
if (subtype.shared.isExemptFromBoundCheck) {
|
|
166
|
+
return types_1.AnyType.create();
|
|
167
|
+
}
|
|
168
|
+
// Fall back to a bound of "object" if no bound is provided.
|
|
169
|
+
let boundType = subtype.shared.boundType ?? getObjectType();
|
|
170
|
+
// If this is a synthesized self/cls type var, self-specialize its type arguments.
|
|
171
|
+
if (types_1.TypeVarType.isSelf(subtype) && (0, types_1.isClass)(boundType) && !types_1.ClassType.isPseudoGenericClass(boundType)) {
|
|
172
|
+
boundType = (0, typeUtils_1.selfSpecializeClass)(boundType, {
|
|
173
|
+
useBoundTypeVars: types_1.TypeVarType.isBound(subtype),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (subtype.priv.isUnpacked && (0, types_1.isClass)(boundType)) {
|
|
177
|
+
boundType = types_1.ClassType.cloneForUnpacked(boundType);
|
|
178
|
+
}
|
|
179
|
+
boundType = types_1.TypeBase.isInstantiable(subtype) ? (0, typeUtils_1.convertToInstantiable)(boundType) : boundType;
|
|
180
|
+
return (0, typeUtils_1.addConditionToType)(boundType, [{ typeVar: subtype, constraintIndex: 0 }]);
|
|
181
|
+
}
|
|
182
|
+
return subtype;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function mapSubtypesExpandTypeVars(type, options, callback, recursionCount = 0) {
|
|
186
|
+
const newSubtypes = [];
|
|
187
|
+
let typeChanged = false;
|
|
188
|
+
function expandSubtype(unexpandedType, isLastSubtype) {
|
|
189
|
+
let expandedType = (0, types_1.isUnion)(unexpandedType) ? unexpandedType : makeTopLevelTypeVarsConcrete(unexpandedType);
|
|
190
|
+
expandedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedType);
|
|
191
|
+
if (options?.expandCallback) {
|
|
192
|
+
expandedType = options.expandCallback(expandedType);
|
|
193
|
+
}
|
|
194
|
+
(0, typeUtils_1.doForEachSubtype)(expandedType, (subtype, index, allSubtypes) => {
|
|
195
|
+
if (options?.conditionFilter) {
|
|
196
|
+
const filteredType = applyConditionFilterToType(subtype, options.conditionFilter, recursionCount);
|
|
197
|
+
if (!filteredType) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
subtype = filteredType;
|
|
201
|
+
}
|
|
202
|
+
let transformedType = callback(subtype, unexpandedType, isLastSubtype && index === allSubtypes.length - 1);
|
|
203
|
+
if (transformedType !== unexpandedType) {
|
|
204
|
+
typeChanged = true;
|
|
205
|
+
}
|
|
206
|
+
if (transformedType) {
|
|
207
|
+
// Apply the type condition if it's associated with a constrained TypeVar.
|
|
208
|
+
const typeCondition = (0, typeUtils_1.getTypeCondition)(subtype)?.filter((condition) => types_1.TypeVarType.hasConstraints(condition.typeVar));
|
|
209
|
+
if (typeCondition && typeCondition.length > 0) {
|
|
210
|
+
transformedType = (0, typeUtils_1.addConditionToType)(transformedType, typeCondition);
|
|
211
|
+
}
|
|
212
|
+
// This code path can often produce many duplicate subtypes. We can
|
|
213
|
+
// reduce the cost of the combineTypes call below by filtering out these
|
|
214
|
+
// duplicates proactively. Equal retained tuple literals can carry
|
|
215
|
+
// different inference fallbacks, which combineTypes must reconcile.
|
|
216
|
+
if (newSubtypes.length === 0 ||
|
|
217
|
+
transformedType.props?.inferredTupleLiteral ||
|
|
218
|
+
newSubtypes[newSubtypes.length - 1].props?.inferredTupleLiteral ||
|
|
219
|
+
!(0, types_1.isTypeSame)(transformedType, newSubtypes[newSubtypes.length - 1])) {
|
|
220
|
+
newSubtypes.push(transformedType);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return undefined;
|
|
224
|
+
}, options?.sortSubtypes);
|
|
225
|
+
}
|
|
226
|
+
if ((0, types_1.isUnion)(type)) {
|
|
227
|
+
const subtypes = options?.sortSubtypes ? (0, typeUtils_1.sortTypes)(type.priv.subtypes) : type.priv.subtypes;
|
|
228
|
+
subtypes.forEach((subtype, index) => {
|
|
229
|
+
expandSubtype(subtype, index === type.priv.subtypes.length - 1);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
expandSubtype(type, /* isLastSubtype */ true);
|
|
234
|
+
}
|
|
235
|
+
if (!typeChanged) {
|
|
236
|
+
return type;
|
|
237
|
+
}
|
|
238
|
+
const newType = (0, types_1.combineTypes)(newSubtypes);
|
|
239
|
+
// Do our best to retain type aliases.
|
|
240
|
+
if (newType.category === 8 /* TypeCategory.Union */) {
|
|
241
|
+
types_1.UnionType.addTypeAliasSource(newType, type);
|
|
242
|
+
}
|
|
243
|
+
return newType;
|
|
244
|
+
}
|
|
245
|
+
function addTypeFormForSymbol(node, type, flags, includesVarDecl) {
|
|
246
|
+
const isIndexBase = node.parent?.nodeType === 27 /* ParseNodeType.Index */ && node.parent.d.leftExpr === node;
|
|
247
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (0, types_1.isTypeVar)(type) && types_1.TypeVarType.isSelf(type)) {
|
|
248
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)(type));
|
|
249
|
+
}
|
|
250
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (0, types_1.isInstantiableClass)(type) && !isIndexBase) {
|
|
251
|
+
if (isTypeFormClass(type)) {
|
|
252
|
+
return createTypeFormType(type, node, /* typeArgs */ undefined);
|
|
253
|
+
}
|
|
254
|
+
const rejectedType = rejectBareSpecialFormInTypeForm(type, node);
|
|
255
|
+
if (rejectedType) {
|
|
256
|
+
return rejectedType;
|
|
257
|
+
}
|
|
258
|
+
if (types_1.ClassType.isBuiltIn(type, 'Self')) {
|
|
259
|
+
type = createSelfType(type, node, /* typeArgs */ undefined, flags);
|
|
260
|
+
if ((0, types_1.isTypeVar)(type)) {
|
|
261
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)(type));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const isValid = isSymbolValidTypeExpression(type, includesVarDecl);
|
|
266
|
+
// If the type already has type information associated with it, don't replace.
|
|
267
|
+
if (type.props?.typeForm) {
|
|
268
|
+
// If the NoConvertSpecialForm flag is set, we are evaluating in
|
|
269
|
+
// the interior of a type expression, so variables are not allowed.
|
|
270
|
+
// Clear any existing type form type for this symbol in this case.
|
|
271
|
+
if ((flags & 33554432 /* EvalFlags.NoConvertSpecialForm */) !== 0 && !isValid) {
|
|
272
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, undefined);
|
|
273
|
+
}
|
|
274
|
+
return type;
|
|
275
|
+
}
|
|
276
|
+
// If the symbol is not valid for a type expression (e.g. it's a variable),
|
|
277
|
+
// don't add TypeForm info.
|
|
278
|
+
if (!isValid) {
|
|
279
|
+
return type;
|
|
280
|
+
}
|
|
281
|
+
if ((0, types_1.isTypeVar)(type) && type.priv.scopeId && !type.shared.isSynthesized) {
|
|
282
|
+
if (!(0, types_1.isTypeVarTuple)(type) || !type.priv.isInUnion) {
|
|
283
|
+
const liveScopeIds = getTypeVarScopesForNode(node);
|
|
284
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)((0, typeUtils_1.makeTypeVarsBound)(type, liveScopeIds)));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
else if ((0, types_1.isInstantiableClass)(type) && !type.priv.includeSubclasses && !types_1.ClassType.isSpecialBuiltIn(type)) {
|
|
288
|
+
if (types_1.ClassType.isBuiltIn(type, 'Any')) {
|
|
289
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, types_1.AnyType.create());
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeWithDefaultTypeArgs)(type)));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (type.props?.typeAliasInfo && types_1.TypeBase.isInstantiable(type)) {
|
|
296
|
+
let typeFormType = type;
|
|
297
|
+
if ((flags & 2 /* EvalFlags.NoSpecialize */) === 0) {
|
|
298
|
+
typeFormType = specializeTypeAliasWithDefaults(typeFormType, /* errorNode */ undefined);
|
|
299
|
+
}
|
|
300
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)(typeFormType));
|
|
301
|
+
}
|
|
302
|
+
return type;
|
|
303
|
+
}
|
|
304
|
+
function inferVarianceForTypeAlias(type) {
|
|
305
|
+
const aliasInfo = type.props?.typeAliasInfo;
|
|
306
|
+
// If this isn't a generic type alias, there's nothing to do.
|
|
307
|
+
if (!aliasInfo || !aliasInfo.shared.typeParams) {
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
// Is the computed variance info already cached?
|
|
311
|
+
if (aliasInfo.shared.computedVariance) {
|
|
312
|
+
return aliasInfo.shared.computedVariance;
|
|
313
|
+
}
|
|
314
|
+
const typeParams = aliasInfo.shared.typeParams;
|
|
315
|
+
// Start with all of the usage variances unknown.
|
|
316
|
+
const usageVariances = typeParams.map(() => 1 /* Variance.Unknown */);
|
|
317
|
+
// Prepopulate the cached value for the type alias to handle
|
|
318
|
+
// recursive type aliases.
|
|
319
|
+
aliasInfo.shared.computedVariance = usageVariances;
|
|
320
|
+
// Traverse the type alias type definition and adjust the usage
|
|
321
|
+
// variances accordingly.
|
|
322
|
+
updateUsageVariancesRecursive(type, typeParams, usageVariances, 3 /* Variance.Covariant */);
|
|
323
|
+
return usageVariances;
|
|
324
|
+
}
|
|
325
|
+
function getUnknownExemptTypeVarsForReturnType(functionType, returnType) {
|
|
326
|
+
if ((0, types_1.isFunction)(returnType) && !returnType.shared.name) {
|
|
327
|
+
const returnTypeScopeId = returnType.shared.typeVarScopeId;
|
|
328
|
+
// If one or more type vars found within the return type are scoped to
|
|
329
|
+
// the functionType but don't appear anywhere else within the functionType's
|
|
330
|
+
// input parameters, rescope them to the return type callable so they are
|
|
331
|
+
// not replaced with Unknown.
|
|
332
|
+
if (returnTypeScopeId && functionType.shared.typeVarScopeId) {
|
|
333
|
+
let typeVarsInReturnType = (0, typeUtils_1.getTypeVarArgsRecursive)(returnType);
|
|
334
|
+
// Remove any type variables that appear in the function's input parameters.
|
|
335
|
+
functionType.shared.parameters.forEach((param, index) => {
|
|
336
|
+
if (types_1.FunctionParam.isTypeDeclared(param)) {
|
|
337
|
+
const typeVarsInInputParam = (0, typeUtils_1.getTypeVarArgsRecursive)(types_1.FunctionType.getParamType(functionType, index));
|
|
338
|
+
typeVarsInReturnType = typeVarsInReturnType.filter((returnTypeVar) => !typeVarsInInputParam.some((inputTypeVar) => (0, types_1.isTypeSame)(returnTypeVar, inputTypeVar)));
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
return typeVarsInReturnType;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return [];
|
|
345
|
+
}
|
|
346
|
+
function createTypeVarType(errorNode, classType, argList) {
|
|
347
|
+
let typeVarName = '';
|
|
348
|
+
let firstConstraintArg;
|
|
349
|
+
let defaultValueNode;
|
|
350
|
+
if (argList.length === 0) {
|
|
351
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarFirstArg(), errorNode);
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
const firstArg = argList[0];
|
|
355
|
+
if (firstArg.valueExpression && firstArg.valueExpression.nodeType === 48 /* ParseNodeType.StringList */) {
|
|
356
|
+
typeVarName = firstArg.valueExpression.d.strings.map((s) => s.d.value).join('');
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarFirstArg(), firstArg.valueExpression || errorNode);
|
|
360
|
+
}
|
|
361
|
+
const typeVar = types_1.TypeBase.cloneAsSpecialForm(types_1.TypeVarType.createInstantiable(typeVarName), types_1.ClassType.cloneAsInstance(classType));
|
|
362
|
+
// Parse the remaining parameters.
|
|
363
|
+
const paramNameMap = new Map();
|
|
364
|
+
for (let i = 1; i < argList.length; i++) {
|
|
365
|
+
const paramNameNode = argList[i].name;
|
|
366
|
+
const paramName = paramNameNode ? paramNameNode.d.value : undefined;
|
|
367
|
+
if (paramName) {
|
|
368
|
+
if (paramNameMap.get(paramName)) {
|
|
369
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.duplicateParam().format({ name: paramName }), argList[i].valueExpression || errorNode);
|
|
370
|
+
}
|
|
371
|
+
if (paramName === 'bound') {
|
|
372
|
+
if (types_1.TypeVarType.hasConstraints(typeVar)) {
|
|
373
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarBoundAndConstrained(), argList[i].valueExpression || errorNode);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
const argType = argList[i].typeResult?.type ??
|
|
377
|
+
getTypeOfExpressionExpectingType(argList[i].valueExpression, {
|
|
378
|
+
noNonTypeSpecialForms: true,
|
|
379
|
+
typeExpression: true,
|
|
380
|
+
parsesStringLiteral: true,
|
|
381
|
+
}).type;
|
|
382
|
+
if ((0, typeUtils_1.requiresSpecialization)(argType, { ignorePseudoGeneric: true, ignoreImplicitTypeArgs: true })) {
|
|
383
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarBoundGeneric(), argList[i].valueExpression || errorNode);
|
|
384
|
+
}
|
|
385
|
+
typeVar.shared.boundType = (0, typeUtils_1.convertToInstance)(argType);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else if (paramName === 'covariant') {
|
|
389
|
+
if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
|
|
390
|
+
if (typeVar.shared.declaredVariance === 4 /* Variance.Contravariant */ ||
|
|
391
|
+
typeVar.shared.declaredVariance === 0 /* Variance.Auto */) {
|
|
392
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarVariance(), argList[i].valueExpression);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
typeVar.shared.declaredVariance = 3 /* Variance.Covariant */;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
else if (paramName === 'contravariant') {
|
|
400
|
+
if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
|
|
401
|
+
if (typeVar.shared.declaredVariance === 3 /* Variance.Covariant */ ||
|
|
402
|
+
typeVar.shared.declaredVariance === 0 /* Variance.Auto */) {
|
|
403
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarVariance(), argList[i].valueExpression);
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
typeVar.shared.declaredVariance = 4 /* Variance.Contravariant */;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
else if (paramName === 'infer_variance') {
|
|
411
|
+
if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
|
|
412
|
+
if (typeVar.shared.declaredVariance === 3 /* Variance.Covariant */ ||
|
|
413
|
+
typeVar.shared.declaredVariance === 4 /* Variance.Contravariant */) {
|
|
414
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarVariance(), argList[i].valueExpression);
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
typeVar.shared.declaredVariance = 0 /* Variance.Auto */;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
else if (paramName === 'default') {
|
|
422
|
+
defaultValueNode = argList[i].valueExpression;
|
|
423
|
+
const argType = argList[i].typeResult?.type ??
|
|
424
|
+
getTypeOfExpressionExpectingType(defaultValueNode, {
|
|
425
|
+
allowTypeVarsWithoutScopeId: true,
|
|
426
|
+
typeExpression: true,
|
|
427
|
+
}).type;
|
|
428
|
+
typeVar.shared.defaultType = (0, typeUtils_1.convertToInstance)(argType);
|
|
429
|
+
typeVar.shared.isDefaultExplicit = true;
|
|
430
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
431
|
+
if (!fileInfo.isStubFile &&
|
|
432
|
+
pythonVersion_1.PythonVersion.isLessThan(fileInfo.executionEnvironment.pythonVersion, pythonVersion_1.pythonVersion3_13) &&
|
|
433
|
+
classType.shared.moduleName !== 'typing_extensions') {
|
|
434
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarDefaultIllegal(), defaultValueNode);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.typeVarUnknownParam().format({ name: paramName }), argList[i].node?.d.name || argList[i].valueExpression || errorNode);
|
|
439
|
+
}
|
|
440
|
+
paramNameMap.set(paramName, paramName);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
if (types_1.TypeVarType.hasBound(typeVar)) {
|
|
444
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarBoundAndConstrained(), argList[i].valueExpression || errorNode);
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
const argType = argList[i].typeResult?.type ??
|
|
448
|
+
getTypeOfExpressionExpectingType(argList[i].valueExpression, {
|
|
449
|
+
typeExpression: true,
|
|
450
|
+
}).type;
|
|
451
|
+
if ((0, typeUtils_1.requiresSpecialization)(argType, { ignorePseudoGeneric: true })) {
|
|
452
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarConstraintGeneric(), argList[i].valueExpression || errorNode);
|
|
453
|
+
}
|
|
454
|
+
types_1.TypeVarType.addConstraint(typeVar, (0, typeUtils_1.convertToInstance)(argType));
|
|
455
|
+
if (firstConstraintArg === undefined) {
|
|
456
|
+
firstConstraintArg = argList[i];
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (typeVar.shared.constraints.length === 1 && firstConstraintArg) {
|
|
462
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarSingleConstraint(), firstConstraintArg.valueExpression || errorNode);
|
|
463
|
+
}
|
|
464
|
+
// If a default is provided, make sure it is compatible with the bound
|
|
465
|
+
// or constraint.
|
|
466
|
+
if (typeVar.shared.isDefaultExplicit && defaultValueNode) {
|
|
467
|
+
verifyTypeVarDefaultIsCompatible(typeVar, defaultValueNode);
|
|
468
|
+
}
|
|
469
|
+
return typeVar;
|
|
470
|
+
}
|
|
471
|
+
function verifyTypeVarDefaultIsCompatible(typeVar, defaultValueNode) {
|
|
472
|
+
(0, debug_1.assert)(typeVar.shared.isDefaultExplicit);
|
|
473
|
+
const constraints = new constraintTracker_1.ConstraintTracker();
|
|
474
|
+
const concreteDefaultType = makeTopLevelTypeVarsConcrete(solveAndApplyConstraints(typeVar.shared.defaultType, constraints, {
|
|
475
|
+
replaceUnsolved: {
|
|
476
|
+
scopeIds: (0, typeUtils_1.getTypeVarScopeIds)(typeVar),
|
|
477
|
+
tupleClassType: getTupleClassType(),
|
|
478
|
+
},
|
|
479
|
+
}));
|
|
480
|
+
if (typeVar.shared.boundType) {
|
|
481
|
+
if (!assignType(typeVar.shared.boundType, concreteDefaultType)) {
|
|
482
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarDefaultBoundMismatch(), defaultValueNode);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
else if (types_1.TypeVarType.hasConstraints(typeVar)) {
|
|
486
|
+
let isConstraintCompatible = true;
|
|
487
|
+
// If the default type is a constrained TypeVar, make sure all of its constraints
|
|
488
|
+
// are also constraints in typeVar. If the default type is not a constrained TypeVar,
|
|
489
|
+
// use its concrete type to compare against the constraints.
|
|
490
|
+
if ((0, types_1.isTypeVar)(typeVar.shared.defaultType) && types_1.TypeVarType.hasConstraints(typeVar.shared.defaultType)) {
|
|
491
|
+
for (const constraint of typeVar.shared.defaultType.shared.constraints) {
|
|
492
|
+
if (!typeVar.shared.constraints.some((c) => (0, types_1.isTypeSame)(c, constraint))) {
|
|
493
|
+
isConstraintCompatible = false;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
else if (!typeVar.shared.constraints.some((constraint) => (0, types_1.isTypeSame)(constraint, concreteDefaultType, { ignoreConditions: true }))) {
|
|
498
|
+
isConstraintCompatible = false;
|
|
499
|
+
}
|
|
500
|
+
if (!isConstraintCompatible) {
|
|
501
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarDefaultConstraintMismatch(), defaultValueNode);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
function getTypeVarTupleDefaultType(node, isPep695Syntax) {
|
|
506
|
+
const argType = getTypeOfExpressionExpectingType(node, {
|
|
507
|
+
allowUnpackedTuple: true,
|
|
508
|
+
allowTypeVarsWithoutScopeId: true,
|
|
509
|
+
forwardRefs: isPep695Syntax,
|
|
510
|
+
typeExpression: true,
|
|
511
|
+
}).type;
|
|
512
|
+
const isUnpackedTuple = (0, types_1.isClass)(argType) && (0, typeUtils_1.isTupleClass)(argType) && argType.priv.isUnpacked;
|
|
513
|
+
const isUnpackedTypeVar = (0, types_1.isUnpackedTypeVarTuple)(argType);
|
|
514
|
+
if (!isUnpackedTuple && !isUnpackedTypeVar) {
|
|
515
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarTupleDefaultNotUnpacked(), node);
|
|
516
|
+
return undefined;
|
|
517
|
+
}
|
|
518
|
+
return (0, typeUtils_1.convertToInstance)(argType);
|
|
519
|
+
}
|
|
520
|
+
function createTypeVarTupleType(errorNode, classType, argList) {
|
|
521
|
+
let typeVarName = '';
|
|
522
|
+
if (argList.length === 0) {
|
|
523
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.typeVarFirstArg(), errorNode);
|
|
524
|
+
return undefined;
|
|
525
|
+
}
|
|
526
|
+
const firstArg = argList[0];
|
|
527
|
+
if (firstArg.valueExpression && firstArg.valueExpression.nodeType === 48 /* ParseNodeType.StringList */) {
|
|
528
|
+
typeVarName = firstArg.valueExpression.d.strings.map((s) => s.d.value).join('');
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarFirstArg(), firstArg.valueExpression || errorNode);
|
|
532
|
+
}
|
|
533
|
+
const typeVar = types_1.TypeBase.cloneAsSpecialForm(types_1.TypeVarType.createInstantiable(typeVarName, types_1.TypeVarKind.TypeVarTuple), types_1.ClassType.cloneAsInstance(classType));
|
|
534
|
+
typeVar.shared.defaultType = (0, tuples_1.makeTupleObject)(context, [{ type: types_1.UnknownType.create(), isUnbounded: true }]);
|
|
535
|
+
// Parse the remaining parameters.
|
|
536
|
+
for (let i = 1; i < argList.length; i++) {
|
|
537
|
+
const paramNameNode = argList[i].name;
|
|
538
|
+
const paramName = paramNameNode ? paramNameNode.d.value : undefined;
|
|
539
|
+
if (paramName) {
|
|
540
|
+
if (paramName === 'default') {
|
|
541
|
+
const expr = argList[i].valueExpression;
|
|
542
|
+
if (expr) {
|
|
543
|
+
const defaultType = getTypeVarTupleDefaultType(expr, /* isPep695Syntax */ false);
|
|
544
|
+
if (defaultType) {
|
|
545
|
+
typeVar.shared.defaultType = defaultType;
|
|
546
|
+
typeVar.shared.isDefaultExplicit = true;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
550
|
+
if (!fileInfo.isStubFile &&
|
|
551
|
+
pythonVersion_1.PythonVersion.isLessThan(fileInfo.executionEnvironment.pythonVersion, pythonVersion_1.pythonVersion3_13) &&
|
|
552
|
+
classType.shared.moduleName !== 'typing_extensions') {
|
|
553
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarDefaultIllegal(), expr);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarTupleUnknownParam().format({ name: argList[i].name?.d.value || '?' }), argList[i].node?.d.name || argList[i].valueExpression || errorNode);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarTupleConstraints(), argList[i].valueExpression || errorNode);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return typeVar;
|
|
565
|
+
}
|
|
566
|
+
function getPseudoGenericTypeVarName(paramName) {
|
|
567
|
+
return `__type_of_${paramName}`;
|
|
568
|
+
}
|
|
569
|
+
function inferVarianceForClass(classType) {
|
|
570
|
+
if (!classType.shared.requiresVarianceInference) {
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
// Presumptively mark the variance inference as complete. This
|
|
574
|
+
// prevents potential recursion.
|
|
575
|
+
classType.shared.requiresVarianceInference = false;
|
|
576
|
+
// Presumptively mark the computed variance to "unknown". We'll
|
|
577
|
+
// replace this below once the variance has been inferred.
|
|
578
|
+
classType.shared.typeParams.forEach((param) => {
|
|
579
|
+
if (param.shared.declaredVariance === 0 /* Variance.Auto */) {
|
|
580
|
+
param.priv.computedVariance = 1 /* Variance.Unknown */;
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
const dummyTypeObject = types_1.ClassType.createInstantiable('__varianceDummy', '', '', uri_1.Uri.empty(), 0, 0, undefined, undefined);
|
|
584
|
+
classType.shared.typeParams.forEach((param, paramIndex) => {
|
|
585
|
+
// Skip TypeVarTuples and ParamSpecs.
|
|
586
|
+
if ((0, types_1.isTypeVarTuple)(param) || (0, types_1.isParamSpec)(param)) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
// Skip type variables without auto-variance.
|
|
590
|
+
if (param.shared.declaredVariance !== 0 /* Variance.Auto */) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
// Replace all type arguments with a dummy type except for the
|
|
594
|
+
// TypeVar of interest, which is replaced with an object instance.
|
|
595
|
+
const srcTypeArgs = classType.shared.typeParams.map((p, i) => {
|
|
596
|
+
if ((0, types_1.isTypeVarTuple)(p)) {
|
|
597
|
+
return p;
|
|
598
|
+
}
|
|
599
|
+
return i === paramIndex ? getObjectType() : dummyTypeObject;
|
|
600
|
+
});
|
|
601
|
+
// Replace all type arguments with a dummy type except for the
|
|
602
|
+
// TypeVar of interest, which is replaced with itself.
|
|
603
|
+
const destTypeArgs = classType.shared.typeParams.map((p, i) => {
|
|
604
|
+
return i === paramIndex || (0, types_1.isTypeVarTuple)(p) ? p : dummyTypeObject;
|
|
605
|
+
});
|
|
606
|
+
const srcType = types_1.ClassType.specialize(classType, srcTypeArgs);
|
|
607
|
+
const destType = types_1.ClassType.specialize(classType, destTypeArgs);
|
|
608
|
+
const isDestSubtypeOfSrc = assignClassToSelf(srcType, destType, 3 /* Variance.Covariant */,
|
|
609
|
+
/* ignoreBaseClassVariance */ false);
|
|
610
|
+
let inferredVariance;
|
|
611
|
+
if (isDestSubtypeOfSrc) {
|
|
612
|
+
inferredVariance = 3 /* Variance.Covariant */;
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
const isSrcSubtypeOfDest = assignClassToSelf(destType, srcType, 4 /* Variance.Contravariant */,
|
|
616
|
+
/* ignoreBaseClassVariance */ false);
|
|
617
|
+
if (isSrcSubtypeOfDest) {
|
|
618
|
+
inferredVariance = 4 /* Variance.Contravariant */;
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
inferredVariance = 2 /* Variance.Invariant */;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
// We assume here that we don't need to clone the type var object
|
|
625
|
+
// because it was already cloned when it was associated with this
|
|
626
|
+
// class scope.
|
|
627
|
+
classType.shared.typeParams[paramIndex].priv.computedVariance = inferredVariance;
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
function convertToTypeFormType(expectedType, srcType) {
|
|
631
|
+
// Is the source is a TypeForm type?
|
|
632
|
+
if (!srcType.props?.typeForm) {
|
|
633
|
+
return srcType;
|
|
634
|
+
}
|
|
635
|
+
let srcTypeFormType;
|
|
636
|
+
// Is the source is a TypeForm type?
|
|
637
|
+
if (srcType.props?.typeForm) {
|
|
638
|
+
srcTypeFormType = srcType.props.typeForm;
|
|
639
|
+
}
|
|
640
|
+
else if ((0, types_1.isClass)(srcType)) {
|
|
641
|
+
if (types_1.TypeBase.isInstantiable(srcType)) {
|
|
642
|
+
if (!types_1.ClassType.isSpecialBuiltIn(srcType)) {
|
|
643
|
+
srcTypeFormType = types_1.ClassType.cloneAsInstance(srcType);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
else if (types_1.ClassType.isBuiltIn(srcType, 'type')) {
|
|
647
|
+
srcTypeFormType =
|
|
648
|
+
srcType.priv.typeArgs?.length && srcType.priv.typeArgs.length > 0
|
|
649
|
+
? srcType.priv.typeArgs[0]
|
|
650
|
+
: types_1.UnknownType.create();
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
else if ((0, types_1.isTypeVar)(srcType) && types_1.TypeBase.isInstantiable(srcType)) {
|
|
654
|
+
if (!(0, types_1.isTypeVarTuple)(srcType) || !srcType.priv.isInUnion) {
|
|
655
|
+
srcTypeFormType = (0, typeUtils_1.convertToInstance)(srcType);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (!srcTypeFormType) {
|
|
659
|
+
return srcType;
|
|
660
|
+
}
|
|
661
|
+
let resultType;
|
|
662
|
+
(0, typeUtils_1.doForEachSubtype)(expectedType, (subtype) => {
|
|
663
|
+
if (resultType || !(0, types_1.isClassInstance)(subtype) || !types_1.ClassType.isBuiltIn(subtype, 'TypeForm')) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
const destTypeFormType = subtype.priv.typeArgs && subtype.priv.typeArgs.length > 0 ? subtype.priv.typeArgs[0] : types_1.AnyType.create();
|
|
667
|
+
if (assignType(destTypeFormType, srcTypeFormType)) {
|
|
668
|
+
resultType = types_1.ClassType.specialize(subtype, [srcTypeFormType]);
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
return resultType ?? srcType;
|
|
672
|
+
}
|
|
673
|
+
function setConstraintsForFreeTypeVars(destType, srcType, constraints) {
|
|
674
|
+
const typeVars = (0, typeUtils_1.getTypeVarArgsRecursive)(destType);
|
|
675
|
+
typeVars.forEach((typeVar) => {
|
|
676
|
+
if (!types_1.TypeVarType.isBound(typeVar) && !constraints.getMainConstraintSet().getTypeVar(typeVar)) {
|
|
677
|
+
// Don't set ParamSpecs or TypeVarTuples.
|
|
678
|
+
if (!(0, types_1.isParamSpec)(srcType) && !(0, types_1.isTypeVarTuple)(srcType)) {
|
|
679
|
+
constraints.setBounds(typeVar, srcType);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
function applyConditionFilterToType(type, conditionFilter, recursionCount) {
|
|
685
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
686
|
+
return type;
|
|
687
|
+
}
|
|
688
|
+
recursionCount++;
|
|
689
|
+
// If the type has a condition associated with it, make sure it's compatible.
|
|
690
|
+
if (!types_1.TypeCondition.isCompatible((0, typeUtils_1.getTypeCondition)(type), conditionFilter)) {
|
|
691
|
+
return undefined;
|
|
692
|
+
}
|
|
693
|
+
// If the type is generic, see if any of its type arguments should be filtered.
|
|
694
|
+
// This is possible only in cases where the type parameter is covariant.
|
|
695
|
+
// TODO - handle functions and tuples
|
|
696
|
+
if ((0, types_1.isClass)(type) && type.priv.typeArgs && !type.priv.tupleTypeArgs) {
|
|
697
|
+
inferVarianceForClass(type);
|
|
698
|
+
let typeWasTransformed = false;
|
|
699
|
+
const filteredTypeArgs = type.priv.typeArgs.map((typeArg, index) => {
|
|
700
|
+
if (index >= type.shared.typeParams.length) {
|
|
701
|
+
return typeArg;
|
|
702
|
+
}
|
|
703
|
+
const variance = types_1.TypeVarType.getVariance(type.shared.typeParams[index]);
|
|
704
|
+
if (variance !== 3 /* Variance.Covariant */) {
|
|
705
|
+
return typeArg;
|
|
706
|
+
}
|
|
707
|
+
// Don't expand recursive type aliases because they can
|
|
708
|
+
// cause infinite recursion.
|
|
709
|
+
if ((0, types_1.isTypeVar)(typeArg) && typeArg.shared.recursiveAlias) {
|
|
710
|
+
return typeArg;
|
|
711
|
+
}
|
|
712
|
+
const filteredTypeArg = mapSubtypesExpandTypeVars(typeArg, { conditionFilter }, (expandedSubtype) => {
|
|
713
|
+
return expandedSubtype;
|
|
714
|
+
}, recursionCount);
|
|
715
|
+
if (filteredTypeArg !== typeArg) {
|
|
716
|
+
typeWasTransformed = true;
|
|
717
|
+
}
|
|
718
|
+
return filteredTypeArg;
|
|
719
|
+
});
|
|
720
|
+
if (typeWasTransformed) {
|
|
721
|
+
return types_1.ClassType.specialize(type, filteredTypeArgs);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return type;
|
|
725
|
+
}
|
|
726
|
+
function getBooleanValue(node) {
|
|
727
|
+
if (node.nodeType === 14 /* ParseNodeType.Constant */) {
|
|
728
|
+
if (node.d.constType === 15 /* KeywordType.False */) {
|
|
729
|
+
return false;
|
|
730
|
+
}
|
|
731
|
+
else if (node.d.constType === 34 /* KeywordType.True */) {
|
|
732
|
+
return true;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.expectedBoolLiteral(), node);
|
|
736
|
+
return false;
|
|
737
|
+
}
|
|
738
|
+
return {
|
|
739
|
+
expandTypedKwargs,
|
|
740
|
+
expandPromotionTypes,
|
|
741
|
+
makeTopLevelTypeVarsConcrete,
|
|
742
|
+
mapSubtypesExpandTypeVars,
|
|
743
|
+
addTypeFormForSymbol,
|
|
744
|
+
inferVarianceForTypeAlias,
|
|
745
|
+
getUnknownExemptTypeVarsForReturnType,
|
|
746
|
+
createTypeVarType,
|
|
747
|
+
createTypeVarTupleType,
|
|
748
|
+
verifyTypeVarDefaultIsCompatible,
|
|
749
|
+
getTypeVarTupleDefaultType,
|
|
750
|
+
getPseudoGenericTypeVarName,
|
|
751
|
+
inferVarianceForClass,
|
|
752
|
+
convertToTypeFormType,
|
|
753
|
+
setConstraintsForFreeTypeVars,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
//# sourceMappingURL=typeVarHandling.js.map
|