Fixed bug that resulted in incorrect evaluation of an identifier used in a method parameter type annotation if it shadows a forward reference in a class scope when the method is using PEP 695 type parameters. This addresses #7800.

This commit is contained in:
Eric Traut 2024-04-29 22:06:54 -07:00
parent 0af66f4468
commit 01c512ee7e
3 changed files with 15 additions and 6 deletions

View File

@ -136,10 +136,12 @@ export class Scope {
}
lookUpSymbolRecursive(name: string, options?: LookupSymbolOptions): SymbolWithScope | undefined {
let effectiveScope: Scope = this;
let symbol = this.symbolTable.get(name);
if (!symbol && options?.useProxyScope && this.proxy) {
symbol = this.proxy.symbolTable.get(name);
effectiveScope = this.proxy;
}
if (symbol) {
@ -160,7 +162,7 @@ export class Scope {
symbol,
isOutsideCallerModule: !!options?.isOutsideCallerModule,
isBeyondExecutionScope: !!options?.isBeyondExecutionScope,
scope: this,
scope: effectiveScope,
};
}
}

View File

@ -20354,11 +20354,14 @@ export function createTypeEvaluator(
// Functions and list comprehensions don't allow access to implicitly
// aliased symbols in outer scopes if they haven't yet been assigned
// within the local scope. Same with type parameter scopes.
const scopeTypeHonorsCodeFlow =
scopeType !== ScopeType.Function &&
scopeType !== ScopeType.ListComprehension &&
scopeType !== ScopeType.TypeParameter;
// within the local scope.
let scopeTypeHonorsCodeFlow = scopeType !== ScopeType.Function && scopeType !== ScopeType.ListComprehension;
// TypeParameter scopes don't honor code flow, but if the symbol is resolved
// using the proxy scope for the TypeParameter scope, we should use code flow.
if (scopeType === ScopeType.TypeParameter && symbolWithScope && symbolWithScope.scope === scope) {
scopeTypeHonorsCodeFlow = false;
}
if (symbolWithScope && honorCodeFlow && scopeTypeHonorsCodeFlow) {
// Filter the declarations based on flow reachability.

View File

@ -43,6 +43,10 @@ class ClassG[T](list["T"]):
pass
class ClassH:
def object[T](self, target: object, new: T) -> T: ...
# This should generate an error because T3 is duplicated.
def func3[T3, S1, T3](): ...