Mercurial > hgrepos > Python > apps > py-cutils
view cutils/util/walk.py @ 178:dac26a2d9de5
Cleanup: remove non used walk-code
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 11 Jan 2025 21:18:53 +0100 |
| parents | 089c40240061 |
| children | 188de62caac6 |
line wrap: on
line source
# -*- coding: utf-8 -*- # :- # :Copyright: (c) 2020-2025 Franz Glasner # :License: BSD-3-Clause # :- r"""Utility sub-module to implement a heavily customized :func:`os.walk`. """ __all__ = ["ScanDir"] import os try: from os import scandir except ImportError: try: from scandir import scandir except ImportError: scandir = None from . import PY2 class WalkDirEntry(object): """A :class:`os.DirEntry` alike to be used in :func:`walk` and for its results. """ __slots__ = ("_name", "_fsname", "_path", "_fspath", "_is_symlink", "_is_dir", "_stat_result") def __init__(self, name): self._name = name if PY2: assert isinstance(name, bytes) self._fsname = name else: self._fsname = os.fsencode(name) self._path = None self._fspath = None self._is_symlink = self._is_dir = self._stat_result = None @property def name(self): return self._name @property def fsname(self): return self._fsname @property def path(self): return self._path @property def fspath(self): if self._path is not None: if self._fspath is None: if PY2: assert isinstance(self._path, bytes) self._fspath = self._path else: self._fspath = os.fsencode(self._path) return self._fspath @property def is_symlink(self): return self._is_symlink @property def is_dir(self): return self._is_dir @property def stat(self): return self._stat_result def __repr__(self): tag = "" if self._is_symlink: tag += "l" if self._is_dir: tag += "d" if tag: return "<WalkDirEntry %r (%s)>" % (self._name, tag) return "<WalkDirEntry %r>" % (self._name,) @classmethod def from_direntry(cls_, entry): w = cls_(entry.name) w._path = entry.path try: w._is_dir = entry.is_dir(follow_symlinks=True) except OSError: # # If is_dir() raises an OSError, consider that the entry # is not a directory, same behaviour than os.path.isdir(). # w._is_dir = False try: w._is_symlink = entry.is_symlink() except OSError: # # If is_symlink() raises an OSError, consider that the entry # is not a symbolic link, same behaviour than os.path.islink(). # w._is_symlink = False # Do not supress errors here and (consistently) follow symlinks w._stat_result = entry.stat(follow_symlinks=True) return w @classmethod def from_path_name(cls_, path, name): w = cls_(name) w._path = os.path.join(path, name) try: w._is_dir = os.path.isdir(w._path) except OSError: # # If is_dir() raises an OSError, consider that the entry # is not a directory, same behaviour than os.path.isdir(). # w._is_dir = False try: w._is_symlink = os.path.islink(w._path) except OSError: # # If is_symlink() raises an OSError, consider that the entry # is not a symbolic link, same behaviour than os.path.islink(). # w._is_symlink = False w._stat_result = os.stat(w._path) return w @staticmethod def sort_key(entry): return entry._fsname if scandir: class ScanDir(object): """An :func:`os.scandir` wrapper that is always an iterator and a context manager. """ __slots__ = ("_scandir_it", ) def __init__(self, path): super(ScanDir, self).__init__() self._scandir_it = os.scandir(path) def __iter__(self): return self def __next__(self): return WalkDirEntry.from_direntry(next(self._scandir_it)) if PY2: next = __next__ def __enter__(self): return self def __exit__(self, *args, **kwds): if hasattr(self._scandir_it, "close"): self._scandir_it.close() else: class ScanDir(object): """An :func:`os.scandir` wrapper that is always an iterator and a context manager. """ __slots__ = ("_listdir_it", "_path") def __init__(self, path): super(ScanDir, self).__init__() self._listdir_it = iter(os.listdir(path)) self._path = path def __iter__(self): return self def __next__(self): return WalkDirEntry.from_path_name(self._path, next(self._listdir_it)) if PY2: next = __next__ def __enter__(self): return self def __exit__(self, *args, **kwds): pass
