Repository: python/mypy

Issue:
RuntimeError when accessing class attribute
The following code breaks mypy:

```
from typing import Any

class FooBar(object):

    # Mapping from dual mc name to a DualClient instance.
    _dual_mc = {}

    @staticmethod
    def foo():
        # type: () -> Any
        "x" in FooBar._dual_mc
```

Stacktrace:

```
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/bin/mypy", line 6, in <module>
    main(__file__)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/main.py", line 53, in main
    type_check_only(sources, bin_dir, options)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/main.py", line 96, in type_check_only
    python_path=options.python_path)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/build.py", line 203, in build
    result = manager.process(initial_states)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/build.py", line 386, in process
    next.process()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/build.py", line 885, in process
    self.type_checker().visit_file(self.tree, self.tree.path)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 385, in visit_file
    self.accept(d)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 394, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 485, in accept
    return visitor.visit_class_def(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 963, in visit_class_def
    self.accept(defn.defs)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 394, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 526, in accept
    return visitor.visit_block(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 1058, in visit_block
    self.accept(s)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 394, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 413, in accept
    return visitor.visit_decorator(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 1815, in visit_decorator
    e.func.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 382, in accept
    return visitor.visit_func_def(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 509, in visit_func_def
    self.check_func_item(defn, name=defn.name())
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 567, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 663, in check_func_def
    self.accept_in_frame(item.body)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 409, in accept_in_frame
    answer = self.accept(node, type_context)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 394, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 526, in accept
    return visitor.visit_block(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 1058, in visit_block
    self.accept(s)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 394, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 540, in accept
    return visitor.visit_expression_stmt(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 1470, in visit_expression_stmt
    self.accept(s.expr)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 394, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 1125, in accept
    return visitor.visit_comparison_expr(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 1940, in visit_comparison_expr
    return self.expr_checker.visit_comparison_expr(e)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checkexpr.py", line 842, in visit_comparison_expr
    self.is_valid_var_arg(right_type)):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checkexpr.py", line 1405, in is_valid_var_arg
    [AnyType()])) or
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/subtypes.py", line 49, in is_subtype
    return left.accept(SubtypeVisitor(right, type_parameter_checker))
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/types.py", line 544, in accept
    return visitor.visit_partial_type(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/subtypes.py", line 195, in visit_partial_type
    raise RuntimeError
RuntimeError:
```



Discussion:
Adding annotations to `FooBar._dual_mc = {}  # type: Dict[Any, Any]` seems to fix the error.


Resolving patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -837,7 +837,10 @@ def visit_comparison_expr(self, e: ComparisonExpr) -> Type:
                 local_errors.disable_count = 0
                 sub_result, method_type = self.check_op_local('__contains__', right_type,
                                                           left, e, local_errors)
-                if (local_errors.is_errors() and
+                if isinstance(right_type, PartialType):
+                    # We don't really know if this is an error or not, so just shut up.
+                    pass
+                elif (local_errors.is_errors() and
                     # is_valid_var_arg is True for any Iterable
                         self.is_valid_var_arg(right_type)):
                     itertype = self.chk.analyze_iterable_item_type(right)


Test patch: