def iter_filtered_dir_entry(dir_entries, match_patterns, on_skip):
    """
    Filter a list of DirEntryPath instances with the given pattern

    :param dir_entries: list of DirEntryPath instances
    :param match_patterns: used with Path.match()
        e.g.: "__pycache__/*", "*.tmp", "*.cache"
    :param on_skip: function that will be called if 'match_patterns' hits.
        e.g.:
        def on_skip(entry, pattern):
            log.error("Skip pattern %r hit: %s" % (pattern, entry.path))
    :return: yields None or DirEntryPath instances
    """

    def match(dir_entry_path, match_patterns, on_skip):
        for match_pattern in match_patterns:
            if dir_entry_path.path_instance.match(match_pattern):
                on_skip(dir_entry_path, match_pattern)
                return True
        return False

    for entry in dir_entries:
        try:
            dir_entry_path = DirEntryPath(entry)
        except FileNotFoundError as err:
            # e.g.: A file was deleted after the first filesystem scan
            # Will be obsolete if we use shadow-copy / snapshot function from filesystem
            # see: https://github.com/jedie/PyHardLinkBackup/issues/6
            log.error("Can't make DirEntryPath() instance: %s" % err)
            continue
        if match(dir_entry_path, match_patterns, on_skip):
            yield None
        else:
            yield dir_entry_path
Filter a list of DirEntryPath instances with the given pattern

    :param dir_entries: list of DirEntryPath instances
    :param match_patterns: used with Path.match()
        e.g.: "__pycache__/*", "*.tmp", "*.cache"
    :param on_skip: function that will be called if 'match_patterns' hits.
        e.g.:
        def on_skip(entry, pattern):
            log.error("Skip pattern %r hit: %s" % (pattern, entry.path))
    :return: yields None or DirEntryPath instances