def find( root, exclude_names=None, exclude_dir_names=None, exclude_file_names=None, exclude_wildcards=None, exclude_dir_wildcards=None, exclude_file_wildcards=None, exclude_extensions=None, handle_dirs=False, ): """ Iterates over file system (starting from given root). Yields Path objects (relative to the given root). If handle_dirs=True, also yields dir Paths. By default only files. If handle_dirs is callable(Path), it is called for each dir instead. Arguments exclude_* controls search: - exclude_dir_<kind> - excludes matching directories from stepping into; - exclude_file_<kind> - excludes matching files; - exclude_<kind> - excludes both dirs and files. Kinds of exclude matches: - exclude_wildcards - matches full (absolute) file path using fnmatch, generic wildcards work too: '*.txt' etc; - exclude_extensions - matches extensions (files only), leading dot is optional; - exclude_names - matches exact base name. """ exclude_dir_names = list( map(str, (exclude_dir_names or []) + (exclude_names or []))) exclude_file_names = list( map(str, (exclude_file_names or []) + (exclude_names or []))) exclude_dir_wildcards = list( map(str, (exclude_dir_wildcards or []) + (exclude_wildcards or []))) exclude_file_wildcards = list( map(str, (exclude_file_wildcards or []) + (exclude_wildcards or []))) exclude_extensions = list( map(lambda _: (_ if _.startswith('.') else '.' + _), map(str, (exclude_extensions or [])))) for root, dirs, files in os.walk(str(root)): root = Path(root) if callable(handle_dirs): handle_dirs(root) elif handle_dirs: yield root if exclude_dir_names: dirs[:] = [ dirname for dirname in dirs if dirname not in exclude_dir_names ] if exclude_dir_wildcards: dirs[:] = [ dirname for dirname in dirs if not any((root / dirname).absolute().match(str(pattern)) for pattern in exclude_dir_wildcards) ] for filename in files: filename = root / filename abs_filename = Path(os.path.abspath( str(filename))) # Path.absolute() does not work with pyfakefs. if exclude_file_wildcards and any( abs_filename.match(str(pattern)) for pattern in exclude_file_wildcards): continue if exclude_file_names and filename.name in exclude_file_names: continue if exclude_extensions and filename.suffix in exclude_extensions: continue yield filename