PageRenderTime 30ms CodeModel.GetById 17ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/ruffus/re_glob.py

https://code.google.com/p/ruffus/
Python | 79 lines | 61 code | 8 blank | 10 comment | 24 complexity | 7e45e0addd8da51fdc20fffca36bb40b MD5 | raw file
 1"""Filename globbing utility."""
 2
 3import sys
 4import os
 5import re
 6
 7__all__ = ["re_glob", "ire_glob"]
 8
 9def re_glob(pathname):
10    """Return a list of paths matching a pathname pattern using regular expresions
11
12    """
13    return list(ire_glob(pathname))
14
15def ire_glob(pathname):
16    """Return an iterator which yields the paths matching a pathname pattern using regular expresions
17    """
18    if not has_magic(pathname):
19        if os.path.lexists(pathname):
20            yield pathname
21        return
22    dirname, basename = os.path.split(pathname)
23    if not dirname:
24        for name in re_glob1(os.curdir, basename):
25            yield name
26        return
27    if has_magic(dirname):
28        dirs = ire_glob(dirname)
29    else:
30        dirs = [dirname]
31    if has_magic(basename):
32        re_glob_in_dir = re_glob1
33    else:
34        re_glob_in_dir = re_glob0
35    for dirname in dirs:
36        for name in re_glob_in_dir(dirname, basename):
37            yield os.path.join(dirname, name)
38
39# These 2 helper functions non-recursively re_glob inside a literal directory.
40# They return a list of basenames. `re_glob1` accepts a pattern while `re_glob0`
41# takes a literal basename (so it only has to check for its existence).
42
43def re_glob1(dirname, pattern):
44    if not dirname:
45        dirname = os.curdir
46    if isinstance(pattern, unicode) and not isinstance(dirname, unicode):
47        dirname = unicode(dirname, sys.getfilesystemencoding() or
48                                   sys.getdefaultencoding())
49    try:
50        names = os.listdir(dirname)
51    except os.error:
52        return []
53    if pattern[0] != '.':
54        names = filter(lambda x: x[0] != '.', names)
55    
56    # only where entire name is specified by regular expression    
57    matching = []
58    for n in names:
59        m = re.match(pattern, n)
60        if m and m.end() == len(n):
61            matching.append(n)
62    return matching
63
64def re_glob0(dirname, basename):
65    if basename == '':
66        # `os.path.split()` returns an empty basename for paths ending with a
67        # directory separator.  'q*x/' should match only directories.
68        if os.path.isdir(dirname):
69            return [basename]
70    else:
71        if os.path.lexists(os.path.join(dirname, basename)):
72            return [basename]
73    return []
74
75
76magic_check = re.compile('[.*\\\^$?(){}[\]]')
77
78def has_magic(s):
79    return magic_check.search(s) is not None