blob: 9ebd83cf90db9e43cf88137d2fc906296044447e [file] [log] [blame]
Guido van Rossum54f22ed2000-02-04 15:10:34 +00001"""Pathname and path-related operations for the Macintosh."""
Guido van Rossum217a5fa1990-12-26 15:40:07 +00002
Guido van Rossum5c1d2291998-03-03 21:49:01 +00003import os
Benjamin Peterson0893a0a2008-05-09 00:27:01 +00004import warnings
Guido van Rossum217a5fa1990-12-26 15:40:07 +00005from stat import *
Martin v. Löwis05c075d2007-03-07 11:04:33 +00006import genericpath
Jack Diederich7b604642006-08-26 18:42:06 +00007from genericpath import *
Serhiy Storchaka2bd8b222015-02-13 12:02:05 +02008from genericpath import _unicode
Guido van Rossum217a5fa1990-12-26 15:40:07 +00009
Skip Montanaro17ab1232001-01-24 06:27:27 +000010__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
11 "basename","dirname","commonprefix","getsize","getmtime",
Georg Brandlf0de6a12005-08-22 18:02:59 +000012 "getatime","getctime", "islink","exists","lexists","isdir","isfile",
Mark Hammond8696ebc2002-10-08 02:44:31 +000013 "walk","expanduser","expandvars","normpath","abspath",
Skip Montanaro117910d2003-02-14 19:35:31 +000014 "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
Martin v. Löwisbdec50f2004-06-08 08:29:33 +000015 "devnull","realpath","supports_unicode_filenames"]
Guido van Rossumb5e05e91991-01-01 18:10:40 +000016
Skip Montanaro117910d2003-02-14 19:35:31 +000017# strings representing various path-related bits and pieces
18curdir = ':'
19pardir = '::'
20extsep = '.'
21sep = ':'
22pathsep = '\n'
23defpath = ':'
24altsep = None
Martin v. Löwisbdec50f2004-06-08 08:29:33 +000025devnull = 'Dev:Null'
Skip Montanaro117910d2003-02-14 19:35:31 +000026
Fred Drakeb4e460a2000-09-28 16:25:20 +000027# Normalize the case of a pathname. Dummy in Posix, but <s>.lower() here.
Guido van Rossum599f2ed1992-01-14 18:28:18 +000028
Fred Drakeb4e460a2000-09-28 16:25:20 +000029def normcase(path):
30 return path.lower()
Guido van Rossum599f2ed1992-01-14 18:28:18 +000031
32
Guido van Rossum217a5fa1990-12-26 15:40:07 +000033def isabs(s):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000034 """Return true if a path is absolute.
35 On the Mac, relative paths begin with a colon,
36 but as a special case, paths with no colons at all are also relative.
37 Anything else is absolute (the string up to the first colon is the
38 volume name)."""
39
Fred Drake8152d322000-12-12 23:20:45 +000040 return ':' in s and s[0] != ':'
Guido van Rossum217a5fa1990-12-26 15:40:07 +000041
Guido van Rossumb5e05e91991-01-01 18:10:40 +000042
Barry Warsaw384d2491997-02-18 21:53:25 +000043def join(s, *p):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000044 path = s
45 for t in p:
Serhiy Storchakae4300732014-09-27 18:53:01 +030046 if (not path) or isabs(t):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000047 path = t
48 continue
49 if t[:1] == ':':
50 t = t[1:]
51 if ':' not in path:
52 path = ':' + path
Fred Drake8152d322000-12-12 23:20:45 +000053 if path[-1:] != ':':
Guido van Rossum54f22ed2000-02-04 15:10:34 +000054 path = path + ':'
55 path = path + t
56 return path
Guido van Rossum217a5fa1990-12-26 15:40:07 +000057
Guido van Rossumb5e05e91991-01-01 18:10:40 +000058
Guido van Rossumb5e05e91991-01-01 18:10:40 +000059def split(s):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000060 """Split a pathname into two parts: the directory leading up to the final
61 bit, and the basename (the filename, without colons, in that directory).
62 The result (s, t) is such that join(s, t) yields the original argument."""
Guido van Rossumb5e05e91991-01-01 18:10:40 +000063
Guido van Rossum54f22ed2000-02-04 15:10:34 +000064 if ':' not in s: return '', s
65 colon = 0
66 for i in range(len(s)):
Fred Drakeb4e460a2000-09-28 16:25:20 +000067 if s[i] == ':': colon = i + 1
Guido van Rossum54f22ed2000-02-04 15:10:34 +000068 path, file = s[:colon-1], s[colon:]
69 if path and not ':' in path:
70 path = path + ':'
71 return path, file
Guido van Rossumb5e05e91991-01-01 18:10:40 +000072
Guido van Rossuma48bf791996-07-23 02:28:32 +000073
74def splitext(p):
Martin v. Löwis05c075d2007-03-07 11:04:33 +000075 return genericpath._splitext(p, sep, altsep, extsep)
76splitext.__doc__ = genericpath._splitext.__doc__
Guido van Rossum0ec31261995-08-10 18:09:16 +000077
78def splitdrive(p):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000079 """Split a pathname into a drive specification and the rest of the
80 path. Useful on DOS/Windows/NT; on the Mac, the drive is always
81 empty (don't use the volume name -- it doesn't have the same
82 syntactic and semantic oddities as DOS drive letters, such as there
83 being a separate current directory per drive)."""
84
85 return '', p
Guido van Rossum0ec31261995-08-10 18:09:16 +000086
87
Guido van Rossumc629d341992-11-05 10:43:02 +000088# Short interfaces to split()
89
90def dirname(s): return split(s)[0]
91def basename(s): return split(s)[1]
92
Jack Jansen791f7d42003-01-15 22:45:48 +000093def ismount(s):
Tim Peters2c60f7a2003-01-29 03:49:43 +000094 if not isabs(s):
95 return False
96 components = split(s)
97 return len(components) == 2 and components[1] == ''
Guido van Rossumc629d341992-11-05 10:43:02 +000098
Guido van Rossum7e4b2de1995-01-27 02:41:45 +000099def islink(s):
Jack Jansen992d58b2002-04-22 13:55:43 +0000100 """Return true if the pathname refers to a symbolic link."""
Guido van Rossum7e4b2de1995-01-27 02:41:45 +0000101
Jack Jansen992d58b2002-04-22 13:55:43 +0000102 try:
Jack Jansen98fc6832003-02-27 23:18:46 +0000103 import Carbon.File
104 return Carbon.File.ResolveAliasFile(s, 0)[2]
Jack Jansen992d58b2002-04-22 13:55:43 +0000105 except:
106 return False
Guido van Rossum7e4b2de1995-01-27 02:41:45 +0000107
Johannes Gijsbersae882f72004-08-30 10:19:56 +0000108# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
109# case.
110
111def lexists(path):
112 """Test whether a path exists. Returns True for broken symbolic links"""
113
114 try:
115 st = os.lstat(path)
116 except os.error:
117 return False
118 return True
119
Jack Jansenf4e7d2a1995-12-15 13:23:37 +0000120def expandvars(path):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000121 """Dummy to retain interface-compatibility with other operating systems."""
122 return path
Jack Jansenf4e7d2a1995-12-15 13:23:37 +0000123
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000124
Jack Jansenf4e7d2a1995-12-15 13:23:37 +0000125def expanduser(path):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000126 """Dummy to retain interface-compatibility with other operating systems."""
127 return path
Guido van Rossum0ec31261995-08-10 18:09:16 +0000128
Neal Norwitz93cf79f2002-03-31 14:06:41 +0000129class norm_error(Exception):
130 """Path cannot be normalized"""
Guido van Rossumc629d341992-11-05 10:43:02 +0000131
132def normpath(s):
Jack Jansen2fc01092000-08-06 21:18:35 +0000133 """Normalize a pathname. Will return the same result for
134 equivalent paths."""
Jack Jansena68bfe21995-08-07 14:09:27 +0000135
Jack Jansen2fc01092000-08-06 21:18:35 +0000136 if ":" not in s:
137 return ":"+s
138
Fred Drakeb4e460a2000-09-28 16:25:20 +0000139 comps = s.split(":")
Jack Jansen2fc01092000-08-06 21:18:35 +0000140 i = 1
141 while i < len(comps)-1:
142 if comps[i] == "" and comps[i-1] != "":
143 if i > 1:
144 del comps[i-1:i+1]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000145 i = i - 1
Jack Jansen2fc01092000-08-06 21:18:35 +0000146 else:
147 # best way to handle this is to raise an exception
Greg Ward034cbf12001-08-08 20:55:10 +0000148 raise norm_error, 'Cannot use :: immediately after volume name'
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000149 else:
Jack Jansen2fc01092000-08-06 21:18:35 +0000150 i = i + 1
151
Fred Drakeb4e460a2000-09-28 16:25:20 +0000152 s = ":".join(comps)
Jack Jansen2fc01092000-08-06 21:18:35 +0000153
154 # remove trailing ":" except for ":" and "Volume:"
155 if s[-1] == ":" and len(comps) > 2 and s != ":"*len(s):
156 s = s[:-1]
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000157 return s
Guido van Rossum0ec31261995-08-10 18:09:16 +0000158
Jack Jansena68bfe21995-08-07 14:09:27 +0000159
160def walk(top, func, arg):
Tim Peterscf5e6a42001-10-10 04:16:20 +0000161 """Directory tree walk with callback function.
162
163 For each directory in the directory tree rooted at top (including top
164 itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
165 dirname is the name of the directory, and fnames a list of the names of
166 the files and subdirectories in dirname (excluding '.' and '..'). func
167 may modify the fnames list in-place (e.g. via del or slice assignment),
168 and walk will only recurse into the subdirectories whose names remain in
169 fnames; this can be used to implement a filter, or to impose a specific
170 order of visiting. No semantics are defined for, or required of, arg,
171 beyond that arg is always passed to func. It can be used, e.g., to pass
172 a filename pattern, or a mutable object designed to accumulate
173 statistics. Passing None for arg is common."""
Philip Jenveyd846f1d2009-05-08 02:28:39 +0000174 warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",
175 stacklevel=2)
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000176 try:
177 names = os.listdir(top)
178 except os.error:
179 return
180 func(arg, top, names)
181 for name in names:
182 name = join(top, name)
Jack Jansen992d58b2002-04-22 13:55:43 +0000183 if isdir(name) and not islink(name):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000184 walk(name, func, arg)
Guido van Rossume294cf61999-01-29 18:05:18 +0000185
186
Guido van Rossume294cf61999-01-29 18:05:18 +0000187def abspath(path):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000188 """Return an absolute path."""
Guido van Rossume294cf61999-01-29 18:05:18 +0000189 if not isabs(path):
Serhiy Storchaka2bd8b222015-02-13 12:02:05 +0200190 if isinstance(path, _unicode):
Ezio Melotti4cc80ca2010-02-20 08:09:39 +0000191 cwd = os.getcwdu()
192 else:
193 cwd = os.getcwd()
194 path = join(cwd, path)
Guido van Rossume294cf61999-01-29 18:05:18 +0000195 return normpath(path)
Guido van Rossum83eeef42001-09-17 15:16:09 +0000196
197# realpath is a no-op on systems without islink support
Jack Jansen992d58b2002-04-22 13:55:43 +0000198def realpath(path):
Tim Peters8ac14952002-05-23 15:15:30 +0000199 path = abspath(path)
200 try:
Jack Jansen98fc6832003-02-27 23:18:46 +0000201 import Carbon.File
Tim Peters8ac14952002-05-23 15:15:30 +0000202 except ImportError:
203 return path
204 if not path:
205 return path
206 components = path.split(':')
207 path = components[0] + ':'
208 for c in components[1:]:
209 path = join(path, c)
Florent Xiclunacf82fa62010-03-21 12:27:20 +0000210 try:
211 path = Carbon.File.FSResolveAliasFile(path, 1)[0].as_pathname()
212 except Carbon.File.Error:
213 pass
Tim Peters8ac14952002-05-23 15:15:30 +0000214 return path
Mark Hammond8696ebc2002-10-08 02:44:31 +0000215
Victor Stinner46287f52010-09-13 20:31:34 +0000216supports_unicode_filenames = True