def get_frame_location(frame):
    """
    Extract information useful for profiling from the frame.

    In one Python module there may be multiple functions with the same name.
    That's why we attach function line to function name.

    :param frame frame:
    :rtype: tuple
    :return: a 3-tuple of:
        - module name, e.g. 'prompt_toolkit.layout.containers'
        - function name or Class.method name, e.g. '1184:Window._copy_body'
        - current line number, int
    """
    function_name = frame.f_code.co_name
    try:
        # `self` isn't a keyword. The name of the first argument of a method is arbitrary.
        # But that's the least wrong way to get a class form a frame.
        class_name = frame.f_locals['self'].__class__.__name__
    except (KeyError, AttributeError):
        function_id = function_name
    else:
        function_id = '{}.{}'.format(class_name, function_name)

    return (frame.f_globals['__name__'], function_id, frame.f_lineno)