| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  | """Pathname and path-related operations for the Macintosh.""" | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 21:49:01 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | from stat import * | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-01-24 06:27:27 +00:00
										 |  |  | __all__ = ["normcase","isabs","join","splitdrive","split","splitext", | 
					
						
							|  |  |  |            "basename","dirname","commonprefix","getsize","getmtime", | 
					
						
							|  |  |  |            "getatime","islink","exists","isdir","isfile", | 
					
						
							|  |  |  |            "walk","expanduser","expandvars","normpath","abspath"] | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-28 16:25:20 +00:00
										 |  |  | # Normalize the case of a pathname.  Dummy in Posix, but <s>.lower() here. | 
					
						
							| 
									
										
										
										
											1992-01-14 18:28:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-28 16:25:20 +00:00
										 |  |  | def normcase(path): | 
					
						
							|  |  |  |     return path.lower() | 
					
						
							| 
									
										
										
										
											1992-01-14 18:28:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | def isabs(s): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Return true if a path is absolute.
 | 
					
						
							|  |  |  |     On the Mac, relative paths begin with a colon, | 
					
						
							|  |  |  |     but as a special case, paths with no colons at all are also relative. | 
					
						
							|  |  |  |     Anything else is absolute (the string up to the first colon is the | 
					
						
							|  |  |  |     volume name)."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-12-12 23:20:45 +00:00
										 |  |  |     return ':' in s and s[0] != ':' | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:25 +00:00
										 |  |  | def join(s, *p): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     path = s | 
					
						
							|  |  |  |     for t in p: | 
					
						
							|  |  |  |         if (not s) or isabs(t): | 
					
						
							|  |  |  |             path = t | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if t[:1] == ':': | 
					
						
							|  |  |  |             t = t[1:] | 
					
						
							|  |  |  |         if ':' not in path: | 
					
						
							|  |  |  |             path = ':' + path | 
					
						
							| 
									
										
										
										
											2000-12-12 23:20:45 +00:00
										 |  |  |         if path[-1:] != ':': | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |             path = path + ':' | 
					
						
							|  |  |  |         path = path + t | 
					
						
							|  |  |  |     return path | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def split(s): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Split a pathname into two parts: the directory leading up to the final
 | 
					
						
							|  |  |  |     bit, and the basename (the filename, without colons, in that directory). | 
					
						
							|  |  |  |     The result (s, t) is such that join(s, t) yields the original argument."""
 | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     if ':' not in s: return '', s | 
					
						
							|  |  |  |     colon = 0 | 
					
						
							|  |  |  |     for i in range(len(s)): | 
					
						
							| 
									
										
										
										
											2000-09-28 16:25:20 +00:00
										 |  |  |         if s[i] == ':': colon = i + 1 | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     path, file = s[:colon-1], s[colon:] | 
					
						
							|  |  |  |     if path and not ':' in path: | 
					
						
							|  |  |  |         path = path + ':' | 
					
						
							|  |  |  |     return path, file | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-07-23 02:28:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def splitext(p): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Split a path into root and extension.
 | 
					
						
							|  |  |  |     The extension is everything starting at the last dot in the last | 
					
						
							|  |  |  |     pathname component; the root is everything before that. | 
					
						
							|  |  |  |     It is always true that root + ext == p."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     root, ext = '', '' | 
					
						
							|  |  |  |     for c in p: | 
					
						
							|  |  |  |         if c == ':': | 
					
						
							|  |  |  |             root, ext = root + ext + c, '' | 
					
						
							|  |  |  |         elif c == '.': | 
					
						
							|  |  |  |             if ext: | 
					
						
							|  |  |  |                 root, ext = root + ext, c | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 ext = c | 
					
						
							|  |  |  |         elif ext: | 
					
						
							|  |  |  |             ext = ext + c | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             root = root + c | 
					
						
							|  |  |  |     return root, ext | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-11-05 10:43:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-10 18:09:16 +00:00
										 |  |  | def splitdrive(p): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Split a pathname into a drive specification and the rest of the
 | 
					
						
							|  |  |  |     path.  Useful on DOS/Windows/NT; on the Mac, the drive is always | 
					
						
							|  |  |  |     empty (don't use the volume name -- it doesn't have the same | 
					
						
							|  |  |  |     syntactic and semantic oddities as DOS drive letters, such as there | 
					
						
							|  |  |  |     being a separate current directory per drive)."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return '', p | 
					
						
							| 
									
										
										
										
											1992-11-05 10:43:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-10 18:09:16 +00:00
										 |  |  | # Short interfaces to split() | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-10 18:09:16 +00:00
										 |  |  | def dirname(s): return split(s)[0] | 
					
						
							|  |  |  | def basename(s): return split(s)[1] | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | def isdir(s): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Return true if the pathname refers to an existing directory.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         st = os.stat(s) | 
					
						
							|  |  |  |     except os.error: | 
					
						
							|  |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2002-06-01 19:51:15 +00:00
										 |  |  |     return S_ISDIR(st.st_mode) | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-07-24 20:49:26 +00:00
										 |  |  | # Get size, mtime, atime of files. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def getsize(filename): | 
					
						
							|  |  |  |     """Return the size of a file, reported by os.stat().""" | 
					
						
							| 
									
										
										
										
											2002-06-01 19:51:15 +00:00
										 |  |  |     return os.stat(filename).st_size | 
					
						
							| 
									
										
										
										
											1998-07-24 20:49:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getmtime(filename): | 
					
						
							|  |  |  |     """Return the last modification time of a file, reported by os.stat().""" | 
					
						
							| 
									
										
										
										
											2002-06-01 19:51:15 +00:00
										 |  |  |     return os.stat(filename).st_mtime | 
					
						
							| 
									
										
										
										
											1998-07-24 20:49:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getatime(filename): | 
					
						
							|  |  |  |     """Return the last access time of a file, reported by os.stat().""" | 
					
						
							| 
									
										
										
										
											2002-06-01 19:51:15 +00:00
										 |  |  |     return os.stat(filename).st_atime | 
					
						
							| 
									
										
										
										
											1998-07-24 20:49:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | def islink(s): | 
					
						
							| 
									
										
										
										
											2002-04-22 13:55:43 +00:00
										 |  |  |     """Return true if the pathname refers to a symbolic link.""" | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-22 13:55:43 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2002-04-23 02:38:39 +00:00
										 |  |  |         import macfs | 
					
						
							| 
									
										
										
										
											2002-04-22 13:55:43 +00:00
										 |  |  |         return macfs.ResolveAliasFile(s)[2] | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | def isfile(s): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Return true if the pathname refers to an existing regular file.""" | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     try: | 
					
						
							|  |  |  |         st = os.stat(s) | 
					
						
							|  |  |  |     except os.error: | 
					
						
							| 
									
										
										
										
											2002-04-07 06:36:23 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2002-06-01 19:51:15 +00:00
										 |  |  |     return S_ISREG(st.st_mode) | 
					
						
							| 
									
										
										
										
											1991-01-01 18:10:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-12-26 15:40:07 +00:00
										 |  |  | def exists(s): | 
					
						
							| 
									
										
										
										
											2002-04-04 22:55:58 +00:00
										 |  |  |     """Return True if the pathname refers to an existing file or directory.""" | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         st = os.stat(s) | 
					
						
							|  |  |  |     except os.error: | 
					
						
							| 
									
										
										
										
											2002-04-04 22:55:58 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  |     return True | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-08-23 09:13:40 +00:00
										 |  |  | # Return the longest prefix of all list elements. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def commonprefix(m): | 
					
						
							|  |  |  |     "Given a list of pathnames, returns the longest common leading component" | 
					
						
							|  |  |  |     if not m: return '' | 
					
						
							|  |  |  |     prefix = m[0] | 
					
						
							|  |  |  |     for item in m: | 
					
						
							|  |  |  |         for i in range(len(prefix)): | 
					
						
							| 
									
										
										
										
											2000-12-12 23:20:45 +00:00
										 |  |  |             if prefix[:i+1] != item[:i+1]: | 
					
						
							| 
									
										
										
										
											2000-08-23 09:13:40 +00:00
										 |  |  |                 prefix = prefix[:i] | 
					
						
							|  |  |  |                 if i == 0: return '' | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |     return prefix | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-12-15 13:23:37 +00:00
										 |  |  | def expandvars(path): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Dummy to retain interface-compatibility with other operating systems.""" | 
					
						
							|  |  |  |     return path | 
					
						
							| 
									
										
										
										
											1995-12-15 13:23:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-11-05 10:43:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  | def expanduser(path): | 
					
						
							|  |  |  |     """Dummy to retain interface-compatibility with other operating systems.""" | 
					
						
							|  |  |  |     return path | 
					
						
							| 
									
										
										
										
											1995-08-10 18:09:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-03-31 14:06:41 +00:00
										 |  |  | class norm_error(Exception): | 
					
						
							|  |  |  |     """Path cannot be normalized""" | 
					
						
							| 
									
										
										
										
											1992-11-05 10:43:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def normpath(s): | 
					
						
							| 
									
										
										
										
											2000-08-06 21:18:35 +00:00
										 |  |  |     """Normalize a pathname.  Will return the same result for
 | 
					
						
							|  |  |  |     equivalent paths."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ":" not in s: | 
					
						
							|  |  |  |         return ":"+s | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-28 16:25:20 +00:00
										 |  |  |     comps = s.split(":") | 
					
						
							| 
									
										
										
										
											2000-08-06 21:18:35 +00:00
										 |  |  |     i = 1 | 
					
						
							|  |  |  |     while i < len(comps)-1: | 
					
						
							|  |  |  |         if comps[i] == "" and comps[i-1] != "": | 
					
						
							|  |  |  |             if i > 1: | 
					
						
							|  |  |  |                 del comps[i-1:i+1] | 
					
						
							| 
									
										
										
										
											2000-09-28 16:25:20 +00:00
										 |  |  |                 i = i - 1 | 
					
						
							| 
									
										
										
										
											2000-08-06 21:18:35 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 # best way to handle this is to raise an exception | 
					
						
							| 
									
										
										
										
											2001-08-08 20:55:10 +00:00
										 |  |  |                 raise norm_error, 'Cannot use :: immediately after volume name' | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2000-08-06 21:18:35 +00:00
										 |  |  |             i = i + 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-28 16:25:20 +00:00
										 |  |  |     s = ":".join(comps) | 
					
						
							| 
									
										
										
										
											2000-08-06 21:18:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # remove trailing ":" except for ":" and "Volume:" | 
					
						
							|  |  |  |     if s[-1] == ":" and len(comps) > 2 and s != ":"*len(s): | 
					
						
							|  |  |  |         s = s[:-1] | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     return s | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-07 14:09:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def walk(top, func, arg): | 
					
						
							| 
									
										
										
										
											2001-10-10 04:16:20 +00:00
										 |  |  |     """Directory tree walk with callback function.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     For each directory in the directory tree rooted at top (including top | 
					
						
							|  |  |  |     itself, but excluding '.' and '..'), call func(arg, dirname, fnames). | 
					
						
							|  |  |  |     dirname is the name of the directory, and fnames a list of the names of | 
					
						
							|  |  |  |     the files and subdirectories in dirname (excluding '.' and '..').  func | 
					
						
							|  |  |  |     may modify the fnames list in-place (e.g. via del or slice assignment), | 
					
						
							|  |  |  |     and walk will only recurse into the subdirectories whose names remain in | 
					
						
							|  |  |  |     fnames; this can be used to implement a filter, or to impose a specific | 
					
						
							|  |  |  |     order of visiting.  No semantics are defined for, or required of, arg, | 
					
						
							|  |  |  |     beyond that arg is always passed to func.  It can be used, e.g., to pass | 
					
						
							|  |  |  |     a filename pattern, or a mutable object designed to accumulate | 
					
						
							|  |  |  |     statistics.  Passing None for arg is common."""
 | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         names = os.listdir(top) | 
					
						
							|  |  |  |     except os.error: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     func(arg, top, names) | 
					
						
							|  |  |  |     for name in names: | 
					
						
							|  |  |  |         name = join(top, name) | 
					
						
							| 
									
										
										
										
											2002-04-22 13:55:43 +00:00
										 |  |  |         if isdir(name) and not islink(name): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |             walk(name, func, arg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-01-29 18:05:18 +00:00
										 |  |  | def abspath(path): | 
					
						
							| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  |     """Return an absolute path.""" | 
					
						
							| 
									
										
										
										
											1999-01-29 18:05:18 +00:00
										 |  |  |     if not isabs(path): | 
					
						
							|  |  |  |         path = join(os.getcwd(), path) | 
					
						
							|  |  |  |     return normpath(path) | 
					
						
							| 
									
										
										
										
											2001-09-17 15:16:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # realpath is a no-op on systems without islink support | 
					
						
							| 
									
										
										
										
											2002-04-22 13:55:43 +00:00
										 |  |  | def realpath(path): | 
					
						
							| 
									
										
										
										
											2002-05-23 15:15:30 +00:00
										 |  |  |     path = abspath(path) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         import macfs | 
					
						
							|  |  |  |     except ImportError: | 
					
						
							|  |  |  |         return path | 
					
						
							|  |  |  |     if not path: | 
					
						
							|  |  |  |         return path | 
					
						
							|  |  |  |     components = path.split(':') | 
					
						
							|  |  |  |     path = components[0] + ':' | 
					
						
							|  |  |  |     for c in components[1:]: | 
					
						
							|  |  |  |         path = join(path, c) | 
					
						
							|  |  |  |         path = macfs.ResolveAliasFile(path)[0].as_pathname() | 
					
						
							|  |  |  |     return path |