# Buggy code
def visit_member_expr(self, expr: MemberExpr) -> None:
    base = expr.expr
    base.accept(self)
    # Bind references to module attributes.
    if isinstance(base, RefExpr) and base.kind == MODULE_REF:
        # This branch handles the case foo.bar where foo is a module.
        # In this case base.node is the module's MypyFile and we look up
        # bar in its namespace.  This must be done for all types of bar.
        file = cast(
            Optional[MypyFile], base.node
        )  # can't use isinstance due to issue #2999
        # TODO: Should we actually use this? Not sure if this makes a difference.
        # if file.fullname() == self.cur_mod_id:
        #     names = self.globals
        # else:
        #     names = file.names
        n = file.names.get(expr.name, None) if file is not None else None
        n = self.dereference_module_cross_ref(n)
        if n and not n.module_hidden:
            if not n:
                return
            n = self.rebind_symbol_table_node(n)
            if n:
                # TODO: What if None?
                expr.kind = n.kind
                expr.fullname = n.fullname
                expr.node = n.node
        elif (
            file is not None
            and (file.is_stub or self.options.python_version >= (3, 7))
            and "__getattr__" in file.names
        ):
            # If there is a module-level __getattr__, then any attribute on the module is valid
            # per PEP 484.
            getattr_defn = file.names["__getattr__"]
            if not getattr_defn:
                typ = AnyType(TypeOfAny.from_error)  # type: Type
            elif isinstance(getattr_defn.node, (FuncDef, Var)):
                if isinstance(getattr_defn.node.type, CallableType):
                    typ = getattr_defn.node.type.ret_type
                else:
                    typ = AnyType(TypeOfAny.from_error)
            else:
                typ = AnyType(TypeOfAny.from_error)
            expr.kind = MDEF
            expr.fullname = "{}.{}".format(file.fullname(), expr.name)
            expr.node = Var(expr.name, type=typ)
        else:
            # We only catch some errors here; the rest will be
            # caught during type checking.
            #
            # This way we can report a larger number of errors in
            # one type checker run. If we reported errors here,
            # the build would terminate after semantic analysis
            # and we wouldn't be able to report any type errors.
            full_name = "%s.%s" % (
                file.fullname() if file is not None else None,
                expr.name,
            )
            mod_name = " '%s'" % file.fullname() if file is not None else ""
            if full_name in obsolete_name_mapping:
                self.fail(
                    "Module%s has no attribute %r (it's now called %r)"
                    % (mod_name, expr.name, obsolete_name_mapping[full_name]),
                    expr,
                )
    elif isinstance(base, RefExpr):
        # This branch handles the case C.bar (or cls.bar or self.bar inside
        # a classmethod/method), where C is a class and bar is a type
        # definition or a module resulting from `import bar` (or a module
        # assignment) inside class C. We look up bar in the class' TypeInfo
        # namespace.  This is done only when bar is a module or a type;
        # other things (e.g. methods) are handled by other code in
        # checkmember.
        type_info = None
        if isinstance(base.node, TypeInfo):
            # C.bar where C is a class
            type_info = base.node
        elif isinstance(base.node, Var) and self.type and self.function_stack:
            # check for self.bar or cls.bar in method/classmethod
            func_def = self.function_stack[-1]
            if not func_def.is_static and isinstance(func_def.type, CallableType):
                formal_arg = func_def.type.argument_by_name(base.node.name())
                if formal_arg and formal_arg.pos == 0:
                    type_info = self.type
        elif isinstance(base.node, TypeAlias) and base.node.no_args:
            if isinstance(base.node.target, Instance):
                type_info = base.node.target.type

        if type_info:
            n = type_info.names.get(expr.name)
            if n is not None and (
                n.kind == MODULE_REF or isinstance(n.node, (TypeInfo, TypeAlias))
            ):
                if not n:
                    return
                expr.kind = n.kind
                expr.fullname = n.fullname
                expr.node = n.node


# Traceback (AssertionError)
sphinx/util/docutils.py:61: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.641
Traceback (most recent call last):
File "/Users/tkomiya/.pyenv/versions/3.7.1/bin/mypy", line 11, in <module>
sys.exit(console_entry())
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/__main__.py", line 7, in console_entry
main(None)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/main.py", line 92, in main
res = build.build(sources, options, None, flush_errors, fscache)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/build.py", line 155, in build
result = _build(sources, options, alt_lib_path, flush_errors, fscache)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/build.py", line 204, in _build
graph = dispatch(sources, manager)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/build.py", line 2172, in dispatch
process_graph(graph, manager)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/build.py", line 2469, in process_graph
process_stale_scc(graph, scc, manager)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/build.py", line 2592, in process_stale_scc
graph[id].type_check_first_pass()
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/build.py", line 1730, in type_check_first_pass
self.type_checker().check_first_pass()
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 282, in check_first_pass
self.accept(d)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 393, in accept
stmt.accept(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/nodes.py", line 688, in accept
return visitor.visit_decorator(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 3002, in visit_decorator
self.check_func_item(e.func, name=e.func.name())
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 770, in check_func_item
self.check_func_def(defn, typ, name)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 934, in check_func_def
self.accept(item.body)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 393, in accept
stmt.accept(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/nodes.py", line 910, in accept
return visitor.visit_block(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 1688, in visit_block
self.accept(s)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 393, in accept
stmt.accept(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/nodes.py", line 1137, in accept
return visitor.visit_try_stmt(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 2808, in visit_try_stmt
self.accept(s.finally_body)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 393, in accept
stmt.accept(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/nodes.py", line 910, in accept
return visitor.visit_block(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 1688, in visit_block
self.accept(s)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 393, in accept
stmt.accept(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/nodes.py", line 965, in accept
return visitor.visit_assignment_stmt(self)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 1696, in visit_assignment_stmt
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 1751, in check_assignment
if self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue):
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/checker.py", line 1822, in check_compatibility_all_supers
len(lvalue_node.info.bases) > 0):
File "/Users/tkomiya/.pyenv/versions/3.7.1/lib/python3.7/site-packages/mypy/nodes.py", line 2488, in __getattribute__
raise AssertionError(object.__getattribute__(self, 'msg'))
AssertionError: Var is lacking info
sphinx/util/docutils.py:61: : note: use --pdb to drop into pdb

# Fixed code
def visit_member_expr(self, expr: MemberExpr) -> None:
    base = expr.expr
    base.accept(self)
    # Bind references to module attributes.
    if isinstance(base, RefExpr) and base.kind == MODULE_REF:
        # This branch handles the case foo.bar where foo is a module.
        # In this case base.node is the module's MypyFile and we look up
        # bar in its namespace.  This must be done for all types of bar.
        file = cast(
            Optional[MypyFile], base.node
        )  # can't use isinstance due to issue #2999
        # TODO: Should we actually use this? Not sure if this makes a difference.
        # if file.fullname() == self.cur_mod_id:
        #     names = self.globals
        # else:
        #     names = file.names
        n = file.names.get(expr.name, None) if file is not None else None
        n = self.dereference_module_cross_ref(n)
        if n and not n.module_hidden:
            if not n:
                return
            n = self.rebind_symbol_table_node(n)
            if n:
                # TODO: What if None?
                expr.kind = n.kind
                expr.fullname = n.fullname
                expr.node = n.node
        elif (
            file is not None
            and (file.is_stub or self.options.python_version >= (3, 7))
            and "__getattr__" in file.names
        ):
            # If there is a module-level __getattr__, then any attribute on the module is valid
            # per PEP 484.
            getattr_defn = file.names["__getattr__"]
            if not getattr_defn:
                typ = AnyType(TypeOfAny.from_error)  # type: Type
            elif isinstance(getattr_defn.node, (FuncDef, Var)):
                if isinstance(getattr_defn.node.type, CallableType):
                    typ = getattr_defn.node.type.ret_type
                else:
                    typ = AnyType(TypeOfAny.from_error)
            else:
                typ = AnyType(TypeOfAny.from_error)
            expr.kind = GDEF
            expr.fullname = "{}.{}".format(file.fullname(), expr.name)
            expr.node = Var(expr.name, type=typ)
        else:
            # We only catch some errors here; the rest will be
            # caught during type checking.
            #
            # This way we can report a larger number of errors in
            # one type checker run. If we reported errors here,
            # the build would terminate after semantic analysis
            # and we wouldn't be able to report any type errors.
            full_name = "%s.%s" % (
                file.fullname() if file is not None else None,
                expr.name,
            )
            mod_name = " '%s'" % file.fullname() if file is not None else ""
            if full_name in obsolete_name_mapping:
                self.fail(
                    "Module%s has no attribute %r (it's now called %r)"
                    % (mod_name, expr.name, obsolete_name_mapping[full_name]),
                    expr,
                )
    elif isinstance(base, RefExpr):
        # This branch handles the case C.bar (or cls.bar or self.bar inside
        # a classmethod/method), where C is a class and bar is a type
        # definition or a module resulting from `import bar` (or a module
        # assignment) inside class C. We look up bar in the class' TypeInfo
        # namespace.  This is done only when bar is a module or a type;
        # other things (e.g. methods) are handled by other code in
        # checkmember.
        type_info = None
        if isinstance(base.node, TypeInfo):
            # C.bar where C is a class
            type_info = base.node
        elif isinstance(base.node, Var) and self.type and self.function_stack:
            # check for self.bar or cls.bar in method/classmethod
            func_def = self.function_stack[-1]
            if not func_def.is_static and isinstance(func_def.type, CallableType):
                formal_arg = func_def.type.argument_by_name(base.node.name())
                if formal_arg and formal_arg.pos == 0:
                    type_info = self.type
        elif isinstance(base.node, TypeAlias) and base.node.no_args:
            if isinstance(base.node.target, Instance):
                type_info = base.node.target.type

        if type_info:
            n = type_info.names.get(expr.name)
            if n is not None and (
                n.kind == MODULE_REF or isinstance(n.node, (TypeInfo, TypeAlias))
            ):
                if not n:
                    return
                expr.kind = n.kind
                expr.fullname = n.fullname
                expr.node = n.node