Repository: python/mypy

Issue:
INTERNAL ERROR when using `:=` assignment expression
To reproduce the bug, run `mypy` with the following command:
```bash
mypy --show-traceback test.py
```

Where the contents of `test.py` are:

```python
def func() -> None:
    obj = MyClass()
    if result := obj.var_name:
        pass


class MyClass:
    def __init__(self):
        self.var_name = "abc"
```

Here is the traceback that I get:

```
test.py:3: error: INTERNAL ERROR -- Please try using mypy master on Github:
https://mypy.rtfd.io/en/latest/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.790+dev.6ee562a8f3e69ac134f8c501b79b3712c9e24bbd
Traceback (most recent call last):
  File "***/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "***/python3.8/site-packages/mypy/__main__.py", line 8, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "***/python3.8/site-packages/mypy/main.py", line 89, in main
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "***/python3.8/site-packages/mypy/build.py", line 180, in build
    result = _build(
  File "***/python3.8/site-packages/mypy/build.py", line 252, in _build
    graph = dispatch(sources, manager, stdout)
  File "***/python3.8/site-packages/mypy/build.py", line 2626, in dispatch
    process_graph(graph, manager)
  File "***/python3.8/site-packages/mypy/build.py", line 2949, in process_graph
    process_stale_scc(graph, scc, manager)
  File "***/python3.8/site-packages/mypy/build.py", line 3047, in process_stale_scc
    graph[id].type_check_first_pass()
  File "***/python3.8/site-packages/mypy/build.py", line 2107, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "***/python3.8/site-packages/mypy/checker.py", line 294, in check_first_pass
    self.accept(d)
  File "***/python3.8/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "***/python3.8/site-packages/mypy/nodes.py", line 677, in accept
    return visitor.visit_func_def(self)
  File "***/python3.8/site-packages/mypy/checker.py", line 726, in visit_func_def
    self._visit_func_def(defn)
  File "***/python3.8/site-packages/mypy/checker.py", line 730, in _visit_func_def
    self.check_func_item(defn, name=defn.name)
  File "***/python3.8/site-packages/mypy/checker.py", line 792, in check_func_item
    self.check_func_def(defn, typ, name)
  File "***/python3.8/site-packages/mypy/checker.py", line 975, in check_func_def
    self.accept(item.body)
  File "***/python3.8/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "***/python3.8/site-packages/mypy/nodes.py", line 1005, in accept
    return visitor.visit_block(self)
  File "***/python3.8/site-packages/mypy/checker.py", line 1973, in visit_block
    self.accept(s)
  File "***/python3.8/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "***/python3.8/site-packages/mypy/nodes.py", line 1196, in accept
    return visitor.visit_if_stmt(self)
  File "***/python3.8/site-packages/mypy/checker.py", line 3212, in visit_if_stmt
    if_map, else_map = self.find_isinstance_check(e)
  File "***/python3.8/site-packages/mypy/checker.py", line 3928, in find_isinstance_check
    if_map, else_map = self.find_isinstance_check_helper(node)
  File "***/python3.8/site-packages/mypy/checker.py", line 4104, in find_isinstance_check_helper
    return self.find_isinstance_check_helper(node.target)
  File "***/python3.8/site-packages/mypy/checker.py", line 4108, in find_isinstance_check_helper
    vartype = type_map[node]
KeyError: <mypy.nodes.NameExpr object at 0x7fb2f0768940>
test.py:3: : note: use --pdb to drop into pdb
```


mypy 0.790+dev.6ee562a8f3e69ac134f8c501b79b3712c9e24bbd
Python 3.8.2



Discussion:
This is a pretty bad crash, since the example looks fairly straightforward.

Resolving patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -3788,6 +3788,9 @@ def accept(self,
         assert typ is not None
         self.chk.store_type(node, typ)
 
+        if isinstance(node, AssignmentExpr) and not has_uninhabited_component(typ):
+            self.chk.store_type(node.target, typ)
+
         if (self.chk.options.disallow_any_expr and
                 not always_allow_any and
                 not self.chk.is_stub and


Test patch:
diff --git a/test-data/unit/check-python38.test b/test-data/unit/check-python38.test
--- a/test-data/unit/check-python38.test
+++ b/test-data/unit/check-python38.test
@@ -377,3 +377,13 @@ def check_partial_list() -> None:
         z.append(3)
     reveal_type(z)  # N: Revealed type is 'builtins.list[builtins.int]'
 [builtins fixtures/list.pyi]
+
+[case testWalrusExpr]
+def func() -> None:
+    foo = Foo()
+    if x := foo.x:
+        pass
+
+class Foo:
+    def __init__(self) -> None:
+        self.x = 123