PageRenderTime 43ms CodeModel.GetById 18ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/macpath.py

http://unladen-swallow.googlecode.com/
Python | 208 lines | 184 code | 13 blank | 11 comment | 14 complexity | 272adfe7ab54bd1a03fa4854a7928803 MD5 | raw file
  1"""Pathname and path-related operations for the Macintosh."""
  2
  3import os
  4import warnings
  5from stat import *
  6import genericpath
  7from genericpath import *
  8
  9__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
 10           "basename","dirname","commonprefix","getsize","getmtime",
 11           "getatime","getctime", "islink","exists","lexists","isdir","isfile",
 12           "walk","expanduser","expandvars","normpath","abspath",
 13           "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
 14           "devnull","realpath","supports_unicode_filenames"]
 15
 16# strings representing various path-related bits and pieces
 17curdir = ':'
 18pardir = '::'
 19extsep = '.'
 20sep = ':'
 21pathsep = '\n'
 22defpath = ':'
 23altsep = None
 24devnull = 'Dev:Null'
 25
 26# Normalize the case of a pathname.  Dummy in Posix, but <s>.lower() here.
 27
 28def normcase(path):
 29    return path.lower()
 30
 31
 32def isabs(s):
 33    """Return true if a path is absolute.
 34    On the Mac, relative paths begin with a colon,
 35    but as a special case, paths with no colons at all are also relative.
 36    Anything else is absolute (the string up to the first colon is the
 37    volume name)."""
 38
 39    return ':' in s and s[0] != ':'
 40
 41
 42def join(s, *p):
 43    path = s
 44    for t in p:
 45        if (not s) or isabs(t):
 46            path = t
 47            continue
 48        if t[:1] == ':':
 49            t = t[1:]
 50        if ':' not in path:
 51            path = ':' + path
 52        if path[-1:] != ':':
 53            path = path + ':'
 54        path = path + t
 55    return path
 56
 57
 58def split(s):
 59    """Split a pathname into two parts: the directory leading up to the final
 60    bit, and the basename (the filename, without colons, in that directory).
 61    The result (s, t) is such that join(s, t) yields the original argument."""
 62
 63    if ':' not in s: return '', s
 64    colon = 0
 65    for i in range(len(s)):
 66        if s[i] == ':': colon = i + 1
 67    path, file = s[:colon-1], s[colon:]
 68    if path and not ':' in path:
 69        path = path + ':'
 70    return path, file
 71
 72
 73def splitext(p):
 74    return genericpath._splitext(p, sep, altsep, extsep)
 75splitext.__doc__ = genericpath._splitext.__doc__
 76
 77def splitdrive(p):
 78    """Split a pathname into a drive specification and the rest of the
 79    path.  Useful on DOS/Windows/NT; on the Mac, the drive is always
 80    empty (don't use the volume name -- it doesn't have the same
 81    syntactic and semantic oddities as DOS drive letters, such as there
 82    being a separate current directory per drive)."""
 83
 84    return '', p
 85
 86
 87# Short interfaces to split()
 88
 89def dirname(s): return split(s)[0]
 90def basename(s): return split(s)[1]
 91
 92def ismount(s):
 93    if not isabs(s):
 94        return False
 95    components = split(s)
 96    return len(components) == 2 and components[1] == ''
 97
 98def islink(s):
 99    """Return true if the pathname refers to a symbolic link."""
100
101    try:
102        import Carbon.File
103        return Carbon.File.ResolveAliasFile(s, 0)[2]
104    except:
105        return False
106
107# Is `stat`/`lstat` a meaningful difference on the Mac?  This is safe in any
108# case.
109
110def lexists(path):
111    """Test whether a path exists.  Returns True for broken symbolic links"""
112
113    try:
114        st = os.lstat(path)
115    except os.error:
116        return False
117    return True
118
119def expandvars(path):
120    """Dummy to retain interface-compatibility with other operating systems."""
121    return path
122
123
124def expanduser(path):
125    """Dummy to retain interface-compatibility with other operating systems."""
126    return path
127
128class norm_error(Exception):
129    """Path cannot be normalized"""
130
131def normpath(s):
132    """Normalize a pathname.  Will return the same result for
133    equivalent paths."""
134
135    if ":" not in s:
136        return ":"+s
137
138    comps = s.split(":")
139    i = 1
140    while i < len(comps)-1:
141        if comps[i] == "" and comps[i-1] != "":
142            if i > 1:
143                del comps[i-1:i+1]
144                i = i - 1
145            else:
146                # best way to handle this is to raise an exception
147                raise norm_error, 'Cannot use :: immediately after volume name'
148        else:
149            i = i + 1
150
151    s = ":".join(comps)
152
153    # remove trailing ":" except for ":" and "Volume:"
154    if s[-1] == ":" and len(comps) > 2 and s != ":"*len(s):
155        s = s[:-1]
156    return s
157
158
159def walk(top, func, arg):
160    """Directory tree walk with callback function.
161
162    For each directory in the directory tree rooted at top (including top
163    itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
164    dirname is the name of the directory, and fnames a list of the names of
165    the files and subdirectories in dirname (excluding '.' and '..').  func
166    may modify the fnames list in-place (e.g. via del or slice assignment),
167    and walk will only recurse into the subdirectories whose names remain in
168    fnames; this can be used to implement a filter, or to impose a specific
169    order of visiting.  No semantics are defined for, or required of, arg,
170    beyond that arg is always passed to func.  It can be used, e.g., to pass
171    a filename pattern, or a mutable object designed to accumulate
172    statistics.  Passing None for arg is common."""
173    warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",
174                      stacklevel=2)
175    try:
176        names = os.listdir(top)
177    except os.error:
178        return
179    func(arg, top, names)
180    for name in names:
181        name = join(top, name)
182        if isdir(name) and not islink(name):
183            walk(name, func, arg)
184
185
186def abspath(path):
187    """Return an absolute path."""
188    if not isabs(path):
189        path = join(os.getcwd(), path)
190    return normpath(path)
191
192# realpath is a no-op on systems without islink support
193def realpath(path):
194    path = abspath(path)
195    try:
196        import Carbon.File
197    except ImportError:
198        return path
199    if not path:
200        return path
201    components = path.split(':')
202    path = components[0] + ':'
203    for c in components[1:]:
204        path = join(path, c)
205        path = Carbon.File.FSResolveAliasFile(path, 1)[0].as_pathname()
206    return path
207
208supports_unicode_filenames = False