def _walk_repository(repodir, ignore_file=None, parse_ignore=None,
                    match_ignore=None, path=None, depth=0):
    """Do the actual repository walking, using repository specific parse and
    match functions.

    The `ignore_file` argument specifies the name of the repository specific
    ignore file (e.g. '.gitignore' for git).

    The `parse_ignore` argument is a function that can parse the ignore file.
    Prototype: `parse_ignore(input)` with `input` a file like object or a
    string.

    The `match_ignore` argument is a function that is used to match individual
    files and directories against a hierarchy of ignore files. Prototype:
    `match_ignore(path)` where path is a list of `(name, parsed_ignore_file,
    ignore_or_mode)`. The path contains one element per path component.
    The `name` field the name of the path component.  The `parsed_ignore_file`
    field is the parsed ignore file file for that level, if any.  The `ignore`
    field is a boolean that indicates the result of a previous `match_ignore()`
    invocation for the level. This field is set for all but the final level. In
    the final level, this field is multiplexed and instead indicates whether
    the final path component is a file or directory.
    """

    if path is None:
        path = []
    parsed_ignore_file = None

    if ignore_file is not None:
        fullname = os.path.join(repodir, ignore_file)
        try:
            st = os.stat(fullname)
        except __HOLE__:
            pass
        else:
            if stat.S_ISREG(st.st_mode):
                with open(fullname) as fin:
                    parsed_ignore_file = parse_ignore(fin)

    path.append(None)
    contents = os.listdir(repodir)

    # For each file and directory in the tree, keep track of a path
    # containing (name, parsed_ignore, ignore) tuples for every path
    # element up till the top of the tree.

    for fname in contents:
        fullname = os.path.join(repodir, fname)
        try:
            st = os.stat(fullname)
        except OSError:
            continue

        if stat.S_ISREG(st.st_mode):
            path[depth] = (fname, parsed_ignore_file, st.st_mode)
            if not match_ignore or not match_ignore(path):
                yield os.path.join(*(p[0] for p in path))

        elif stat.S_ISDIR(st.st_mode):
            path[depth] = (fname, parsed_ignore_file, st.st_mode)
            ignore = match_ignore(path) if match_ignore else INCLUDE
            path[depth] = (fname, parsed_ignore_file, ignore)
            if ignore != TRUNCATE:
                path_yielded = False
                for elem in _walk_repository(fullname, ignore_file, parse_ignore,
                                             match_ignore, path, depth+1):
                    if not path_yielded:
                        yield os.path.join(*(p[0] for p in path[:depth+1]))
                        path_yielded = True
                    yield elem

        # Ignore anything that is not a file or directory.
    del path[-1]
dataset/ETHPy150Open ravello/testmill/lib/testmill/versioncontrol.py/_walk_repository