diff --git a/Lib/glob.py b/Lib/glob.py --- a/Lib/glob.py +++ b/Lib/glob.py @@ -53,13 +53,23 @@ else: yield from glob1(dirname, basename) 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, recursive) + + if has_magic(dirname): + # `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: + # Here, dirname may not be an existing directory, this will be checked + # for by glob0(). + dirs = [dirname] + else: + dirs = (d for d in _iglob(dirname, recursive) if + not d or os.path.isdir(d)) + elif os.path.isdir(dirname): + dirs = [dirname] else: - dirs = [dirname] + return + if has_magic(basename): if recursive and _isrecursive(basename): glob_in_dir = glob2 @@ -76,13 +86,8 @@ # takes a literal basename (so it only has to check for its existence). def glob1(dirname, pattern): - if not dirname: - if isinstance(pattern, bytes): - dirname = bytes(os.curdir, 'ASCII') - else: - dirname = os.curdir try: - names = os.listdir(dirname) + names = _listdir(dirname) except OSError: return [] if not _ishidden(pattern): @@ -110,21 +115,17 @@ # Recursively yields relative pathnames inside a literal directory. def _rlistdir(dirname): - if not dirname: - if isinstance(dirname, bytes): - dirname = bytes(os.curdir, 'ASCII') - else: - dirname = os.curdir try: - names = os.listdir(dirname) + names = _listdir(dirname) except os.error: return for x in names: if not _ishidden(x): yield x path = os.path.join(dirname, x) if dirname else x - for y in _rlistdir(path): - yield os.path.join(x, y) + if os.path.isdir(path): + for y in _rlistdir(path): + yield os.path.join(x, y) magic_check = re.compile('([*?[])') @@ -146,6 +147,16 @@ else: return pattern == '**' +def _listdir(dirname): + if not dirname: + if isinstance(dirname, bytes): + dirname = bytes(os.curdir, 'ASCII') + else: + dirname = os.curdir + else: + assert os.path.isdir(dirname) + return os.listdir(dirname) + def escape(pathname): """Escape all special characters. """