# Buggy code
def check_reverse_op_method(
    self, defn: FuncItem, typ: CallableType, method: str, context: Context
) -> None:
    """Check a reverse operator method such as __radd__."""

    # This used to check for some very obscure scenario.  It now
    # just decides whether it's worth calling
    # check_overlapping_op_methods().

    # First check for a valid signature
    method_type = CallableType(
        [AnyType(TypeOfAny.special_form), AnyType(TypeOfAny.special_form)],
        [nodes.ARG_POS, nodes.ARG_POS],
        [None, None],
        AnyType(TypeOfAny.special_form),
        self.named_type("builtins.function"),
    )
    if not is_subtype(typ, method_type):
        self.msg.invalid_signature(typ, context)
        return

    if method in ("__eq__", "__ne__"):
        # These are defined for all objects => can't cause trouble.
        return

    # With 'Any' or 'object' return type we are happy, since any possible
    # return value is valid.
    ret_type = typ.ret_type
    if isinstance(ret_type, AnyType):
        return
    if isinstance(ret_type, Instance):
        if ret_type.type.fullname() == "builtins.object":
            return

    if len(typ.arg_types) == 2:
        # TODO check self argument kind

        # Check for the issue described above.
        arg_type = typ.arg_types[1]
        other_method = nodes.normal_from_reverse_op[method]
        if isinstance(arg_type, Instance):
            if not arg_type.type.has_readable_member(other_method):
                return
        elif isinstance(arg_type, AnyType):
            return
        elif isinstance(arg_type, UnionType):
            if not arg_type.has_readable_member(other_method):
                return
        else:
            return

        typ2 = self.expr_checker.analyze_external_member_access(
            other_method, arg_type, defn
        )
        self.check_overlapping_op_methods(
            typ, method, defn.info, typ2, other_method, cast(Instance, arg_type), defn
        )


# Traceback (AttributeError)
third_party/3/pyspark/sql/column.pyi:24: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.511
Traceback (most recent call last):
File "/home/user/anaconda3/bin/mypy", line 6, in <module>
main(__file__)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/main.py", line 46, in main
res = type_check_only(sources, bin_dir, options)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/main.py", line 93, in type_check_only
options=options)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/build.py", line 188, in build
graph = dispatch(sources, manager)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/build.py", line 1595, in dispatch
process_graph(graph, manager)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/build.py", line 1838, in process_graph
process_stale_scc(graph, scc, manager)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/build.py", line 1937, in process_stale_scc
graph[id].type_check_first_pass()
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/build.py", line 1510, in type_check_first_pass
self.type_checker.check_first_pass()
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 177, in check_first_pass
self.accept(d)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 264, in accept
stmt.accept(self)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/nodes.py", line 750, in accept
return visitor.visit_class_def(self)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 1080, in visit_class_def
self.accept(defn.defs)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 264, in accept
stmt.accept(self)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/nodes.py", line 811, in accept
return visitor.visit_block(self)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 1173, in visit_block
self.accept(s)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 264, in accept
stmt.accept(self)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/nodes.py", line 565, in accept
return visitor.visit_func_def(self)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 510, in visit_func_def
self.check_func_item(defn, name=defn.name())
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 569, in check_func_item
self.check_func_def(defn, typ, name)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 616, in check_func_def
self.check_reverse_op_method(item, typ, name)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 806, in check_reverse_op_method
defn)
File "/home/user/anaconda3/lib/python3.5/site-packages/mypy/checker.py", line 876, in check_overlapping_op_methods
forward_base.type.name(), forward_name, context)
AttributeError: 'UnionType' object has no attribute 'type'
third_party/3/pyspark/sql/column.pyi:24: note: use --pdb to drop into pdb

# Fixed code
def check_reverse_op_method(
    self,
    defn: FuncItem,
    reverse_type: CallableType,
    reverse_name: str,
    context: Context,
) -> None:
    """Check a reverse operator method such as __radd__."""
    # Decides whether it's worth calling check_overlapping_op_methods().

    # This used to check for some very obscure scenario.  It now
    # just decides whether it's worth calling
    # check_overlapping_op_methods().

    # First check for a valid signature
    method_type = CallableType(
        [AnyType(TypeOfAny.special_form), AnyType(TypeOfAny.special_form)],
        [nodes.ARG_POS, nodes.ARG_POS],
        [None, None],
        AnyType(TypeOfAny.special_form),
        self.named_type("builtins.function"),
    )
    if not is_subtype(reverse_type, method_type):
        self.msg.invalid_signature(reverse_type, context)
        return

    if reverse_name in ("__eq__", "__ne__"):
        # These are defined for all objects => can't cause trouble.
        return

    # With 'Any' or 'object' return type we are happy, since any possible
    # return value is valid.
    ret_type = reverse_type.ret_type
    if isinstance(ret_type, AnyType):
        return
    if isinstance(ret_type, Instance):
        if ret_type.type.fullname() == "builtins.object":
            return
    if reverse_type.arg_kinds[0] == ARG_STAR:
        reverse_type = reverse_type.copy_modified(
            arg_types=[reverse_type.arg_types[0]] * 2,
            arg_kinds=[ARG_POS] * 2,
            arg_names=[reverse_type.arg_names[0], "_"],
        )
    assert len(reverse_type.arg_types) == 2

    forward_name = nodes.normal_from_reverse_op[reverse_name]
    forward_inst = reverse_type.arg_types[1]
    if isinstance(forward_inst, TypeVarType):
        forward_inst = forward_inst.upper_bound
    if isinstance(forward_inst, (FunctionLike, TupleType, TypedDictType)):
        forward_inst = forward_inst.fallback
    if isinstance(forward_inst, TypeType):
        item = forward_inst.item
        if isinstance(item, Instance):
            opt_meta = item.type.metaclass_type
            if opt_meta is not None:
                forward_inst = opt_meta
    if not (
        isinstance(forward_inst, (Instance, UnionType))
        and forward_inst.has_readable_member(forward_name)
    ):
        return
    forward_base = reverse_type.arg_types[1]
    forward_type = self.expr_checker.analyze_external_member_access(
        forward_name, forward_base, context=defn
    )
    self.check_overlapping_op_methods(
        reverse_type,
        reverse_name,
        defn.info,
        forward_type,
        forward_name,
        forward_base,
        context=defn,
    )