Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/PC/layout/support/filesets.py
12 views
1
"""
2
File sets and globbing helper for make_layout.
3
"""
4
5
__author__ = "Steve Dower <[email protected]>"
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 not os.path.isdir(root):
97
return
98
if isinstance(patterns, tuple):
99
for p in patterns:
100
yield from _rglob(root, p, condition or _return_true)
101
else:
102
yield from _rglob(root, patterns, condition or _return_true)
103
104