def _apply_filters(nodes_and_ctxs, ctx_filter, category_filter):
    if ctx_filter or category_filter:
        unfiltered = list(nodes_and_ctxs)
        nodes_and_ctxs = []
        seen = set()
        while unfiltered:
            node, ctx = unfiltered.pop()
            if (node, ctx) in seen:
                continue
            seen.add((node, ctx))

            shift_set = ctx.get_shift_set()
            categories = node.categories
            include = True

            # check if context is included
            if ctx_filter is not None:
                if not shift_set:
                    if None not in ctx_filter:
                        include = False
                else:
                    # check if shift set is included
                    for key, value in shift_set.iteritems():
                        if key in ctx_filter and value in ctx_filter[key]:
                            break
                    else:
                        include = False

            # check at least one of the node categories is in the filter
            if include and category_filter is not None:
                if not categories and None not in category_filter:
                    include = False
                else:
                    for category in categories:
                        if category in category_filter:
                            break
                        else:
                            include = False

            # if both filters passed add it to the list and continue to the next one
            if include:
                nodes_and_ctxs.append((node, ctx))
                continue

            # add this nodes dependencies to see if any of those match the filter
            unfiltered.extend(node.get_dependencies(ctx))

    return nodes_and_ctxs
Check we can export a file without errors.
dataset/ETHPy150Open manahl/mdf/mdf/viewer/frame.py/_apply_filters--crossover with--dataset/ETHPy150Open google/grr/grr/lib/export_utils_test.py/TestExports.testRecursiveDownload