mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-06 12:57:14 +03:00
Fixed recent regression that results in a false positive under certain specific circumstances involving higher-order functions that return generic callable types. This addresses #8852. (#8892)
This commit is contained in:
parent
bf2c2bd7c5
commit
56183a3de4
@ -2158,8 +2158,9 @@ export function synthesizeTypeVarForSelfCls(classType: ClassType, isClsParam: bo
|
||||
const scopeId = getTypeVarScopeId(classType) ?? '';
|
||||
selfType.shared.isSynthesized = true;
|
||||
selfType.shared.isSynthesizedSelf = true;
|
||||
selfType.priv.nameWithScope = TypeVarType.makeNameWithScope(selfType.shared.name, scopeId);
|
||||
selfType.priv.scopeId = scopeId;
|
||||
selfType.priv.scopeName = '';
|
||||
selfType.priv.nameWithScope = TypeVarType.makeNameWithScope(selfType.shared.name, scopeId, selfType.priv.scopeName);
|
||||
|
||||
const boundType = ClassType.specialize(
|
||||
classType,
|
||||
|
@ -2854,7 +2854,11 @@ export namespace TypeVarType {
|
||||
newInstance.shared.name = name;
|
||||
|
||||
if (newInstance.priv.scopeId) {
|
||||
newInstance.priv.nameWithScope = makeNameWithScope(name, newInstance.priv.scopeId);
|
||||
newInstance.priv.nameWithScope = makeNameWithScope(
|
||||
name,
|
||||
newInstance.priv.scopeId,
|
||||
newInstance.priv.scopeName ?? ''
|
||||
);
|
||||
}
|
||||
|
||||
return newInstance;
|
||||
@ -2867,7 +2871,7 @@ export namespace TypeVarType {
|
||||
scopeType: TypeVarScopeType | undefined
|
||||
): TypeVarType {
|
||||
const newInstance = TypeBase.cloneType(type);
|
||||
newInstance.priv.nameWithScope = makeNameWithScope(type.shared.name, scopeId);
|
||||
newInstance.priv.nameWithScope = makeNameWithScope(type.shared.name, scopeId, scopeName ?? '');
|
||||
newInstance.priv.scopeId = scopeId;
|
||||
newInstance.priv.scopeName = scopeName;
|
||||
newInstance.priv.scopeType = scopeType;
|
||||
@ -2957,8 +2961,12 @@ export namespace TypeVarType {
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
export function makeNameWithScope(name: string, scopeId: string) {
|
||||
return `${name}.${scopeId}`;
|
||||
export function makeNameWithScope(name: string, scopeId: string, scopeName: string) {
|
||||
// We include the scopeName here even though it's normally already part
|
||||
// of the scopeId. There are cases where it can diverge, specifically
|
||||
// in scenarios involving higher-order functions that return generic
|
||||
// callable types. See adjustCallableReturnType for details.
|
||||
return `${name}.${scopeId}.${scopeName}`;
|
||||
}
|
||||
|
||||
// When solving the TypeVars for a callable, we need to distinguish between
|
||||
|
@ -0,0 +1,21 @@
|
||||
# This sample tests a particular situation that regressed.
|
||||
|
||||
from typing import Any, Generic, TypeVar, TypeVarTuple, Callable
|
||||
|
||||
D = TypeVar("D")
|
||||
S = TypeVarTuple("S")
|
||||
|
||||
|
||||
class N(Generic[*S, D]): ...
|
||||
|
||||
|
||||
def func1[*S1, D1, *S2, D2, Dim1](
|
||||
c: Callable[[N[*S1, D1], N[*S2, D2]], Any],
|
||||
) -> Callable[[N[Dim1, *S1, D1], N[Dim1, *S2, D2]], Any]: ...
|
||||
|
||||
|
||||
def func2[X, Y, Z](x: N[X, Y, Z], y: N[X, Y, Z]):
|
||||
func1(func3)(x, y)
|
||||
|
||||
|
||||
def func3[Dim1, T](x: N[Dim1, T], y: N[Dim1, T]) -> N[T]: ...
|
@ -909,6 +909,12 @@ test('SolverHigherOrder12', () => {
|
||||
TestUtils.validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('SolverHigherOrder13', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solverHigherOrder13.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('SolverLiteral1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solverLiteral1.py']);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user