Repository: python/mypy

Issue:
Crash in TypeVarType.serialize() when extracting dict().get as a variable
Repro:
```python
from typing import *
d = {}  # type: Dict[str, int]
g = d.get
```
Traceback:
```
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/guido/src/mypy/mypy/__main__.py", line 5, in <module>
    main(None)
  File "/Users/guido/src/mypy/mypy/main.py", line 42, in main
    res = type_check_only(sources, bin_dir, options)
  File "/Users/guido/src/mypy/mypy/main.py", line 86, in type_check_only
    options=options)
  File "/Users/guido/src/mypy/mypy/build.py", line 183, in build
    dispatch(sources, manager)
  File "/Users/guido/src/mypy/mypy/build.py", line 1531, in dispatch
    process_graph(graph, manager)
  File "/Users/guido/src/mypy/mypy/build.py", line 1768, in process_graph
    process_stale_scc(graph, scc)
  File "/Users/guido/src/mypy/mypy/build.py", line 1856, in process_stale_scc
    graph[id].write_cache()
  File "/Users/guido/src/mypy/mypy/build.py", line 1512, in write_cache
    self.manager)
  File "/Users/guido/src/mypy/mypy/build.py", line 862, in write_cache
    data = tree.serialize()
  File "/Users/guido/src/mypy/mypy/nodes.py", line 271, in serialize
    'names': self.names.serialize(self._fullname),
  File "/Users/guido/src/mypy/mypy/nodes.py", line 2265, in serialize
    data[key] = value.serialize(fullname, key)
  File "/Users/guido/src/mypy/mypy/nodes.py", line 2211, in serialize
    data['node'] = self.node.serialize()
  File "/Users/guido/src/mypy/mypy/nodes.py", line 671, in serialize
    'type': None if self.type is None else self.type.serialize(),
  File "/Users/guido/src/mypy/mypy/types.py", line 837, in serialize
    'items': [t.serialize() for t in self.items()],
  File "/Users/guido/src/mypy/mypy/types.py", line 837, in <listcomp>
    'items': [t.serialize() for t in self.items()],
  File "/Users/guido/src/mypy/mypy/types.py", line 763, in serialize
    for t in self.arg_types],
  File "/Users/guido/src/mypy/mypy/types.py", line 763, in <listcomp>
    for t in self.arg_types],
  File "/Users/guido/src/mypy/mypy/types.py", line 1079, in serialize
    'items': [t.serialize() for t in self.items],
  File "/Users/guido/src/mypy/mypy/types.py", line 1079, in <listcomp>
    'items': [t.serialize() for t in self.items],
  File "/Users/guido/src/mypy/mypy/types.py", line 496, in serialize
    assert not self.id.is_meta_var()
AssertionError
```


Discussion:

Resolving patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -990,6 +990,13 @@ def analyze_ordinary_member_access(self, e: MemberExpr,
                 e.name, original_type, e, is_lvalue, False, False,
                 self.named_type, self.not_ready_callback, self.msg,
                 original_type=original_type, chk=self.chk)
+            if isinstance(member_type, CallableType):
+                for v in member_type.variables:
+                    v.id.meta_level = 0
+            if isinstance(member_type, Overloaded):
+                for it in member_type.items():
+                    for v in it.variables:
+                        v.id.meta_level = 0
             if is_lvalue:
                 return member_type
             else:


Test patch:
diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test
--- a/test-data/unit/check-incremental.test
+++ b/test-data/unit/check-incremental.test
@@ -1767,6 +1767,25 @@ main:2: error: Revealed type is 'TypedDict(x=builtins.int, _fallback=typing.Mapp
 main:3: error: Revealed type is 'TypedDict(x=builtins.int, _fallback=ntcrash.C.A@4)'
 main:4: error: Revealed type is 'def () -> ntcrash.C.A@4'
 
+[case testGenericMethodRestoreMetaLevel]
+from typing import Dict
+
+d = {}  # type: Dict[str, int]
+g = d.get  # This should not crash: see https://github.com/python/mypy/issues/2804
+[builtins fixtures/dict.pyi]
+
+[case testGenericMethodRestoreMetaLevel2]
+from typing import TypeVar
+
+T = TypeVar('T')
+
+class D:
+    def m(self, x: T) -> T:
+        return x
+
+g = D().m  # This should not crash: see https://github.com/python/mypy/issues/2804
+[builtins fixtures/dict.pyi]
+
 [case testIncrementalPerFileFlags]
 # flags: --config-file tmp/mypy.ini
 import a