10
10
11
11
__all__ = ["glob" , "iglob" , "escape" ]
12
12
13
- def glob (pathname , * , root_dir = None , dir_fd = None , recursive = False ):
13
+ def glob (pathname , * , root_dir = None , dir_fd = None , recursive = False ,
14
+ include_hidden = False ):
14
15
"""Return a list of paths matching a pathname pattern.
15
16
16
17
The pattern may contain simple shell-style wildcards a la
17
- fnmatch. However, unlike fnmatch, filenames starting with a
18
+ fnmatch. Unlike fnmatch, filenames starting with a
18
19
dot are special cases that are not matched by '*' and '?'
19
- patterns.
20
+ patterns by default .
20
21
21
- If recursive is true, the pattern '**' will match any files and
22
+ If `include_hidden` is true, the patterns '*', '?', '**' will match hidden
23
+ directories.
24
+
25
+ If `recursive` is true, the pattern '**' will match any files and
22
26
zero or more directories and subdirectories.
23
27
"""
24
- return list (iglob (pathname , root_dir = root_dir , dir_fd = dir_fd , recursive = recursive ))
28
+ return list (iglob (pathname , root_dir = root_dir , dir_fd = dir_fd , recursive = recursive ,
29
+ include_hidden = include_hidden ))
25
30
26
- def iglob (pathname , * , root_dir = None , dir_fd = None , recursive = False ):
31
+ def iglob (pathname , * , root_dir = None , dir_fd = None , recursive = False ,
32
+ include_hidden = False ):
27
33
"""Return an iterator which yields the paths matching a pathname pattern.
28
34
29
35
The pattern may contain simple shell-style wildcards a la
@@ -40,7 +46,8 @@ def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False):
40
46
root_dir = os .fspath (root_dir )
41
47
else :
42
48
root_dir = pathname [:0 ]
43
- it = _iglob (pathname , root_dir , dir_fd , recursive , False )
49
+ it = _iglob (pathname , root_dir , dir_fd , recursive , False ,
50
+ include_hidden = include_hidden )
44
51
if not pathname or recursive and _isrecursive (pathname [:2 ]):
45
52
try :
46
53
s = next (it ) # skip empty string
@@ -50,7 +57,8 @@ def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False):
50
57
pass
51
58
return it
52
59
53
- def _iglob (pathname , root_dir , dir_fd , recursive , dironly ):
60
+ def _iglob (pathname , root_dir , dir_fd , recursive , dironly ,
61
+ include_hidden = False ):
54
62
dirname , basename = os .path .split (pathname )
55
63
if not has_magic (pathname ):
56
64
assert not dironly
@@ -64,15 +72,18 @@ def _iglob(pathname, root_dir, dir_fd, recursive, dironly):
64
72
return
65
73
if not dirname :
66
74
if recursive and _isrecursive (basename ):
67
- yield from _glob2 (root_dir , basename , dir_fd , dironly )
75
+ yield from _glob2 (root_dir , basename , dir_fd , dironly ,
76
+ include_hidden = include_hidden )
68
77
else :
69
- yield from _glob1 (root_dir , basename , dir_fd , dironly )
78
+ yield from _glob1 (root_dir , basename , dir_fd , dironly ,
79
+ include_hidden = include_hidden )
70
80
return
71
81
# `os.path.split()` returns the argument itself as a dirname if it is a
72
82
# drive or UNC path. Prevent an infinite recursion if a drive or UNC path
73
83
# contains magic characters (i.e. r'\\?\C:').
74
84
if dirname != pathname and has_magic (dirname ):
75
- dirs = _iglob (dirname , root_dir , dir_fd , recursive , True )
85
+ dirs = _iglob (dirname , root_dir , dir_fd , recursive , True ,
86
+ include_hidden = include_hidden )
76
87
else :
77
88
dirs = [dirname ]
78
89
if has_magic (basename ):
@@ -83,20 +94,21 @@ def _iglob(pathname, root_dir, dir_fd, recursive, dironly):
83
94
else :
84
95
glob_in_dir = _glob0
85
96
for dirname in dirs :
86
- for name in glob_in_dir (_join (root_dir , dirname ), basename , dir_fd , dironly ):
97
+ for name in glob_in_dir (_join (root_dir , dirname ), basename , dir_fd , dironly ,
98
+ include_hidden = include_hidden ):
87
99
yield os .path .join (dirname , name )
88
100
89
101
# These 2 helper functions non-recursively glob inside a literal directory.
90
102
# They return a list of basenames. _glob1 accepts a pattern while _glob0
91
103
# takes a literal basename (so it only has to check for its existence).
92
104
93
- def _glob1 (dirname , pattern , dir_fd , dironly ):
105
+ def _glob1 (dirname , pattern , dir_fd , dironly , include_hidden = False ):
94
106
names = _listdir (dirname , dir_fd , dironly )
95
- if not _ishidden (pattern ):
96
- names = (x for x in names if not _ishidden (x ))
107
+ if include_hidden or not _ishidden (pattern ):
108
+ names = (x for x in names if include_hidden or not _ishidden (x ))
97
109
return fnmatch .filter (names , pattern )
98
110
99
- def _glob0 (dirname , basename , dir_fd , dironly ):
111
+ def _glob0 (dirname , basename , dir_fd , dironly , include_hidden = False ):
100
112
if basename :
101
113
if _lexists (_join (dirname , basename ), dir_fd ):
102
114
return [basename ]
@@ -118,10 +130,11 @@ def glob1(dirname, pattern):
118
130
# This helper function recursively yields relative pathnames inside a literal
119
131
# directory.
120
132
121
- def _glob2 (dirname , pattern , dir_fd , dironly ):
133
+ def _glob2 (dirname , pattern , dir_fd , dironly , include_hidden = False ):
122
134
assert _isrecursive (pattern )
123
135
yield pattern [:0 ]
124
- yield from _rlistdir (dirname , dir_fd , dironly )
136
+ yield from _rlistdir (dirname , dir_fd , dironly ,
137
+ include_hidden = include_hidden )
125
138
126
139
# If dironly is false, yields all file names inside a directory.
127
140
# If dironly is true, yields only directory names.
@@ -164,13 +177,14 @@ def _listdir(dirname, dir_fd, dironly):
164
177
return list (it )
165
178
166
179
# Recursively yields relative pathnames inside a literal directory.
167
- def _rlistdir (dirname , dir_fd , dironly ):
180
+ def _rlistdir (dirname , dir_fd , dironly , include_hidden = False ):
168
181
names = _listdir (dirname , dir_fd , dironly )
169
182
for x in names :
170
- if not _ishidden (x ):
183
+ if include_hidden or not _ishidden (x ):
171
184
yield x
172
185
path = _join (dirname , x ) if dirname else x
173
- for y in _rlistdir (path , dir_fd , dironly ):
186
+ for y in _rlistdir (path , dir_fd , dironly ,
187
+ include_hidden = include_hidden ):
174
188
yield _join (x , y )
175
189
176
190
0 commit comments