Fixed bug that results in a false positive error under certain circumstances involving a call to a higher-order generic function with another function that involves a class with a contravariant type variable. This addresses #7212.

This commit is contained in:
Eric Traut 2024-05-31 13:44:51 -07:00
parent 0e42a7ea56
commit e69974cee0
3 changed files with 38 additions and 3 deletions

View File

@ -23480,7 +23480,10 @@ export function createTypeEvaluator(
// rather than dest. If the type variable is not in the scope of the
// provided TypeVarContext, simply verify that the concrete types are
// compatible.
if (!srcTypeVarContext || !srcTypeVarContext.hasSolveForScope(getTypeVarScopeId(srcType))) {
if (
(flags & AssignTypeFlags.IgnoreTypeVarScope) === 0 &&
(!srcTypeVarContext || !srcTypeVarContext.hasSolveForScope(getTypeVarScopeId(srcType)))
) {
return assignType(
makeTopLevelTypeVarsConcrete(destType),
makeTopLevelTypeVarsConcrete(srcType),
@ -23497,7 +23500,7 @@ export function createTypeEvaluator(
srcType,
destType,
diag,
srcTypeVarContext,
srcTypeVarContext ?? new TypeVarContext(),
originalFlags,
recursionCount
)
@ -23515,7 +23518,7 @@ export function createTypeEvaluator(
srcType as TypeVarType,
destSubtype,
diag,
srcTypeVarContext,
srcTypeVarContext ?? new TypeVarContext(),
originalFlags,
recursionCount
)

View File

@ -0,0 +1,26 @@
# This sample tests the case involving a higher-order function and a
# class that uses a contravariant type variable.
from collections.abc import Callable
from typing import TypeVar, Generic
T = TypeVar("T", contravariant=True)
A = TypeVar("A")
B = TypeVar("B")
C = TypeVar("C")
class ClassA(Generic[T]):
pass
def func1(c: Callable[[A], None], v: A):
pass
def func2(c: ClassA[B]) -> None:
pass
def func3(c: ClassA[int]):
func1(func2, c)

View File

@ -855,6 +855,12 @@ test('SolverHigherOrder11', () => {
TestUtils.validateResults(analysisResults, 0);
});
test('SolverHigherOrder12', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solverHigherOrder12.py']);
TestUtils.validateResults(analysisResults, 0);
});
test('SolverLiteral1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solverLiteral1.py']);