import inspect


def get_lineno_from_deeper_in_stack(n_frames_offset, original_lineno, func_name=None):
    """
    Given a line number, find the frame in the stack that it refers to,
    and return the line number from a frame deeper in the stack.
    If `func_name` is passed, change the line number only if the original frame references the named function.
    Useful for replacing the line number of a custom logging function
    with the line number of the *call* to that function.
    In other words, dereferencing a logging call.

    Parameters
    ----------
    n_frames_offset : int
    original_lineno : int
    func_name : str, optional

    Returns
    -------
    int

    """
    frames = inspect.stack()
    original_frame_ix = next(ix for ix, frame in enumerate(frames) if frame[2] == original_lineno)
    if func_name is None or frames[original_frame_ix][3] == func_name:
        return frames[original_frame_ix + n_frames_offset][2]
    return original_lineno