import inspect


def caller_module_name(current_frame):
    """
    :param current_frame: use inspect.currentframe().
    :return: the name of the module calling the function, foo(), in which this calling_module() is invoked.
     Ignores callers that belong in the same module as foo()
    """

    current_frame_filename = current_frame.f_code.co_filename  # filename in which foo() resides

    # go back a frame takes us to the frame calling foo()
    caller_frame = current_frame.f_back
    caller_filename = caller_frame.f_code.co_filename

    # find the first frame that does not have the same filename. this ensures that we don't consider functions within
    # the same module as foo() that use foo() as a helper function
    while caller_filename == current_frame_filename:
        caller_frame = caller_frame.f_back
        caller_filename = caller_frame.f_code.co_filename

    return inspect.getmodulename(caller_filename)