# Buggy code
def run_program(self, src, filename, maximum_depth):
    """Run the code and return the CFG nodes.

    Args:
      src: The program source code.
      filename: The filename the source is from.
      maximum_depth: Maximum depth to follow call chains.
    Returns:
      A tuple (CFGNode, set) containing the last CFGNode of the program as
        well as all the top-level names defined by it.
    """
    director = directors.Director(src, self.errorlog, filename, self.options.disable)
    # This modifies the errorlog passed to the constructor.  Kind of ugly,
    # but there isn't a better way to wire both pieces together.
    self.errorlog.set_error_filter(director.should_report_error)
    self.director = director
    self.filename = filename

    self.maximum_depth = maximum_depth

    code = self.compile_src(src, filename=filename)
    visitor = _FindIgnoredTypeComments(self.director.type_comments)
    pyc.visit(code, visitor)
    for line in visitor.ignored_lines():
        self.errorlog.ignored_type_comment(
            self.filename, line, self.director.type_comments[line][1]
        )

    node = self.root_cfg_node.ConnectNew("init")
    node, f_globals, f_locals, _ = self.run_bytecode(node, code)
    logging.info("Done running bytecode, postprocessing globals")
    # Check for abstract methods on non-abstract classes.
    for val, frames in self.concrete_classes:
        if not val.is_abstract:
            for member in sum((var.data for var in val.members.values()), []):
                if isinstance(member, abstract.Function) and member.is_abstract:
                    self.errorlog.ignored_abstractmethod(frames, val.name, member.name)
    for param, frames in self.params_with_late_types:
        try:
            param.resolve_late_types(node, f_globals, f_locals)
        except abstract.TypeParameterError as e:
            self.errorlog.invalid_typevar(frames, utils.message(e))
    for func in self.functions_with_late_annotations:
        self.annotations_util.eval_function_late_annotations(
            node, func, f_globals, f_locals
        )
    for cls in self.classes_with_late_annotations:
        self.annotations_util.eval_class_late_annotations(
            node, cls, f_globals, f_locals
        )
    for func, opcode in self.functions_type_params_check:
        func.signature.check_type_parameter_count(self.simple_stack(opcode))
    while f_globals.late_annotations:
        name, annot = f_globals.late_annotations.popitem()
        attr = self.annotations_util.init_annotation(
            node, annot.expr, annot.name, annot.stack, f_globals, f_locals
        )
        self.attribute_handler.set_attribute(node, f_globals, name, attr)
    assert not self.frames, "Frames left over!"
    log.info("Final node: <%d>%s", node.id, node.name)
    return node, f_globals.members


# 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 run_program(self, src, filename, maximum_depth):
    """Run the code and return the CFG nodes.

    Args:
      src: The program source code.
      filename: The filename the source is from.
      maximum_depth: Maximum depth to follow call chains.
    Returns:
      A tuple (CFGNode, set) containing the last CFGNode of the program as
        well as all the top-level names defined by it.
    """
    director = directors.Director(src, self.errorlog, filename, self.options.disable)
    # This modifies the errorlog passed to the constructor.  Kind of ugly,
    # but there isn't a better way to wire both pieces together.
    self.errorlog.set_error_filter(director.should_report_error)
    self.director = director
    self.filename = filename

    self.maximum_depth = maximum_depth

    code = self.compile_src(src, filename=filename)
    visitor = _FindIgnoredTypeComments(self.director.type_comments)
    pyc.visit(code, visitor)
    for line in visitor.ignored_lines():
        self.errorlog.ignored_type_comment(
            self.filename, line, self.director.type_comments[line][1]
        )

    node = self.root_cfg_node.ConnectNew("init")
    node, f_globals, f_locals, _ = self.run_bytecode(node, code)
    logging.info("Done running bytecode, postprocessing globals")
    # Check for abstract methods on non-abstract classes.
    for val, frames in self.concrete_classes:
        if not val.is_abstract:
            for member in sum((var.data for var in val.members.values()), []):
                if isinstance(member, abstract.Function) and member.is_abstract:
                    self.errorlog.ignored_abstractmethod(frames, val.name, member.name)
    for annot in itertools.chain.from_iterable(self.late_annotations.values()):
        # If `annot` has already been resolved, this is a no-op. Otherwise, it
        # contains a real name error that will be logged when we resolve it now.
        annot.resolve(node, f_globals, f_locals)
    self.late_annotations = None  # prevent adding unresolvable annotations
    for func, opcode in self.functions_type_params_check:
        func.signature.check_type_parameter_count(self.simple_stack(opcode))
    assert not self.frames, "Frames left over!"
    log.info("Final node: <%d>%s", node.id, node.name)
    return node, f_globals.members