diff options
author | andrei kulakov <andrei.avk@gmail.com> | 2021-12-18 14:23:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-18 14:23:34 (GMT) |
commit | ae36cd1e792db9d6db4c6847ec2a7d50a71f2b68 (patch) | |
tree | 3e223cb1c046e119dbce83550d7bf5a6ed213a76 /Lib/glob.py | |
parent | 6f2df4295123f8b961d49474b7668f7564a534a4 (diff) | |
download | cpython-ae36cd1e792db9d6db4c6847ec2a7d50a71f2b68.zip cpython-ae36cd1e792db9d6db4c6847ec2a7d50a71f2b68.tar.gz cpython-ae36cd1e792db9d6db4c6847ec2a7d50a71f2b68.tar.bz2 |
bpo-37578: glob.glob -- added include_hidden parameter (GH-30153)
Automerge-Triggered-By: GH:asvetlov
Diffstat (limited to 'Lib/glob.py')
-rw-r--r-- | Lib/glob.py | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/Lib/glob.py b/Lib/glob.py index 9fc08f4..a725642 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -10,20 +10,26 @@ import sys __all__ = ["glob", "iglob", "escape"] -def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False): +def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, + include_hidden=False): """Return a list of paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la - fnmatch. However, unlike fnmatch, filenames starting with a + fnmatch. Unlike fnmatch, filenames starting with a dot are special cases that are not matched by '*' and '?' - patterns. + patterns by default. - If recursive is true, the pattern '**' will match any files and + If `include_hidden` is true, the patterns '*', '?', '**' will match hidden + directories. + + If `recursive` is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ - return list(iglob(pathname, root_dir=root_dir, dir_fd=dir_fd, recursive=recursive)) + return list(iglob(pathname, root_dir=root_dir, dir_fd=dir_fd, recursive=recursive, + include_hidden=include_hidden)) -def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False): +def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, + include_hidden=False): """Return an iterator which yields the paths matching a pathname pattern. 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): root_dir = os.fspath(root_dir) else: root_dir = pathname[:0] - it = _iglob(pathname, root_dir, dir_fd, recursive, False) + it = _iglob(pathname, root_dir, dir_fd, recursive, False, + include_hidden=include_hidden) if not pathname or recursive and _isrecursive(pathname[:2]): try: s = next(it) # skip empty string @@ -50,7 +57,8 @@ def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False): pass return it -def _iglob(pathname, root_dir, dir_fd, recursive, dironly): +def _iglob(pathname, root_dir, dir_fd, recursive, dironly, + include_hidden=False): dirname, basename = os.path.split(pathname) if not has_magic(pathname): assert not dironly @@ -64,15 +72,18 @@ def _iglob(pathname, root_dir, dir_fd, recursive, dironly): return if not dirname: if recursive and _isrecursive(basename): - yield from _glob2(root_dir, basename, dir_fd, dironly) + yield from _glob2(root_dir, basename, dir_fd, dironly, + include_hidden=include_hidden) else: - yield from _glob1(root_dir, basename, dir_fd, dironly) + yield from _glob1(root_dir, basename, dir_fd, dironly, + include_hidden=include_hidden) return # `os.path.split()` returns the argument itself as a dirname if it is a # drive or UNC path. Prevent an infinite recursion if a drive or UNC path # contains magic characters (i.e. r'\\?\C:'). if dirname != pathname and has_magic(dirname): - dirs = _iglob(dirname, root_dir, dir_fd, recursive, True) + dirs = _iglob(dirname, root_dir, dir_fd, recursive, True, + include_hidden=include_hidden) else: dirs = [dirname] if has_magic(basename): @@ -83,20 +94,21 @@ def _iglob(pathname, root_dir, dir_fd, recursive, dironly): else: glob_in_dir = _glob0 for dirname in dirs: - for name in glob_in_dir(_join(root_dir, dirname), basename, dir_fd, dironly): + for name in glob_in_dir(_join(root_dir, dirname), basename, dir_fd, dironly, + include_hidden=include_hidden): yield os.path.join(dirname, name) # These 2 helper functions non-recursively glob inside a literal directory. # They return a list of basenames. _glob1 accepts a pattern while _glob0 # takes a literal basename (so it only has to check for its existence). -def _glob1(dirname, pattern, dir_fd, dironly): +def _glob1(dirname, pattern, dir_fd, dironly, include_hidden=False): names = _listdir(dirname, dir_fd, dironly) - if not _ishidden(pattern): - names = (x for x in names if not _ishidden(x)) + if include_hidden or not _ishidden(pattern): + names = (x for x in names if include_hidden or not _ishidden(x)) return fnmatch.filter(names, pattern) -def _glob0(dirname, basename, dir_fd, dironly): +def _glob0(dirname, basename, dir_fd, dironly, include_hidden=False): if basename: if _lexists(_join(dirname, basename), dir_fd): return [basename] @@ -118,10 +130,11 @@ def glob1(dirname, pattern): # This helper function recursively yields relative pathnames inside a literal # directory. -def _glob2(dirname, pattern, dir_fd, dironly): +def _glob2(dirname, pattern, dir_fd, dironly, include_hidden=False): assert _isrecursive(pattern) yield pattern[:0] - yield from _rlistdir(dirname, dir_fd, dironly) + yield from _rlistdir(dirname, dir_fd, dironly, + include_hidden=include_hidden) # If dironly is false, yields all file names inside a directory. # If dironly is true, yields only directory names. @@ -164,13 +177,14 @@ def _listdir(dirname, dir_fd, dironly): return list(it) # Recursively yields relative pathnames inside a literal directory. -def _rlistdir(dirname, dir_fd, dironly): +def _rlistdir(dirname, dir_fd, dironly, include_hidden=False): names = _listdir(dirname, dir_fd, dironly) for x in names: - if not _ishidden(x): + if include_hidden or not _ishidden(x): yield x path = _join(dirname, x) if dirname else x - for y in _rlistdir(path, dir_fd, dironly): + for y in _rlistdir(path, dir_fd, dironly, + include_hidden=include_hidden): yield _join(x, y) |