Home | History | Annotate | Download | only in support
      1 """
      2 File sets and globbing helper for make_layout.
      3 """
      4 
      5 __author__ = "Steve Dower <steve.dower (at] python.org>"
      6 __version__ = "3.8"
      7 
      8 import os
      9 
     10 
     11 class FileStemSet:
     12     def __init__(self, *patterns):
     13         self._names = set()
     14         self._prefixes = []
     15         self._suffixes = []
     16         for p in map(os.path.normcase, patterns):
     17             if p.endswith("*"):
     18                 self._prefixes.append(p[:-1])
     19             elif p.startswith("*"):
     20                 self._suffixes.append(p[1:])
     21             else:
     22                 self._names.add(p)
     23 
     24     def _make_name(self, f):
     25         return os.path.normcase(f.stem)
     26 
     27     def __contains__(self, f):
     28         bn = self._make_name(f)
     29         return (
     30             bn in self._names
     31             or any(map(bn.startswith, self._prefixes))
     32             or any(map(bn.endswith, self._suffixes))
     33         )
     34 
     35 
     36 class FileNameSet(FileStemSet):
     37     def _make_name(self, f):
     38         return os.path.normcase(f.name)
     39 
     40 
     41 class FileSuffixSet:
     42     def __init__(self, *patterns):
     43         self._names = set()
     44         self._prefixes = []
     45         self._suffixes = []
     46         for p in map(os.path.normcase, patterns):
     47             if p.startswith("*."):
     48                 self._names.add(p[1:])
     49             elif p.startswith("*"):
     50                 self._suffixes.append(p[1:])
     51             elif p.endswith("*"):
     52                 self._prefixes.append(p[:-1])
     53             elif p.startswith("."):
     54                 self._names.add(p)
     55             else:
     56                 self._names.add("." + p)
     57 
     58     def _make_name(self, f):
     59         return os.path.normcase(f.suffix)
     60 
     61     def __contains__(self, f):
     62         bn = self._make_name(f)
     63         return (
     64             bn in self._names
     65             or any(map(bn.startswith, self._prefixes))
     66             or any(map(bn.endswith, self._suffixes))
     67         )
     68 
     69 
     70 def _rglob(root, pattern, condition):
     71     dirs = [root]
     72     recurse = pattern[:3] in {"**/", "**\\"}
     73     if recurse:
     74         pattern = pattern[3:]
     75 
     76     while dirs:
     77         d = dirs.pop(0)
     78         if recurse:
     79             dirs.extend(
     80                 filter(
     81                     condition, (type(root)(f2) for f2 in os.scandir(d) if f2.is_dir())
     82                 )
     83             )
     84         yield from (
     85             (f.relative_to(root), f)
     86             for f in d.glob(pattern)
     87             if f.is_file() and condition(f)
     88         )
     89 
     90 
     91 def _return_true(f):
     92     return True
     93 
     94 
     95 def rglob(root, patterns, condition=None):
     96     if isinstance(patterns, tuple):
     97         for p in patterns:
     98             yield from _rglob(root, p, condition or _return_true)
     99     else:
    100         yield from _rglob(root, patterns, condition or _return_true)
    101