def get_suppressions(relative_filepaths, root, messages):
    """
    Given every message which was emitted by the tools, and the
    list of files to inspect, create a list of files to ignore,
    and a map of filepath -> line-number -> codes to ignore
    """
    paths_to_ignore = set()
    lines_to_ignore = defaultdict(set)
    messages_to_ignore = defaultdict(lambda: defaultdict(set))

    # first deal with 'noqa' style messages
    for filepath in relative_filepaths:
        abspath = os.path.join(root, filepath)

        try:
            file_contents = encoding.read_py_file(abspath).split('\n')
        except encoding.CouldNotHandleEncoding as err:
            # TODO: this output will break output formats such as JSON
            warnings.warn('{0}: {1}'.format(err.path, err.cause), ImportWarning)
            continue

        ignore_file, ignore_lines = get_noqa_suppressions(file_contents)
        if ignore_file:
            paths_to_ignore.add(filepath)
        lines_to_ignore[filepath] |= ignore_lines

    # now figure out which messages were suppressed by pylint
    pylint_ignore_files, pylint_ignore_messages = _parse_pylint_informational(messages)
    paths_to_ignore |= pylint_ignore_files
    for filepath, line in pylint_ignore_messages.items():
        for line_number, codes in line.items():
            for code in codes:
                messages_to_ignore[filepath][line_number].add(('pylint', code))
                if code in _PYLINT_EQUIVALENTS:
                    for equivalent in _PYLINT_EQUIVALENTS[code]:
                        messages_to_ignore[filepath][line_number].add(equivalent)

    return paths_to_ignore, lines_to_ignore, messages_to_ignore
Given every message which was emitted by the tools, and the
    list of files to inspect, create a list of files to ignore,
    and a map of filepath -> line-number -> codes to ignore