You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			56 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Python
		
	
from __future__ import annotations
 | 
						|
 | 
						|
import typing
 | 
						|
from collections import deque
 | 
						|
from collections.abc import Collection, Iterator
 | 
						|
 | 
						|
from ._path import combine
 | 
						|
 | 
						|
if typing.TYPE_CHECKING:
 | 
						|
    from typing import Callable
 | 
						|
 | 
						|
    from ._base import FS
 | 
						|
    from ._info import Info
 | 
						|
 | 
						|
 | 
						|
class BoundWalker:
 | 
						|
    def __init__(self, fs: FS):
 | 
						|
        self._fs = fs
 | 
						|
 | 
						|
    def _iter_walk(
 | 
						|
        self, path: str, namespaces: Collection[str] | None = None
 | 
						|
    ) -> Iterator[tuple[str, Info | None]]:
 | 
						|
        """Walk files using a *breadth first* search."""
 | 
						|
        queue = deque([path])
 | 
						|
        push = queue.appendleft
 | 
						|
        pop = queue.pop
 | 
						|
        _scan = self._fs.scandir
 | 
						|
        _combine = combine
 | 
						|
 | 
						|
        while queue:
 | 
						|
            dir_path = pop()
 | 
						|
            for info in _scan(dir_path, namespaces=namespaces):
 | 
						|
                if info.is_dir:
 | 
						|
                    yield dir_path, info
 | 
						|
                    push(_combine(dir_path, info.name))
 | 
						|
                else:
 | 
						|
                    yield dir_path, info
 | 
						|
        yield path, None
 | 
						|
 | 
						|
    def _filter(
 | 
						|
        self,
 | 
						|
        include: Callable[[str, Info], bool] = lambda path, info: True,
 | 
						|
        path: str = "/",
 | 
						|
        namespaces: Collection[str] | None = None,
 | 
						|
    ) -> Iterator[str]:
 | 
						|
        _combine = combine
 | 
						|
        for path, info in self._iter_walk(path, namespaces):
 | 
						|
            if info is not None and include(path, info):
 | 
						|
                yield _combine(path, info.name)
 | 
						|
 | 
						|
    def files(self, path: str = "/") -> Iterator[str]:
 | 
						|
        yield from self._filter(lambda _, info: info.is_file, path)
 | 
						|
 | 
						|
    def dirs(self, path: str = "/") -> Iterator[str]:
 | 
						|
        yield from self._filter(lambda _, info: info.is_dir, path)
 |