# Buggy code
def get_attribute(self, node, obj, name, valself=None):
    """Get the named attribute from the given object.

    Args:
      node: The current CFG node.
      obj: The object.
      name: The name of the attribute to retrieve.
      valself: A cfg.Binding to a self reference to include in the attribute's
        origins. If obj is a mixin.Class, valself can be a binding to:
        * an instance of obj - obj will be treated strictly as a class.
        * obj itself - obj will be treated as an instance of its metaclass.
        * None - if name == "__getitem__", obj is a type annotation; else, obj
            is strictly a class, but the attribute is left unbound.
        Else, valself is optional and should be a binding to obj when given.

    Returns:
      A tuple (CFGNode, cfg.Variable). If this attribute doesn't exist,
      the Variable will be None.
    """
    if name in obj.late_annotations:
        # We're using a late annotation before it's been evaluated. We could call
        # _process_one_annotation with the current (incomplete) globals, but
        # whether the call succeeds would depend on the order in which the globals
        # are analyzed. It's simpler (although less precise) to just return Any.
        return node, self.vm.new_unsolvable(node)
    # Some objects have special attributes, like "__get__" or "__iter__"
    special_attribute = obj.get_special_attribute(node, name, valself)
    if special_attribute is not None:
        return node, special_attribute
    if isinstance(obj, abstract.Function):
        if name == "__get__":
            # The pytd for "function" has a __get__ attribute, but if we already
            # have a function we don't want to be treated as a descriptor.
            return node, None
        else:
            return self._get_instance_attribute(node, obj, name, valself)
    elif isinstance(obj, abstract.ParameterizedClass):
        return self.get_attribute(node, obj.base_cls, name, valself)
    elif isinstance(obj, mixin.Class):
        return self._get_class_attribute(node, obj, name, valself)
    elif isinstance(obj, overlay.Overlay):
        return self._get_module_attribute(node, obj.get_module(name), name, valself)
    elif isinstance(obj, abstract.Module):
        return self._get_module_attribute(node, obj, name, valself)
    elif isinstance(obj, abstract.SimpleAbstractValue):
        return self._get_instance_attribute(node, obj, name, valself)
    elif isinstance(obj, abstract.Union):
        nodes = []
        ret = self.vm.program.NewVariable()
        for o in obj.options:
            node2, attr = self.get_attribute(node, o, name, valself)
            if attr is not None:
                ret.PasteVariable(attr, node2)
                nodes.append(node2)
        if ret.bindings:
            return self.vm.join_cfg_nodes(nodes), ret
        else:
            return node, None
    elif isinstance(obj, special_builtins.SuperInstance):
        if obj.super_obj:
            cls = obj.super_cls
            valself = obj.super_obj.to_binding(node)
            skip = obj.super_cls
        else:
            cls = self.vm.convert.super_type
            skip = None
        return self._lookup_from_mro_and_handle_descriptors(
            node, cls, name, valself, skip
        )
    elif isinstance(obj, special_builtins.Super):
        return self.get_attribute(node, self.vm.convert.super_type, name, valself)
    elif isinstance(obj, abstract.BoundFunction):
        return self.get_attribute(node, obj.underlying, name, valself)
    elif isinstance(obj, abstract.TypeParameterInstance):
        param_var = obj.instance.get_instance_type_parameter(obj.name)
        if not param_var.bindings:
            param_var = obj.param.instantiate(self.vm.root_cfg_node)
        results = []
        nodes = []
        for v in param_var.data:
            node2, ret = self.get_attribute(node, v, name, valself)
            if ret is None:
                return node, None
            else:
                results.append(ret)
                nodes.append(node2)
        node = self.vm.join_cfg_nodes(nodes)
        return node, self.vm.join_variables(node, results)
    elif isinstance(obj, abstract.Empty):
        return node, None
    else:
        return node, None


# Traceback (AttributeError)
from typing import Any
def __getattr__(name: Any) -> Any: ...
# Caught error in pytype: 'LateAnnotation' object has no attribute 'Bindings'
# Traceback (most recent call last):
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/io.py", line 131, in check_or_generate_pyi
#     input_filename=options.input, options=options, loader=loader)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/io.py", line 89, in generate_pyi
#     analyze.infer_types, input_filename, options, loader)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/io.py", line 62, in _call
#     deep=deep)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 668, in infer_types
#     tracer.exitpoint = tracer.analyze(loc, defs, maximum_depth)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 407, in analyze
#     return self.analyze_toplevel(node, defs)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 370, in analyze_toplevel
#     new_node = self.analyze_class(node, value)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 352, in analyze_class
#     node = self.analyze_method_var(node, name, b)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 202, in analyze_method_var
#     node2 = self.maybe_analyze_method(node1, val)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 157, in maybe_analyze_method
#     node, _ = self.call_function_with_args(node, val, args)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 121, in call_function_with_args
#     new_node, ret = self.call_function_in_frame(node, fvar, *args)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/analyze.py", line 132, in call_function_in_frame
#     state, var, args, kwargs, starargs, starstarargs)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/vm.py", line 917, in call_function_with_state
#     starstarargs=starstarargs), fallback_to_unsolvable, allow_noreturn=True)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/vm.py", line 953, in call_function
#     new_node, one_result = func.call(node, funcv, args)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/abstract.py", line 3247, in call
#     alias_map=self.alias_map)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/abstract.py", line 3051, in call
#     node2, ret = self.vm.run_frame(frame, node)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/vm.py", line 292, in run_frame
#     state = self.run_instruction(op, state)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/vm.py", line 253, in run_instruction
#     state = bytecode_fn(state, op)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/vm.py", line 1980, in byte_LOAD_ATTR
#     state, val = self.load_attr(state, obj, name)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/vm.py", line 1224, in load_attr
#     node, result, errors = self._retrieve_attr(state.node, obj, attr)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/vm.py", line 1195, in _retrieve_attr
#     node, val.data, attr, val)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/attribute.py", line 65, in get_attribute
#     return self._get_instance_attribute(node, obj, name, valself)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/attribute.py", line 234, in _get_instance_attribute
#     return self._get_attribute(node, obj, obj.cls, name, valself)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/attribute.py", line 270, in _get_attribute
#     node, attr = self.get_attribute(node, cls, name, valself)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/attribute.py", line 58, in get_attribute
#     return self._get_class_attribute(node, obj, name, valself)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/attribute.py", line 229, in _get_class_attribute
#     return self._get_attribute(node, cls, meta, name, valself)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/attribute.py", line 284, in _get_attribute
#     attr = self._filter_var(node, attr)
#   File "/Users/name/.pyenv/versions/3.7.3/envs/venv/lib/python3.7/site-packages/pytype/attribute.py", line 426, in _filter_var
#     bindings = var.Bindings(node, strict=False)
# AttributeError: 'LateAnnotation' object has no attribute 'Bindings'

# Fixed code
def get_attribute(self, node, obj, name, valself=None):
    """Get the named attribute from the given object.

    Args:
      node: The current CFG node.
      obj: The object.
      name: The name of the attribute to retrieve.
      valself: A cfg.Binding to a self reference to include in the attribute's
        origins. If obj is a mixin.Class, valself can be a binding to:
        * an instance of obj - obj will be treated strictly as a class.
        * obj itself - obj will be treated as an instance of its metaclass.
        * None - if name == "__getitem__", obj is a type annotation; else, obj
            is strictly a class, but the attribute is left unbound.
        Else, valself is optional and should be a binding to obj when given.

    Returns:
      A tuple (CFGNode, cfg.Variable). If this attribute doesn't exist,
      the Variable will be None.
    """
    # Some objects have special attributes, like "__get__" or "__iter__"
    special_attribute = obj.get_special_attribute(node, name, valself)
    if special_attribute is not None:
        return node, special_attribute
    if isinstance(obj, abstract.Function):
        if name == "__get__":
            # The pytd for "function" has a __get__ attribute, but if we already
            # have a function we don't want to be treated as a descriptor.
            return node, None
        else:
            return self._get_instance_attribute(node, obj, name, valself)
    elif isinstance(obj, abstract.ParameterizedClass):
        return self.get_attribute(node, obj.base_cls, name, valself)
    elif isinstance(obj, mixin.Class):
        return self._get_class_attribute(node, obj, name, valself)
    elif isinstance(obj, overlay.Overlay):
        return self._get_module_attribute(node, obj.get_module(name), name, valself)
    elif isinstance(obj, abstract.Module):
        return self._get_module_attribute(node, obj, name, valself)
    elif isinstance(obj, abstract.SimpleAbstractValue):
        return self._get_instance_attribute(node, obj, name, valself)
    elif isinstance(obj, abstract.Union):
        nodes = []
        ret = self.vm.program.NewVariable()
        for o in obj.options:
            node2, attr = self.get_attribute(node, o, name, valself)
            if attr is not None:
                ret.PasteVariable(attr, node2)
                nodes.append(node2)
        if ret.bindings:
            return self.vm.join_cfg_nodes(nodes), ret
        else:
            return node, None
    elif isinstance(obj, special_builtins.SuperInstance):
        if obj.super_obj:
            cls = obj.super_cls
            valself = obj.super_obj.to_binding(node)
            skip = obj.super_cls
        else:
            cls = self.vm.convert.super_type
            skip = None
        return self._lookup_from_mro_and_handle_descriptors(
            node, cls, name, valself, skip
        )
    elif isinstance(obj, special_builtins.Super):
        return self.get_attribute(node, self.vm.convert.super_type, name, valself)
    elif isinstance(obj, abstract.BoundFunction):
        return self.get_attribute(node, obj.underlying, name, valself)
    elif isinstance(obj, abstract.TypeParameterInstance):
        param_var = obj.instance.get_instance_type_parameter(obj.name)
        if not param_var.bindings:
            param_var = obj.param.instantiate(self.vm.root_cfg_node)
        results = []
        nodes = []
        for v in param_var.data:
            node2, ret = self.get_attribute(node, v, name, valself)
            if ret is None:
                return node, None
            else:
                results.append(ret)
                nodes.append(node2)
        node = self.vm.join_cfg_nodes(nodes)
        return node, self.vm.join_variables(node, results)
    elif isinstance(obj, abstract.Empty):
        return node, None
    else:
        return node, None