Skip to content

Commit 65ac270

Browse files
authored
Use type variable bound to infer constraints (#12230)
This fixes a regression where `iter(x)` could generate a false positive if `x` has a type variable type.
1 parent eca4c30 commit 65ac270

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

mypy/constraints.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,10 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
513513
return infer_constraints(template,
514514
mypy.typeops.tuple_fallback(actual),
515515
self.direction)
516+
elif isinstance(actual, TypeVarType):
517+
if not actual.values:
518+
return infer_constraints(template, actual.upper_bound, self.direction)
519+
return []
516520
else:
517521
return []
518522

test-data/unit/check-protocols.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2807,6 +2807,27 @@ class MyClass:
28072807
[builtins fixtures/isinstance.pyi]
28082808
[typing fixtures/typing-full.pyi]
28092809

2810+
[case testProtocolAndTypeVariableSpecialCase]
2811+
from typing import TypeVar, Iterable, Optional, Callable, Protocol
2812+
2813+
T_co = TypeVar('T_co', covariant=True)
2814+
2815+
class SupportsNext(Protocol[T_co]):
2816+
def __next__(self) -> T_co: ...
2817+
2818+
N = TypeVar("N", bound=SupportsNext, covariant=True)
2819+
2820+
class SupportsIter(Protocol[T_co]):
2821+
def __iter__(self) -> T_co: ...
2822+
2823+
def f(i: SupportsIter[N]) -> N: ...
2824+
2825+
I = TypeVar('I', bound=Iterable)
2826+
2827+
def g(x: I, y: Iterable) -> None:
2828+
f(x)
2829+
f(y)
2830+
28102831
[case testMatchProtocolAgainstOverloadWithAmbiguity]
28112832
from typing import TypeVar, Protocol, Union, Generic, overload
28122833

0 commit comments

Comments
 (0)