0001 """Pathname and path-related operations for the Macintosh.""" 0002 0003 import os 0004 from stat import * 0005 0006 __all__ = ["normcase","isabs","join","splitdrive","split","splitext", 0007 "basename","dirname","commonprefix","getsize","getmtime", 0008 "getatime","getctime", "islink","exists","isdir","isfile", 0009 "walk","expanduser","expandvars","normpath","abspath", 0010 "curdir","pardir","sep","pathsep","defpath","altsep","extsep", 0011 "devnull","realpath","supports_unicode_filenames"] 0012 0013 # strings representing various path-related bits and pieces 0014 curdir = ':' 0015 pardir = '::' 0016 extsep = '.' 0017 sep = ':' 0018 pathsep = '\n' 0019 defpath = ':' 0020 altsep = None 0021 devnull = 'Dev:Null' 0022 0023 # Normalize the case of a pathname. Dummy in Posix, but <s>.lower() here. 0024 0025 def normcase(path): 0026 return path.lower() 0027 0028 0029 def isabs(s): 0030 """Return true if a path is absolute. 0031 On the Mac, relative paths begin with a colon, 0032 but as a special case, paths with no colons at all are also relative. 0033 Anything else is absolute (the string up to the first colon is the 0034 volume name).""" 0035 0036 return ':' in s and s[0] != ':' 0037 0038 0039 def join(s, *p): 0040 path = s 0041 for t in p: 0042 if (not s) or isabs(t): 0043 path = t 0044 continue 0045 if t[:1] == ':': 0046 t = t[1:] 0047 if ':' not in path: 0048 path = ':' + path 0049 if path[-1:] != ':': 0050 path = path + ':' 0051 path = path + t 0052 return path 0053 0054 0055 def split(s): 0056 """Split a pathname into two parts: the directory leading up to the final 0057 bit, and the basename (the filename, without colons, in that directory). 0058 The result (s, t) is such that join(s, t) yields the original argument.""" 0059 0060 if ':' not in s: return '', s 0061 colon = 0 0062 for i in range(len(s)): 0063 if s[i] == ':': colon = i + 1 0064 path, file = s[:colon-1], s[colon:] 0065 if path and not ':' in path: 0066 path = path + ':' 0067 return path, file 0068 0069 0070 def splitext(p): 0071 """Split a path into root and extension. 0072 The extension is everything starting at the last dot in the last 0073 pathname component; the root is everything before that. 0074 It is always true that root + ext == p.""" 0075 0076 i = p.rfind('.') 0077 if i<=p.rfind(':'): 0078 return p, '' 0079 else: 0080 return p[:i], p[i:] 0081 0082 0083 def splitdrive(p): 0084 """Split a pathname into a drive specification and the rest of the 0085 path. Useful on DOS/Windows/NT; on the Mac, the drive is always 0086 empty (don't use the volume name -- it doesn't have the same 0087 syntactic and semantic oddities as DOS drive letters, such as there 0088 being a separate current directory per drive).""" 0089 0090 return '', p 0091 0092 0093 # Short interfaces to split() 0094 0095 def dirname(s): return split(s)[0] 0096 def basename(s): return split(s)[1] 0097 0098 def ismount(s): 0099 if not isabs(s): 0100 return False 0101 components = split(s) 0102 return len(components) == 2 and components[1] == '' 0103 0104 def isdir(s): 0105 """Return true if the pathname refers to an existing directory.""" 0106 0107 try: 0108 st = os.stat(s) 0109 except os.error: 0110 return 0 0111 return S_ISDIR(st.st_mode) 0112 0113 0114 # Get size, mtime, atime of files. 0115 0116 def getsize(filename): 0117 """Return the size of a file, reported by os.stat().""" 0118 return os.stat(filename).st_size 0119 0120 def getmtime(filename): 0121 """Return the last modification time of a file, reported by os.stat().""" 0122 return os.stat(filename).st_mtime 0123 0124 def getatime(filename): 0125 """Return the last access time of a file, reported by os.stat().""" 0126 return os.stat(filename).st_atime 0127 0128 0129 def islink(s): 0130 """Return true if the pathname refers to a symbolic link.""" 0131 0132 try: 0133 import Carbon.File 0134 return Carbon.File.ResolveAliasFile(s, 0)[2] 0135 except: 0136 return False 0137 0138 0139 def isfile(s): 0140 """Return true if the pathname refers to an existing regular file.""" 0141 0142 try: 0143 st = os.stat(s) 0144 except os.error: 0145 return False 0146 return S_ISREG(st.st_mode) 0147 0148 def getctime(filename): 0149 """Return the creation time of a file, reported by os.stat().""" 0150 return os.stat(filename).st_ctime 0151 0152 def exists(s): 0153 """Test whether a path exists. Returns False for broken symbolic links""" 0154 0155 try: 0156 st = os.stat(s) 0157 except os.error: 0158 return False 0159 return True 0160 0161 # Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any 0162 # case. 0163 0164 def lexists(path): 0165 """Test whether a path exists. Returns True for broken symbolic links""" 0166 0167 try: 0168 st = os.lstat(path) 0169 except os.error: 0170 return False 0171 return True 0172 0173 # Return the longest prefix of all list elements. 0174 0175 def commonprefix(m): 0176 "Given a list of pathnames, returns the longest common leading component" 0177 if not m: return '' 0178 prefix = m[0] 0179 for item in m: 0180 for i in range(len(prefix)): 0181 if prefix[:i+1] != item[:i+1]: 0182 prefix = prefix[:i] 0183 if i == 0: return '' 0184 break 0185 return prefix 0186 0187 def expandvars(path): 0188 """Dummy to retain interface-compatibility with other operating systems.""" 0189 return path 0190 0191 0192 def expanduser(path): 0193 """Dummy to retain interface-compatibility with other operating systems.""" 0194 return path 0195 0196 class norm_error(Exception): 0197 """Path cannot be normalized""" 0198 0199 def normpath(s): 0200 """Normalize a pathname. Will return the same result for 0201 equivalent paths.""" 0202 0203 if ":" not in s: 0204 return ":"+s 0205 0206 comps = s.split(":") 0207 i = 1 0208 while i < len(comps)-1: 0209 if comps[i] == "" and comps[i-1] != "": 0210 if i > 1: 0211 del comps[i-1:i+1] 0212 i = i - 1 0213 else: 0214 # best way to handle this is to raise an exception 0215 raise norm_error, 'Cannot use :: immediately after volume name' 0216 else: 0217 i = i + 1 0218 0219 s = ":".join(comps) 0220 0221 # remove trailing ":" except for ":" and "Volume:" 0222 if s[-1] == ":" and len(comps) > 2 and s != ":"*len(s): 0223 s = s[:-1] 0224 return s 0225 0226 0227 def walk(top, func, arg): 0228 """Directory tree walk with callback function. 0229 0230 For each directory in the directory tree rooted at top (including top 0231 itself, but excluding '.' and '..'), call func(arg, dirname, fnames). 0232 dirname is the name of the directory, and fnames a list of the names of 0233 the files and subdirectories in dirname (excluding '.' and '..'). func 0234 may modify the fnames list in-place (e.g. via del or slice assignment), 0235 and walk will only recurse into the subdirectories whose names remain in 0236 fnames; this can be used to implement a filter, or to impose a specific 0237 order of visiting. No semantics are defined for, or required of, arg, 0238 beyond that arg is always passed to func. It can be used, e.g., to pass 0239 a filename pattern, or a mutable object designed to accumulate 0240 statistics. Passing None for arg is common.""" 0241 0242 try: 0243 names = os.listdir(top) 0244 except os.error: 0245 return 0246 func(arg, top, names) 0247 for name in names: 0248 name = join(top, name) 0249 if isdir(name) and not islink(name): 0250 walk(name, func, arg) 0251 0252 0253 def abspath(path): 0254 """Return an absolute path.""" 0255 if not isabs(path): 0256 path = join(os.getcwd(), path) 0257 return normpath(path) 0258 0259 # realpath is a no-op on systems without islink support 0260 def realpath(path): 0261 path = abspath(path) 0262 try: 0263 import Carbon.File 0264 except ImportError: 0265 return path 0266 if not path: 0267 return path 0268 components = path.split(':') 0269 path = components[0] + ':' 0270 for c in components[1:]: 0271 path = join(path, c) 0272 path = Carbon.File.FSResolveAliasFile(path, 1)[0].as_pathname() 0273 return path 0274 0275 supports_unicode_filenames = False 0276
Generated by PyXR 0.9.4