Fixed bug that resulted in incorrect type evaluation when a generic callback protocol was invoked in a nested manner. This addresses https://github.com/microsoft/pyright/issues/5356. (#5361)

Co-authored-by: Eric Traut <erictr@microsoft.com>
This commit is contained in:
Eric Traut 2023-06-21 15:55:50 -07:00 committed by GitHub
parent fb62cc9bf8
commit b3c77ba45c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 2 deletions

View File

@ -10936,6 +10936,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
skipUnknownArgCheck = false,
inferenceContext?: InferenceContext
): CallResult {
const signatureTracker = inferenceContext?.signatureTracker ?? new UniqueSignatureTracker();
typeResult.type = ensureFunctionSignaturesAreUnique(
typeResult.type,
signatureTracker,
errorNode.start
) as FunctionType;
const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, typeResult, 0);
if (matchResults.argumentErrors) {
@ -10959,7 +10966,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
matchResults,
typeVarContext,
skipUnknownArgCheck,
inferenceContext
makeInferenceContext(inferenceContext?.expectedType, inferenceContext?.isTypeIncomplete, signatureTracker)
);
}

View File

@ -1,7 +1,7 @@
# This sample tests the handling of nested calls to generic functions
# when bidirectional type inference is involved.
from typing import Callable, Generic, Literal, ParamSpec, TypeVar
from typing import Any, Callable, Generic, Literal, ParamSpec, Protocol, TypeVar
_T = TypeVar("_T")
_P = ParamSpec("_P")
@ -46,3 +46,16 @@ def func4(a: int, b: int) -> str:
reveal_type(func1(func2(func3)), expected_text="Future[int]")
reveal_type(func1(func2(func4, 1, 2)), expected_text="Future[str]")
reveal_type(func1(func2(func4, a=1, b=2)), expected_text="Future[str]")
class Proto(Protocol):
def __call__(self, func: _T) -> _T:
...
def func5(cb: Proto, names: Any):
val1 = cb(cb(names))
reveal_type(val1, expected_text="Any")
val2 = cb(cb(1))
reveal_type(val2, expected_text="int")