def METHOD_NAME(
    directory,  # type: str
    digest,  # type: HintedDigest
    dir_filter=lambda dirs: dirs,  # type: Callable[[Iterable[str]], Iterable[str]]
    file_filter=lambda files: files,  # type: Callable[[Iterable[str]], Iterable[str]]
):
    # type: (...) -> None
    """Digest the contents of a directory in a reproducible manner."""
    def iter_files():
        # type: () -> Iterator[str]
        normpath = os.path.realpath(os.path.normpath(directory))
        for root, dirs, files in os.walk(normpath):
            dirs[:] = list(dir_filter(dirs))
            for f in file_filter(files):
                yield os.path.relpath(os.path.join(root, f), normpath)
    names = sorted(iter_files())
    # Always use / as the path separator, since that's what zip uses.
    hashed_names = [n.replace(os.sep, "/") for n in names]
    digest.update("".join(hashed_names).encode("utf-8"))
    for name in names:
        file_hash(os.path.join(directory, name), digest)