<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def make_annotations(f, globals_d=None):
 # type: (Callable, Dict) -> Dict[str, Any] """Create an annotations dictionary from Python2 type comments http://mypy.readthedocs.io/en/latest/python2.html Args: f: The function to examine for type comments globals_d: The globals dictionary to get type idents from. If not specified then make the annotations dict contain strings rather than the looked up objects """

    locals_d = {}  # type: Dict[str, Any]
    if globals_d is None:
        # If not given a globals_d then we should just populate annotations with
        # the strings in the type comment.
        globals_d = {}
        # The current approach is to use eval, which means manufacturing a
        # dict like object that will just echo the string back to you. This
        # has a number of complexities for somthing like numpy.number or
        # Callable[..., int], which are handled in EchoStr above, so it might be
        # better off as an ast.parse in the future...
        locals_d = EchoDict()
    lines, _ = inspect.getsourcelines(f)
    arg_spec = getargspec(f)
    args = list(arg_spec.args)
    if arg_spec.varargs is not None:
        args.append(arg_spec.varargs)
    if arg_spec.keywords is not None:
        args.append(arg_spec.keywords)
    it = iter(lines)
    types = []  # type: List
    found = None
    for token in tokenize.generate_tokens(lambda: next(it)):
        typ, string, start, end, line = token
        if typ == tokenize.COMMENT:
            found = type_re.match(string)
            if found:
                parts = found.groups()
                # (...) is used to represent all the args so far
                if parts[0] != "(...)":
                    expr = parts[0].replace("*", "")
                    try:
                        ob = eval(expr, globals_d, locals_d)
                    except Exception as e:
                        raise ValueError(
                            "Error evaluating %r: %s" % (expr, e))
                    if isinstance(ob, tuple):
                        # We got more than one argument
                        types += list(ob)
                    else:
                        # We got a single argument
                        types.append(ob)
                if parts[1]:
                    # Got a return, done
                    try:
                        ob = eval(parts[2], globals_d, locals_d)
                    except Exception as e:
                        raise ValueError(
                            "Error evaluating %r: %s" % (parts[2], e))
                    if args and args[0] in ["self", "cls"]:
                        # Allow the first argument to be inferred
                        if len(args) == len(types) + 1:
                            args = args[1:]
                    assert len(args) == len(types), \
                        "Args %r Types %r length mismatch" % (args, types)
                    ret = dict(zip(args, types))
                    ret["return"] = ob
                    return ret
    if found:
        # If we have ever found a type comment, but not the return value, error
        raise ValueError("Got to the end of the function without seeing ->")
    return {}