Skip to content

Commit 67ff4cf

Browse files
ilevkivskyiJukkaL
authored andcommitted
Infer constraints against tuple fallbacks (#4087)
Fixes #1485. Tuple fallback was overlooked in constraint inference. As usual, I place nominal before structural.
1 parent ad6dd4e commit 67ff4cf

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

mypy/constraints.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,8 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
373373
cb = infer_constraints(template.args[0], item, SUPERTYPE_OF)
374374
res.extend(cb)
375375
return res
376-
elif (isinstance(actual, TupleType) and template.type.is_protocol and
377-
self.direction == SUPERTYPE_OF):
378-
if mypy.subtypes.is_subtype(actual.fallback, erase_typevars(template)):
379-
res.extend(infer_constraints(template, actual.fallback, self.direction))
380-
return res
381-
return []
376+
elif isinstance(actual, TupleType) and self.direction == SUPERTYPE_OF:
377+
return infer_constraints(template, actual.fallback, self.direction)
382378
else:
383379
return []
384380

test-data/unit/check-tuples.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,21 @@ reveal_type(t[x:]) # E: Revealed type is 'Union[builtins.int, builtins.str]'
941941
t[y:] # E: Slice index must be an integer or None
942942
[builtins fixtures/tuple.pyi]
943943

944+
[case testInferTupleTypeFallbackAgainstInstance]
945+
from typing import TypeVar, Generic, Tuple
946+
T = TypeVar('T')
947+
948+
class Base(Generic[T]): pass
949+
def f(x: Base[T]) -> T: pass
950+
951+
class DT(Tuple[str, str], Base[int]):
952+
pass
953+
954+
reveal_type(f(DT())) # E: Revealed type is 'builtins.int*'
955+
956+
[builtins fixtures/tuple.pyi]
957+
[out]
958+
944959
[case testTypeTupleClassmethod]
945960
from typing import Tuple, Type
946961

test-data/unit/pythoneval.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,17 @@ async def main() -> None:
14181418
_testAsyncioGatherPreciseType.py:9: error: Revealed type is 'builtins.str'
14191419
_testAsyncioGatherPreciseType.py:10: error: Revealed type is 'builtins.str'
14201420

1421+
[case testMultipleInheritanceWorksWithTupleTypeGeneric]
1422+
from typing import SupportsAbs, NamedTuple
1423+
1424+
class Point(NamedTuple('Point', [('x', int), ('y', int)]), SupportsAbs[int]):
1425+
def __abs__(p) -> int:
1426+
return abs(p.x) + abs(p.y)
1427+
1428+
def test(a: Point) -> bool:
1429+
return abs(a) == 2
1430+
[out]
1431+
14211432
[case testNoCrashOnGenericUnionUnpacking]
14221433
from typing import Union, Dict
14231434

0 commit comments

Comments
 (0)