mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Fixed bug that results in a false negative when solving a type variable that involves an invariant context. (#8051)
This commit is contained in:
parent
e4226ffea9
commit
5ac25c8256
@ -516,6 +516,31 @@ export function assignTypeToTypeVar(
|
||||
}
|
||||
}
|
||||
|
||||
// If this is an invariant context, make sure the narrow type bound
|
||||
// isn't too wide.
|
||||
if (isInvariant && newNarrowTypeBound) {
|
||||
if (
|
||||
!evaluator.assignType(
|
||||
adjSrcType,
|
||||
newNarrowTypeBound,
|
||||
diag?.createAddendum(),
|
||||
/* destTypeVarContext */ undefined,
|
||||
/* srcTypeVarContext */ undefined,
|
||||
AssignTypeFlags.IgnoreTypeVarScope,
|
||||
recursionCount
|
||||
)
|
||||
) {
|
||||
if (diag && diagAddendum) {
|
||||
diag.addMessage(
|
||||
LocAddendum.typeAssignmentMismatch().format(
|
||||
evaluator.printSrcDestTypes(newNarrowTypeBound, adjSrcType)
|
||||
)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we don't exceed the wide type bound.
|
||||
if (curWideTypeBound && newNarrowTypeBound) {
|
||||
if (!isTypeSame(curWideTypeBound, newNarrowTypeBound, {}, recursionCount)) {
|
||||
|
@ -13,7 +13,6 @@ class NT1(NamedTuple, Generic[_T1]):
|
||||
c: list[_T1]
|
||||
|
||||
|
||||
reveal_type(NT1(3, 4, ["hi"]), expected_text="NT1[int | str]")
|
||||
reveal_type(NT1(3, 4, []), expected_text="NT1[int]")
|
||||
reveal_type(NT1(3.4, 4, [1, 2]), expected_text="NT1[float]")
|
||||
reveal_type(NT1(3.4, 4, [2j]), expected_text="NT1[complex]")
|
||||
|
20
packages/pyright-internal/src/tests/samples/solver35.py
Normal file
20
packages/pyright-internal/src/tests/samples/solver35.py
Normal file
@ -0,0 +1,20 @@
|
||||
# This sample tests the case where the constraint solver is asked to
|
||||
# solve a TypeVar that is in an invariant context.
|
||||
|
||||
from typing import TypeVar
|
||||
|
||||
T1 = TypeVar("T1")
|
||||
T2 = TypeVar("T2")
|
||||
|
||||
|
||||
def func1(v1: T1, v2: T2, v1_list: list[T1], v2_list: list[T2]): ...
|
||||
|
||||
|
||||
def func2(v1: int, v2: str, v1_list: list[int], v2_list: list[str]):
|
||||
func1(v1, v2, v1_list, v2_list)
|
||||
|
||||
# This should generate an error because the last two arguments are swapped.
|
||||
func1(v2, v1, v1_list, v2_list)
|
||||
|
||||
# This should generate an error because the last two arguments are swapped.
|
||||
func1(v1_list=v1_list, v2_list=v2_list, v1=v2, v2=v1)
|
@ -765,6 +765,12 @@ test('Solver34', () => {
|
||||
TestUtils.validateResults(analysisResults, 1);
|
||||
});
|
||||
|
||||
test('Solver35', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solver35.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 4);
|
||||
});
|
||||
|
||||
test('SolverScoring1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solverScoring1.py']);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user