Repository: python/mypy

Issue:
Tuple[int] (0, 0) is not considered Container[T]
This program fails:

``` python
from typing import *
T = TypeVar('T')
def foo(a: Container[T]) -> T: ...
foo((1, 2))  # E: Argument 1 to "foo" has incompatible type "Tuple[int, int]"; expected Container[None]
```

But without a type variable it works:

``` python
from typing import *
def foo(a: Container[int]) -> int: ...
foo((1, 2))  # OK
```

The same program (with type variable) does work substituting Iterable[T]:

``` python
from typing import *
T = TypeVar('T')
def foo(a: Iterable[T]) -> T: ...
foo((1, 2))  # OK
```

Explain?

Tuple[int] (0, 0) is not considered Container[T]
This program fails:

``` python
from typing import *
T = TypeVar('T')
def foo(a: Container[T]) -> T: ...
foo((1, 2))  # E: Argument 1 to "foo" has incompatible type "Tuple[int, int]"; expected Container[None]
```

But without a type variable it works:

``` python
from typing import *
def foo(a: Container[int]) -> int: ...
foo((1, 2))  # OK
```

The same program (with type variable) does work substituting Iterable[T]:

``` python
from typing import *
T = TypeVar('T')
def foo(a: Iterable[T]) -> T: ...
foo((1, 2))  # OK
```

Explain?



Discussion:
See https://github.com/python/mypy/blob/master/mypy/constraints.py#L279. I imagine it just needs another case for `Container`, to match https://github.com/python/mypy/blob/master/mypy/subtypes.py#L174.

Would also need a test. But still very easy.

@gvanrossum Working on it, but one question – where should I write the test? Should it be in `test-data/unit`?

It should go in one of the files under `test-data/unit`. Preferably next to a similar test for Iterable or Sequence etc., if you can find one.

See https://github.com/python/mypy/blob/master/mypy/constraints.py#L279. I imagine it just needs another case for `Container`, to match https://github.com/python/mypy/blob/master/mypy/subtypes.py#L174.

Would also need a test. But still very easy.

@gvanrossum Working on it, but one question – where should I write the test? Should it be in `test-data/unit`?

It should go in one of the files under `test-data/unit`. Preferably next to a similar test for Iterable or Sequence etc., if you can find one.


Resolving patch:
diff --git a/mypy/constraints.py b/mypy/constraints.py
--- a/mypy/constraints.py
+++ b/mypy/constraints.py
@@ -278,6 +278,7 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
             return self.infer_against_any(template.args)
         if (isinstance(actual, TupleType) and
             (is_named_instance(template, 'typing.Iterable') or
+             is_named_instance(template, 'typing.Container') or
              is_named_instance(template, 'typing.Sequence') or
              is_named_instance(template, 'typing.Reversible'))
                 and self.direction == SUPERTYPE_OF):


Test patch:
diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test
--- a/test-data/unit/check-generics.test
+++ b/test-data/unit/check-generics.test
@@ -851,3 +851,9 @@ def f3(x: A, y: B) -> B: ...
 g = f1
 g = f2
 g = f3
+
+[case testTypeVariableWithContainerAndTuple]
+from typing import TypeVar, Container
+T = TypeVar('T')
+def f(x: Container[T]) -> T: ...
+reveal_type(f((1, 2))) # E: Revealed type is 'builtins.int*'