Repository: python/mypy

Issue:
`INTERNAL ERROR` with generic type + NamedTuple + classmethod
The following code crashes mypy (Python 3.6.5 / mypy 0.641) : 

```python
from typing import TypeVar, Type, NamedTuple

T = TypeVar('T', bound='Parent')

class Parent(NamedTuple):
    attr1: str

    @classmethod
    def with_stuff_appended(cls: Type[T]) -> T:
        return cls(attr1='bla')

class Child(Parent):
    pass
```

Traceback : 

```traceback
test.py:10: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.641
Traceback (most recent call last):
  File "/home/spiq/.virtualenvs/kialo/bin/mypy", line 11, in <module>
    sys.exit(console_entry())
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/main.py", line 92, in main
    res = build.build(sources, options, None, flush_errors, fscache)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/build.py", line 155, in build
    result = _build(sources, options, alt_lib_path, flush_errors, fscache)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/build.py", line 204, in _build
    graph = dispatch(sources, manager)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/build.py", line 2172, in dispatch
    process_graph(graph, manager)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/build.py", line 2469, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/build.py", line 2592, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/build.py", line 1730, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 282, in check_first_pass
    self.accept(d)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 393, in accept
    stmt.accept(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/nodes.py", line 845, in accept
    return visitor.visit_class_def(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 1536, in visit_class_def
    self.accept(defn.defs)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 393, in accept
    stmt.accept(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/nodes.py", line 910, in accept
    return visitor.visit_block(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 1688, in visit_block
    self.accept(s)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 393, in accept
    stmt.accept(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/nodes.py", line 688, in accept
    return visitor.visit_decorator(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 3002, in visit_decorator
    self.check_func_item(e.func, name=e.func.name())
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 770, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 934, in check_func_def
    self.accept(item.body)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 393, in accept
    stmt.accept(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/nodes.py", line 910, in accept
    return visitor.visit_block(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 1688, in visit_block
    self.accept(s)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 393, in accept
    stmt.accept(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/nodes.py", line 1043, in accept
    return visitor.visit_return_stmt(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 2606, in visit_return_stmt
    self.check_return_stmt(s)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checker.py", line 2639, in check_return_stmt
    allow_none_return=allow_none_func_call)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checkexpr.py", line 3007, in accept
    typ = node.accept(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/nodes.py", line 1418, in accept
    return visitor.visit_call_expr(self)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checkexpr.py", line 229, in visit_call_expr
    return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checkexpr.py", line 307, in visit_call_expr_inner
    ret_type = self.check_call_expr_with_callee_type(callee_type, e, fullname, object_type)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checkexpr.py", line 587, in check_call_expr_with_callee_type
    object_type=object_type)[0]
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checkexpr.py", line 721, in check_call
    callable_node, arg_messages)
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/checkexpr.py", line 628, in check_call
    if (callee.is_type_obj() and callee.type_object().is_abstract
  File "/home/spiq/.virtualenvs/kialo/lib/python3.6/site-packages/mypy/types.py", line 817, in type_object
    assert isinstance(ret, Instance)
AssertionError: 
test.py:10: : note: use --pdb to drop into pdb

```




Discussion:
Confirmed on master.

Resolving patch:
diff --git a/mypy/types.py b/mypy/types.py
--- a/mypy/types.py
+++ b/mypy/types.py
@@ -923,10 +923,10 @@ def is_type_obj(self) -> bool:
     def type_object(self) -> mypy.nodes.TypeInfo:
         assert self.is_type_obj()
         ret = self.ret_type
-        if isinstance(ret, TupleType):
-            ret = ret.partial_fallback
         if isinstance(ret, TypeVarType):
             ret = ret.upper_bound
+        if isinstance(ret, TupleType):
+            ret = ret.partial_fallback
         assert isinstance(ret, Instance)
         return ret.type
 


Test patch:
diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test
--- a/test-data/unit/check-namedtuple.test
+++ b/test-data/unit/check-namedtuple.test
@@ -828,3 +828,21 @@ class Child(Base):
 
 Base(param=10)
 Child(param=10)
+
+[case testNamedTupleClassMethodWithGenericReturnValue]
+from typing import TypeVar, Type, NamedTuple
+
+T = TypeVar('T', bound='Parent')
+
+class Parent(NamedTuple):
+    x: str
+
+    @classmethod
+    def class_method(cls: Type[T]) -> T:
+        return cls(x='text')
+
+class Child(Parent):
+    pass
+
+reveal_type(Child.class_method())  # E: Revealed type is 'Tuple[builtins.str, fallback=__main__.Child]'
+[builtins fixtures/classmethod.pyi]