1 """Filename globbing utility.""" 2 3 import sys 4 import os 5 import re 6 import fnmatch 7 8 __all__ = ["glob", "iglob"] 9 10 def glob(pathname): 11 """Return a list of paths matching a pathname pattern. 12 13 The pattern may contain simple shell-style wildcards a la fnmatch. 14 15 """ 16 return list(iglob(pathname)) 17 18 def iglob(pathname): 19 """Return an iterator which yields the paths matching a pathname pattern. 20 21 The pattern may contain simple shell-style wildcards a la fnmatch. 22 23 """ 24 if not has_magic(pathname): 25 if os.path.lexists(pathname): 26 yield pathname 27 return 28 dirname, basename = os.path.split(pathname) 29 if not dirname: 30 for name in glob1(os.curdir, basename): 31 yield name 32 return 33 if has_magic(dirname): 34 dirs = iglob(dirname) 35 else: 36 dirs = [dirname] 37 if has_magic(basename): 38 glob_in_dir = glob1 39 else: 40 glob_in_dir = glob0 41 for dirname in dirs: 42 for name in glob_in_dir(dirname, basename): 43 yield os.path.join(dirname, name) 44 45 # These 2 helper functions non-recursively glob inside a literal directory. 46 # They return a list of basenames. `glob1` accepts a pattern while `glob0` 47 # takes a literal basename (so it only has to check for its existence). 48 49 def glob1(dirname, pattern): 50 if not dirname: 51 dirname = os.curdir 52 if isinstance(pattern, unicode) and not isinstance(dirname, unicode): 53 dirname = unicode(dirname, sys.getfilesystemencoding() or 54 sys.getdefaultencoding()) 55 try: 56 names = os.listdir(dirname) 57 except os.error: 58 return [] 59 if pattern[0] != '.': 60 names = filter(lambda x: x[0] != '.', names) 61 return fnmatch.filter(names, pattern) 62 63 def glob0(dirname, basename): 64 if basename == '': 65 # `os.path.split()` returns an empty basename for paths ending with a 66 # directory separator. 'q*x/' should match only directories. 67 if os.path.isdir(dirname): 68 return [basename] 69 else: 70 if os.path.lexists(os.path.join(dirname, basename)): 71 return [basename] 72 return [] 73 74 75 magic_check = re.compile('[*?[]') 76 77 def has_magic(s): 78 return magic_check.search(s) is not None 79