Strongly inspired by https://github.com/python/cpython/blob/3.8/Lib/glob.py
iglob(sftp, pathname, recursive, dironly)
SFTP implementation of glob.iglob, but lighter
The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike fnmatch, filenames starting with a dot are special cases that are not matched by '' and '?' patterns. If recursive is true, the pattern '*' will match any files and zero or more directories and subdirectories.
Source code in sftputil/glob.py
def iglob(sftp, pathname, recursive, dironly):
"""SFTP implementation of glob.iglob, but lighter
The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike
fnmatch, filenames starting with a dot are special cases that are not matched by
'*' and '?' patterns. If recursive is true, the pattern '**' will match any files
and zero or more directories and subdirectories.
"""
dirname, basename = os.path.split(pathname)
if not _has_magic(str(pathname)):
assert not dironly
# No special characters, simply yield the pathname if it exists
if basename:
if sftp.exists(pathname):
yield pathname
else:
# Patterns ending with a slash should match only directories
if sftp.is_dir(dirname):
yield pathname
return
# TODO: WHAT IS THIS COMMENTED CODE?
# if not dirname:
# # The path does not contain parent directory
# # Search for a recursive pattern ** or directly a file pattern
# if recursive and _is_recursive(basename):
# yield from _glob_r_p(sftp, dirname, basename, dironly)
# else:
# yield from _glob_nr_p(sftp, dirname, basename, dironly)
# return
# Before searching for the basename, search for every dirname matching the pattern.
if dirname != pathname and _has_magic(dirname):
dirs = iglob(sftp, dirname, recursive, True)
else:
dirs = [dirname]
# Then, search for the basename using the appropriate glob function.
if _has_magic(basename):
if recursive and _is_recursive(basename):
glob_in_dir = _glob_r_p
else:
glob_in_dir = _glob_nr_p
else:
glob_in_dir = _glob_nr_l
for dirname in dirs:
for name in glob_in_dir(sftp, dirname, basename, dironly):
yield os.path.join(dirname, name)