Home | History | Annotate | Download | only in Lib
      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