mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-07 13:29:17 +03:00
Fixed regression that caused a false positive error related to incorrect usage of a type variable within a type alias definition.
This commit is contained in:
parent
aee583b94b
commit
ca02505965
@ -183,6 +183,7 @@ import {
|
|||||||
TypedDictEntry,
|
TypedDictEntry,
|
||||||
TypeSourceId,
|
TypeSourceId,
|
||||||
TypeVarScopeId,
|
TypeVarScopeId,
|
||||||
|
TypeVarScopeType,
|
||||||
TypeVarType,
|
TypeVarType,
|
||||||
UnboundType,
|
UnboundType,
|
||||||
UnionType,
|
UnionType,
|
||||||
@ -3479,7 +3480,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
|||||||
type = TypeVarType.cloneForScopeId(
|
type = TypeVarType.cloneForScopeId(
|
||||||
type,
|
type,
|
||||||
getScopeIdForNode(enclosingScope),
|
getScopeIdForNode(enclosingScope),
|
||||||
enclosingScope.name.value
|
enclosingScope.name.value,
|
||||||
|
enclosingScope.nodeType === ParseNodeType.Function
|
||||||
|
? TypeVarScopeType.Function
|
||||||
|
: TypeVarScopeType.Class
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
fail('AssociateTypeVarsWithCurrentScope flag was set but enclosing scope not found');
|
fail('AssociateTypeVarsWithCurrentScope flag was set but enclosing scope not found');
|
||||||
@ -3682,7 +3686,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
|||||||
type: TypeVarType.cloneForScopeId(
|
type: TypeVarType.cloneForScopeId(
|
||||||
type,
|
type,
|
||||||
leftType.details.recursiveTypeAliasScopeId,
|
leftType.details.recursiveTypeAliasScopeId,
|
||||||
leftType.details.recursiveTypeAliasName
|
leftType.details.recursiveTypeAliasName,
|
||||||
|
TypeVarScopeType.TypeAlias
|
||||||
),
|
),
|
||||||
foundInterveningClass: false,
|
foundInterveningClass: false,
|
||||||
};
|
};
|
||||||
@ -11832,7 +11837,9 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
|||||||
const fileInfo = AnalyzerNodeInfo.getFileInfo(name);
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(name);
|
||||||
const typeAliasScopeId = getScopeIdForNode(name);
|
const typeAliasScopeId = getScopeIdForNode(name);
|
||||||
|
|
||||||
const boundTypeVars = typeParameters.filter((typeVar) => typeVar.scopeId !== typeAliasScopeId);
|
const boundTypeVars = typeParameters.filter(
|
||||||
|
(typeVar) => typeVar.scopeId !== typeAliasScopeId && typeVar.scopeType === TypeVarScopeType.Class
|
||||||
|
);
|
||||||
if (boundTypeVars.length > 0) {
|
if (boundTypeVars.length > 0) {
|
||||||
addError(
|
addError(
|
||||||
Localizer.Diagnostic.genericTypeAliasBoundTypeVar().format({
|
Localizer.Diagnostic.genericTypeAliasBoundTypeVar().format({
|
||||||
@ -12544,7 +12551,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
|||||||
typeVar.details.isSynthesized = true;
|
typeVar.details.isSynthesized = true;
|
||||||
typeVar.scopeId = getScopeIdForNode(initDeclNode);
|
typeVar.scopeId = getScopeIdForNode(initDeclNode);
|
||||||
typeVar.details.boundType = UnknownType.create();
|
typeVar.details.boundType = UnknownType.create();
|
||||||
return TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(node), node.name.value);
|
return TypeVarType.cloneForScopeId(
|
||||||
|
typeVar,
|
||||||
|
getScopeIdForNode(node),
|
||||||
|
node.name.value,
|
||||||
|
TypeVarScopeType.Class
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ import {
|
|||||||
OverloadedFunctionType,
|
OverloadedFunctionType,
|
||||||
Type,
|
Type,
|
||||||
TypedDictEntry,
|
TypedDictEntry,
|
||||||
|
TypeVarScopeType,
|
||||||
TypeVarType,
|
TypeVarType,
|
||||||
UnknownType,
|
UnknownType,
|
||||||
} from './types';
|
} from './types';
|
||||||
@ -300,7 +301,12 @@ export function synthesizeTypedDictClassMethods(
|
|||||||
const typeVarScopeId = evaluator.getScopeIdForNode(node);
|
const typeVarScopeId = evaluator.getScopeIdForNode(node);
|
||||||
let defaultTypeVar = TypeVarType.createInstance(`__${classType.details.name}_default`);
|
let defaultTypeVar = TypeVarType.createInstance(`__${classType.details.name}_default`);
|
||||||
defaultTypeVar.details.isSynthesized = true;
|
defaultTypeVar.details.isSynthesized = true;
|
||||||
defaultTypeVar = TypeVarType.cloneForScopeId(defaultTypeVar, typeVarScopeId, classType.details.name);
|
defaultTypeVar = TypeVarType.cloneForScopeId(
|
||||||
|
defaultTypeVar,
|
||||||
|
typeVarScopeId,
|
||||||
|
classType.details.name,
|
||||||
|
TypeVarScopeType.Function
|
||||||
|
);
|
||||||
|
|
||||||
const createGetMethod = (keyType: Type, valueType: Type, includeDefault: boolean) => {
|
const createGetMethod = (keyType: Type, valueType: Type, includeDefault: boolean) => {
|
||||||
const getOverload = FunctionType.createInstance(
|
const getOverload = FunctionType.createInstance(
|
||||||
|
@ -1716,6 +1716,12 @@ export interface TypeVarDetails {
|
|||||||
|
|
||||||
export type ParamSpecAccess = 'args' | 'kwargs';
|
export type ParamSpecAccess = 'args' | 'kwargs';
|
||||||
|
|
||||||
|
export const enum TypeVarScopeType {
|
||||||
|
Class,
|
||||||
|
Function,
|
||||||
|
TypeAlias,
|
||||||
|
}
|
||||||
|
|
||||||
export interface TypeVarType extends TypeBase {
|
export interface TypeVarType extends TypeBase {
|
||||||
category: TypeCategory.TypeVar;
|
category: TypeCategory.TypeVar;
|
||||||
details: TypeVarDetails;
|
details: TypeVarDetails;
|
||||||
@ -1728,6 +1734,9 @@ export interface TypeVarType extends TypeBase {
|
|||||||
// so it should be used only for error messages.
|
// so it should be used only for error messages.
|
||||||
scopeName?: string | undefined;
|
scopeName?: string | undefined;
|
||||||
|
|
||||||
|
// If the TypeVar is bound to a scope, this is the scope type.
|
||||||
|
scopeType?: TypeVarScopeType;
|
||||||
|
|
||||||
// String formatted as <name>.<scopeId>.
|
// String formatted as <name>.<scopeId>.
|
||||||
nameWithScope?: string | undefined;
|
nameWithScope?: string | undefined;
|
||||||
|
|
||||||
@ -1779,11 +1788,17 @@ export namespace TypeVarType {
|
|||||||
return newInstance;
|
return newInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cloneForScopeId(type: TypeVarType, scopeId: string, scopeName: string) {
|
export function cloneForScopeId(
|
||||||
|
type: TypeVarType,
|
||||||
|
scopeId: string,
|
||||||
|
scopeName: string,
|
||||||
|
scopeType: TypeVarScopeType
|
||||||
|
) {
|
||||||
const newInstance: TypeVarType = { ...type };
|
const newInstance: TypeVarType = { ...type };
|
||||||
newInstance.nameWithScope = makeNameWithScope(type.details.name, scopeId);
|
newInstance.nameWithScope = makeNameWithScope(type.details.name, scopeId);
|
||||||
newInstance.scopeId = scopeId;
|
newInstance.scopeId = scopeId;
|
||||||
newInstance.scopeName = scopeName;
|
newInstance.scopeName = scopeName;
|
||||||
|
newInstance.scopeType = scopeType;
|
||||||
return newInstance;
|
return newInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user