| Guido van Rossum | ab096c9 | 1997-04-02 05:47:11 +0000 | [diff] [blame] | 1 | """Filename globbing utility.""" | 
| Guido van Rossum | 65a9620 | 1991-01-01 18:17:49 +0000 | [diff] [blame] | 2 |  | 
| Guido van Rossum | bba77af | 1992-01-12 23:26:24 +0000 | [diff] [blame] | 3 | import os | 
| Guido van Rossum | 65a9620 | 1991-01-01 18:17:49 +0000 | [diff] [blame] | 4 | import fnmatch | 
| Guido van Rossum | 9694fca | 1997-10-22 21:00:49 +0000 | [diff] [blame] | 5 | import re | 
| Guido van Rossum | 65a9620 | 1991-01-01 18:17:49 +0000 | [diff] [blame] | 6 |  | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 7 | __all__ = ["glob", "iglob"] | 
| Guido van Rossum | bba77af | 1992-01-12 23:26:24 +0000 | [diff] [blame] | 8 |  | 
| Guido van Rossum | 65a9620 | 1991-01-01 18:17:49 +0000 | [diff] [blame] | 9 | def glob(pathname): | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 10 |     """Return a list of paths matching a pathname pattern. | 
| Guido van Rossum | ab096c9 | 1997-04-02 05:47:11 +0000 | [diff] [blame] | 11 |  | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 12 |     The pattern may contain simple shell-style wildcards a la fnmatch. | 
| Guido van Rossum | ab096c9 | 1997-04-02 05:47:11 +0000 | [diff] [blame] | 13 |  | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 14 |     """ | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 15 |     return list(iglob(pathname)) | 
 | 16 |  | 
 | 17 | def iglob(pathname): | 
 | 18 |     """Return a list of paths matching a pathname pattern. | 
 | 19 |  | 
 | 20 |     The pattern may contain simple shell-style wildcards a la fnmatch. | 
 | 21 |  | 
 | 22 |     """ | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 23 |     if not has_magic(pathname): | 
| Johannes Gijsbers | ae882f7 | 2004-08-30 10:19:56 +0000 | [diff] [blame] | 24 |         if os.path.lexists(pathname): | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 25 |             yield pathname | 
 | 26 |         return | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 27 |     dirname, basename = os.path.split(pathname) | 
| Martin v. Löwis | b5d4d2a | 2001-06-06 06:24:38 +0000 | [diff] [blame] | 28 |     if not dirname: | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 29 |         for name in glob1(os.curdir, basename): | 
 | 30 |             yield name | 
 | 31 |         return | 
 | 32 |     if has_magic(dirname): | 
 | 33 |         dirs = iglob(dirname) | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 34 |     else: | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 35 |         dirs = [dirname] | 
 | 36 |     if has_magic(basename): | 
 | 37 |         glob_in_dir = glob1 | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 38 |     else: | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 39 |         glob_in_dir = glob0 | 
 | 40 |     for dirname in dirs: | 
 | 41 |         for name in glob_in_dir(dirname, basename): | 
 | 42 |             yield os.path.join(dirname, name) | 
 | 43 |  | 
 | 44 | # These 2 helper functions non-recursively glob inside a literal directory. | 
 | 45 | # They return a list of basenames. `glob1` accepts a pattern while `glob0` | 
 | 46 | # takes a literal basename (so it only has to check for its existence). | 
| Guido van Rossum | 65a9620 | 1991-01-01 18:17:49 +0000 | [diff] [blame] | 47 |  | 
 | 48 | def glob1(dirname, pattern): | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 49 |     if not dirname: | 
 | 50 |         dirname = os.curdir | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 51 |     try: | 
 | 52 |         names = os.listdir(dirname) | 
 | 53 |     except os.error: | 
 | 54 |         return [] | 
| Martin v. Löwis | b5d4d2a | 2001-06-06 06:24:38 +0000 | [diff] [blame] | 55 |     if pattern[0]!='.': | 
 | 56 |         names=filter(lambda x: x[0]!='.',names) | 
 | 57 |     return fnmatch.filter(names,pattern) | 
| Guido van Rossum | 65a9620 | 1991-01-01 18:17:49 +0000 | [diff] [blame] | 58 |  | 
| Johannes Gijsbers | 836f543 | 2005-01-08 13:13:19 +0000 | [diff] [blame] | 59 | def glob0(dirname, basename): | 
 | 60 |     if basename == '': | 
 | 61 |         # `os.path.split()` returns an empty basename for paths ending with a | 
 | 62 |         # directory separator.  'q*x/' should match only directories. | 
 | 63 |         if os.isdir(dirname): | 
 | 64 |             return [basename] | 
 | 65 |     else: | 
 | 66 |         if os.path.lexists(os.path.join(dirname, basename)): | 
 | 67 |             return [basename] | 
 | 68 |     return [] | 
 | 69 |  | 
| Guido van Rossum | c2ef5c2 | 1992-01-12 23:32:11 +0000 | [diff] [blame] | 70 |  | 
| Guido van Rossum | 9694fca | 1997-10-22 21:00:49 +0000 | [diff] [blame] | 71 | magic_check = re.compile('[*?[]') | 
| Guido van Rossum | c2ef5c2 | 1992-01-12 23:32:11 +0000 | [diff] [blame] | 72 |  | 
| Guido van Rossum | 65a9620 | 1991-01-01 18:17:49 +0000 | [diff] [blame] | 73 | def has_magic(s): | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 74 |     return magic_check.search(s) is not None |