Repository: python/mypy

Issue:
Caching problem with --new-semantic-analyzer and --warn-unused-ignores
With mypy 0.710 (Python 3.7.2) and the new semantic analyzer, I got a strange caching problem. Consider a directory with three files:

```python
# __init__.py (empty)

# foo.py
from typing import Any

class desc:
    def __get__(self, _: Any, __: Any = None) -> int:
        return 42

class Base:
    @property
    def foo(self) -> int:
        raise NotImplementedError()

class Sub(Base):
    foo = desc(42)  # type: ignore

# bar.py
from foo import Sub

Sub().foo
Sub().foo
```

Running mypy in this directory for the first time with `PYTHONPATH=. mypy --new-semantic-analyzer --warn-unused-ignores bar.py` results in the following (expected) output:

```
bar.py:3: error: Cannot determine type of 'foo'
bar.py:4: error: Cannot determine type of 'foo'
```

Changing `bar.py` to this:

```python
from foo import Sub

Sub().foo  # type: ignore
Sub().foo
```

and rerunning mypy with the command above now results in this error message:

```
bar.py:3: note: unused 'type: ignore' comment
```

Note that the problem in line 4 is not reported anymore.

Restoring the original `bar.py` and rerunning mypy for a third time will pass without any error message.

Deleting `.mypy_cache` will start this process from the beginning.



Discussion:
Thanks for reporting! I think this is important to investigate.

Resolving patch:
diff --git a/mypy/nodes.py b/mypy/nodes.py
--- a/mypy/nodes.py
+++ b/mypy/nodes.py
@@ -763,7 +763,7 @@ def deserialize(cls, data: JsonDict) -> 'Decorator':
     'is_self', 'is_initialized_in_class', 'is_staticmethod',
     'is_classmethod', 'is_property', 'is_settable_property', 'is_suppressed_import',
     'is_classvar', 'is_abstract_var', 'is_final', 'final_unset_in_class', 'final_set_in_init',
-    'explicit_self_type',
+    'explicit_self_type', 'is_ready',
 ]  # type: Final
 
 
@@ -867,6 +867,7 @@ def deserialize(cls, data: JsonDict) -> 'Var':
         name = data['name']
         type = None if data['type'] is None else mypy.types.deserialize_type(data['type'])
         v = Var(name, type)
+        v.is_ready = False  # Override True default set in __init__
         v._fullname = data['fullname']
         set_flags(v, data['flags'])
         v.final_value = data.get('final_value')


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
@@ -5069,3 +5069,41 @@ def test() -> None:
 [builtins fixtures/list.pyi]
 [out]
 [out2]
+
+[case testCannotDetermineTypeFromOtherModule]
+# flags: --new-semantic-analyzer
+import aa
+
+[file aa.py]
+import a
+
+[file aa.py.2]
+import a  # dummy
+
+[file a.py]
+from b import Sub
+
+Sub().foo
+Sub().foo
+
+[file b.py]
+from typing import Any
+
+class desc:
+    def __get__(self, _: Any, __: Any = None) -> int:
+        return 42
+
+class Base:
+    @property
+    def foo(self) -> int: ...
+
+class Sub(Base):
+    foo = desc(42)  # type: ignore
+
+[builtins fixtures/property.pyi]
+[out]
+tmp/a.py:3: error: Cannot determine type of 'foo'
+tmp/a.py:4: error: Cannot determine type of 'foo'
+[out2]
+tmp/a.py:3: error: Cannot determine type of 'foo'
+tmp/a.py:4: error: Cannot determine type of 'foo'