diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/glob.py | 62 | ||||
-rw-r--r-- | Lib/test/test_glob.py | 4 |
2 files changed, 43 insertions, 23 deletions
diff --git a/Lib/glob.py b/Lib/glob.py index 4ba4138..ecc6d25 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -4,7 +4,7 @@ import os import fnmatch import re -__all__ = ["glob"] +__all__ = ["glob", "iglob"] def glob(pathname): """Return a list of paths matching a pathname pattern. @@ -12,35 +12,42 @@ def glob(pathname): The pattern may contain simple shell-style wildcards a la fnmatch. """ + return list(iglob(pathname)) + +def iglob(pathname): + """Return a list of paths matching a pathname pattern. + + The pattern may contain simple shell-style wildcards a la fnmatch. + + """ if not has_magic(pathname): if os.path.lexists(pathname): - return [pathname] - else: - return [] + yield pathname + return dirname, basename = os.path.split(pathname) if not dirname: - return glob1(os.curdir, basename) - elif has_magic(dirname): - list = glob(dirname) + for name in glob1(os.curdir, basename): + yield name + return + if has_magic(dirname): + dirs = iglob(dirname) else: - list = [dirname] - if not has_magic(basename): - result = [] - for dirname in list: - if basename or os.path.isdir(dirname): - name = os.path.join(dirname, basename) - if os.path.lexists(name): - result.append(name) + dirs = [dirname] + if has_magic(basename): + glob_in_dir = glob1 else: - result = [] - for dirname in list: - sublist = glob1(dirname, basename) - for name in sublist: - result.append(os.path.join(dirname, name)) - return result + glob_in_dir = glob0 + for dirname in dirs: + for name in glob_in_dir(dirname, basename): + 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): - if not dirname: dirname = os.curdir + if not dirname: + dirname = os.curdir try: names = os.listdir(dirname) except os.error: @@ -49,6 +56,17 @@ def glob1(dirname, pattern): names=filter(lambda x: x[0]!='.',names) return fnmatch.filter(names,pattern) +def glob0(dirname, basename): + if basename == '': + # `os.path.split()` returns an empty basename for paths ending with a + # directory separator. 'q*x/' should match only directories. + if os.isdir(dirname): + return [basename] + else: + if os.path.lexists(os.path.join(dirname, basename)): + return [basename] + return [] + magic_check = re.compile('[*?[]') diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py index af81dab..f23dcf1 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -61,7 +61,9 @@ class GlobTests(unittest.TestCase): else: pattern = os.path.join(*parts) p = os.path.join(self.tempdir, pattern) - return glob.glob(p) + res = glob.glob(p) + self.assertEqual(list(glob.iglob(p)), res) + return res def assertSequencesEqual_noorder(self, l1, l2): self.assertEqual(set(l1), set(l2)) |