| """ |
| File sets and globbing helper for make_layout. |
| """ |
| |
| __author__ = "Steve Dower <steve.dower@python.org>" |
| __version__ = "3.8" |
| |
| import os |
| |
| |
| class FileStemSet: |
| def __init__(self, *patterns): |
| self._names = set() |
| self._prefixes = [] |
| self._suffixes = [] |
| for p in map(os.path.normcase, patterns): |
| if p.endswith("*"): |
| self._prefixes.append(p[:-1]) |
| elif p.startswith("*"): |
| self._suffixes.append(p[1:]) |
| else: |
| self._names.add(p) |
| |
| def _make_name(self, f): |
| return os.path.normcase(f.stem) |
| |
| def __contains__(self, f): |
| bn = self._make_name(f) |
| return ( |
| bn in self._names |
| or any(map(bn.startswith, self._prefixes)) |
| or any(map(bn.endswith, self._suffixes)) |
| ) |
| |
| |
| class FileNameSet(FileStemSet): |
| def _make_name(self, f): |
| return os.path.normcase(f.name) |
| |
| |
| class FileSuffixSet: |
| def __init__(self, *patterns): |
| self._names = set() |
| self._prefixes = [] |
| self._suffixes = [] |
| for p in map(os.path.normcase, patterns): |
| if p.startswith("*."): |
| self._names.add(p[1:]) |
| elif p.startswith("*"): |
| self._suffixes.append(p[1:]) |
| elif p.endswith("*"): |
| self._prefixes.append(p[:-1]) |
| elif p.startswith("."): |
| self._names.add(p) |
| else: |
| self._names.add("." + p) |
| |
| def _make_name(self, f): |
| return os.path.normcase(f.suffix) |
| |
| def __contains__(self, f): |
| bn = self._make_name(f) |
| return ( |
| bn in self._names |
| or any(map(bn.startswith, self._prefixes)) |
| or any(map(bn.endswith, self._suffixes)) |
| ) |
| |
| |
| def _rglob(root, pattern, condition): |
| dirs = [root] |
| recurse = pattern[:3] in {"**/", "**\\"} |
| if recurse: |
| pattern = pattern[3:] |
| |
| while dirs: |
| d = dirs.pop(0) |
| if recurse: |
| dirs.extend( |
| filter( |
| condition, (type(root)(f2) for f2 in os.scandir(d) if f2.is_dir()) |
| ) |
| ) |
| yield from ( |
| (f.relative_to(root), f) |
| for f in d.glob(pattern) |
| if f.is_file() and condition(f) |
| ) |
| |
| |
| def _return_true(f): |
| return True |
| |
| |
| def rglob(root, patterns, condition=None): |
| if isinstance(patterns, tuple): |
| for p in patterns: |
| yield from _rglob(root, p, condition or _return_true) |
| else: |
| yield from _rglob(root, patterns, condition or _return_true) |