blob: 0f1dd4dc608aa2f15fc457cb6ac59d40edbfab6d [file] [log] [blame]
Guido van Rossum15e22e11997-12-05 19:03:01 +00001# Module 'ntpath' -- common operations on WinNT/Win95 pathnames
Tim Peters2344fae2001-01-15 00:50:52 +00002"""Common pathname manipulations, WindowsNT/95 version.
Guido van Rossum534972b1999-02-03 17:20:50 +00003
4Instead of importing this module directly, import os and refer to this
5module as os.path.
Guido van Rossum15e22e11997-12-05 19:03:01 +00006"""
Guido van Rossum555915a1994-02-24 11:32:59 +00007
8import os
9import stat
Mark Hammond8696ebc2002-10-08 02:44:31 +000010import sys
Skip Montanaro4d5d5bf2000-07-13 01:01:03 +000011
Skip Montanaro269b83b2001-02-06 01:07:02 +000012__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
13 "basename","dirname","commonprefix","getsize","getmtime",
14 "getatime","islink","exists","isdir","isfile","ismount",
Mark Hammond8696ebc2002-10-08 02:44:31 +000015 "walk","expanduser","expandvars","normpath","abspath","splitunc",
16 "supports_unicode_filenames"]
Guido van Rossum555915a1994-02-24 11:32:59 +000017
Guido van Rossume2ad88c1997-08-12 14:46:58 +000018# Normalize the case of a pathname and map slashes to backslashes.
19# Other normalizations (such as optimizing '../' away) are not done
Guido van Rossum555915a1994-02-24 11:32:59 +000020# (this is done by normpath).
Guido van Rossume2ad88c1997-08-12 14:46:58 +000021
Guido van Rossum555915a1994-02-24 11:32:59 +000022def normcase(s):
Guido van Rossum16a0bc21998-02-18 13:48:31 +000023 """Normalize case of pathname.
24
Guido van Rossum534972b1999-02-03 17:20:50 +000025 Makes all characters lowercase and all slashes into backslashes."""
Fred Drakeb4e460a2000-09-28 16:25:20 +000026 return s.replace("/", "\\").lower()
Guido van Rossum555915a1994-02-24 11:32:59 +000027
Guido van Rossum77e1db31997-06-02 23:11:57 +000028
Fred Drakeef0b5dd2000-02-17 17:30:40 +000029# Return whether a path is absolute.
Guido van Rossum555915a1994-02-24 11:32:59 +000030# Trivial in Posix, harder on the Mac or MS-DOS.
31# For DOS it is absolute if it starts with a slash or backslash (current
Guido van Rossum534972b1999-02-03 17:20:50 +000032# volume), or if a pathname after the volume letter and colon / UNC resource
33# starts with a slash or backslash.
Guido van Rossum555915a1994-02-24 11:32:59 +000034
35def isabs(s):
Guido van Rossum15e22e11997-12-05 19:03:01 +000036 """Test whether a path is absolute"""
37 s = splitdrive(s)[1]
38 return s != '' and s[:1] in '/\\'
Guido van Rossum555915a1994-02-24 11:32:59 +000039
40
Guido van Rossum77e1db31997-06-02 23:11:57 +000041# Join two (or more) paths.
42
Barry Warsaw384d2491997-02-18 21:53:25 +000043def join(a, *p):
Guido van Rossum15e22e11997-12-05 19:03:01 +000044 """Join two or more pathname components, inserting "\\" as needed"""
45 path = a
46 for b in p:
Tim Peters33dc0a12001-07-27 08:09:54 +000047 b_wins = 0 # set to 1 iff b makes path irrelevant
48 if path == "":
49 b_wins = 1
Tim Peters1bdd0f22001-07-19 17:18:18 +000050
Tim Peters33dc0a12001-07-27 08:09:54 +000051 elif isabs(b):
52 # This probably wipes out path so far. However, it's more
53 # complicated if path begins with a drive letter:
54 # 1. join('c:', '/a') == 'c:/a'
55 # 2. join('c:/', '/a') == 'c:/a'
56 # But
57 # 3. join('c:/a', '/b') == '/b'
58 # 4. join('c:', 'd:/') = 'd:/'
59 # 5. join('c:/', 'd:/') = 'd:/'
60 if path[1:2] != ":" or b[1:2] == ":":
61 # Path doesn't start with a drive letter, or cases 4 and 5.
62 b_wins = 1
Tim Peters1bdd0f22001-07-19 17:18:18 +000063
Tim Peters33dc0a12001-07-27 08:09:54 +000064 # Else path has a drive letter, and b doesn't but is absolute.
65 elif len(path) > 3 or (len(path) == 3 and
66 path[-1] not in "/\\"):
67 # case 3
68 b_wins = 1
Tim Peters1bdd0f22001-07-19 17:18:18 +000069
Tim Peters33dc0a12001-07-27 08:09:54 +000070 if b_wins:
71 path = b
72 else:
73 # Join, and ensure there's a separator.
74 assert len(path) > 0
75 if path[-1] in "/\\":
76 if b and b[0] in "/\\":
77 path += b[1:]
78 else:
79 path += b
80 elif path[-1] == ":":
81 path += b
82 elif b:
83 if b[0] in "/\\":
84 path += b
85 else:
86 path += "\\" + b
Tim Peters6a3e5f12001-11-05 21:25:02 +000087 else:
88 # path is not empty and does not end with a backslash,
89 # but b is empty; since, e.g., split('a/') produces
90 # ('a', ''), it's best if join() adds a backslash in
91 # this case.
92 path += '\\'
Tim Peters1bdd0f22001-07-19 17:18:18 +000093
Guido van Rossum15e22e11997-12-05 19:03:01 +000094 return path
Guido van Rossum555915a1994-02-24 11:32:59 +000095
96
97# Split a path in a drive specification (a drive letter followed by a
Guido van Rossumf3c695c1999-04-06 19:32:19 +000098# colon) and the path specification.
Guido van Rossum555915a1994-02-24 11:32:59 +000099# It is always true that drivespec + pathspec == p
100def splitdrive(p):
Guido van Rossumf3c695c1999-04-06 19:32:19 +0000101 """Split a pathname into drive and path specifiers. Returns a 2-tuple
102"(drive,path)"; either part may be empty"""
Guido van Rossum15e22e11997-12-05 19:03:01 +0000103 if p[1:2] == ':':
104 return p[0:2], p[2:]
Guido van Rossumf3c695c1999-04-06 19:32:19 +0000105 return '', p
106
107
108# Parse UNC paths
109def splitunc(p):
110 """Split a pathname into UNC mount point and relative path specifiers.
111
112 Return a 2-tuple (unc, rest); either part may be empty.
113 If unc is not empty, it has the form '//host/mount' (or similar
114 using backslashes). unc+rest is always the input path.
115 Paths containing drive letters never have an UNC part.
116 """
117 if p[1:2] == ':':
118 return '', p # Drive letter present
Guido van Rossum534972b1999-02-03 17:20:50 +0000119 firstTwo = p[0:2]
120 if firstTwo == '//' or firstTwo == '\\\\':
121 # is a UNC path:
122 # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
123 # \\machine\mountpoint\directories...
124 # directory ^^^^^^^^^^^^^^^
125 normp = normcase(p)
Fred Drakeb4e460a2000-09-28 16:25:20 +0000126 index = normp.find('\\', 2)
Guido van Rossum534972b1999-02-03 17:20:50 +0000127 if index == -1:
128 ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
129 return ("", p)
Fred Drakeb4e460a2000-09-28 16:25:20 +0000130 index = normp.find('\\', index + 1)
Guido van Rossum534972b1999-02-03 17:20:50 +0000131 if index == -1:
132 index = len(p)
133 return p[:index], p[index:]
Guido van Rossum15e22e11997-12-05 19:03:01 +0000134 return '', p
Guido van Rossum555915a1994-02-24 11:32:59 +0000135
136
137# Split a path in head (everything up to the last '/') and tail (the
Guido van Rossum8f0fa9e1999-03-19 21:05:12 +0000138# rest). After the trailing '/' is stripped, the invariant
Guido van Rossum555915a1994-02-24 11:32:59 +0000139# join(head, tail) == p holds.
140# The resulting head won't end in '/' unless it is the root.
141
142def split(p):
Guido van Rossum534972b1999-02-03 17:20:50 +0000143 """Split a pathname.
144
145 Return tuple (head, tail) where tail is everything after the final slash.
146 Either part may be empty."""
Guido van Rossum8f0fa9e1999-03-19 21:05:12 +0000147
Guido van Rossum15e22e11997-12-05 19:03:01 +0000148 d, p = splitdrive(p)
Guido van Rossum8f0fa9e1999-03-19 21:05:12 +0000149 # set i to index beyond p's last slash
150 i = len(p)
151 while i and p[i-1] not in '/\\':
152 i = i - 1
153 head, tail = p[:i], p[i:] # now tail has no slashes
154 # remove trailing slashes from head, unless it's all slashes
155 head2 = head
156 while head2 and head2[-1] in '/\\':
157 head2 = head2[:-1]
158 head = head2 or head
Guido van Rossum15e22e11997-12-05 19:03:01 +0000159 return d + head, tail
Guido van Rossum555915a1994-02-24 11:32:59 +0000160
161
162# Split a path in root and extension.
Guido van Rossum73e122f1997-01-22 00:17:26 +0000163# The extension is everything starting at the last dot in the last
Guido van Rossum555915a1994-02-24 11:32:59 +0000164# pathname component; the root is everything before that.
165# It is always true that root + ext == p.
166
167def splitext(p):
Guido van Rossum534972b1999-02-03 17:20:50 +0000168 """Split the extension from a pathname.
169
170 Extension is everything from the last dot to the end.
171 Return (root, ext), either part may be empty."""
Guido van Rossum15e22e11997-12-05 19:03:01 +0000172 root, ext = '', ''
173 for c in p:
174 if c in ['/','\\']:
175 root, ext = root + ext + c, ''
176 elif c == '.':
177 if ext:
178 root, ext = root + ext, c
179 else:
180 ext = c
181 elif ext:
182 ext = ext + c
183 else:
184 root = root + c
185 return root, ext
Guido van Rossum555915a1994-02-24 11:32:59 +0000186
187
188# Return the tail (basename) part of a path.
189
190def basename(p):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000191 """Returns the final component of a pathname"""
192 return split(p)[1]
Guido van Rossum555915a1994-02-24 11:32:59 +0000193
194
195# Return the head (dirname) part of a path.
196
197def dirname(p):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000198 """Returns the directory component of a pathname"""
199 return split(p)[0]
Guido van Rossum555915a1994-02-24 11:32:59 +0000200
201
202# Return the longest prefix of all list elements.
203
204def commonprefix(m):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000205 "Given a list of pathnames, returns the longest common leading component"
206 if not m: return ''
Skip Montanaro62358312000-08-22 13:01:53 +0000207 prefix = m[0]
208 for item in m:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000209 for i in range(len(prefix)):
Fred Drake8152d322000-12-12 23:20:45 +0000210 if prefix[:i+1] != item[:i+1]:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000211 prefix = prefix[:i]
212 if i == 0: return ''
213 break
Skip Montanaro62358312000-08-22 13:01:53 +0000214 return prefix
Guido van Rossum555915a1994-02-24 11:32:59 +0000215
216
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000217# Get size, mtime, atime of files.
218
219def getsize(filename):
Guido van Rossum534972b1999-02-03 17:20:50 +0000220 """Return the size of a file, reported by os.stat()"""
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000221 return os.stat(filename).st_size
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000222
223def getmtime(filename):
Guido van Rossum534972b1999-02-03 17:20:50 +0000224 """Return the last modification time of a file, reported by os.stat()"""
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000225 return os.stat(filename).st_mtime
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000226
227def getatime(filename):
Guido van Rossum534972b1999-02-03 17:20:50 +0000228 """Return the last access time of a file, reported by os.stat()"""
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000229 return os.stat(filename).st_atime
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000230
231
Guido van Rossum555915a1994-02-24 11:32:59 +0000232# Is a path a symbolic link?
233# This will always return false on systems where posix.lstat doesn't exist.
234
235def islink(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000236 """Test for symbolic link. On WindowsNT/95 always returns false"""
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000237 return False
Guido van Rossum555915a1994-02-24 11:32:59 +0000238
239
240# Does a path exist?
241# This is false for dangling symbolic links.
242
243def exists(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000244 """Test whether a path exists"""
245 try:
246 st = os.stat(path)
247 except os.error:
Tim Petersbc0e9102002-04-04 22:55:58 +0000248 return False
249 return True
Guido van Rossum555915a1994-02-24 11:32:59 +0000250
251
252# Is a path a dos directory?
253# This follows symbolic links, so both islink() and isdir() can be true
254# for the same path.
255
256def isdir(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000257 """Test whether a path is a directory"""
258 try:
259 st = os.stat(path)
260 except os.error:
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000261 return False
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000262 return stat.S_ISDIR(st.st_mode)
Guido van Rossum555915a1994-02-24 11:32:59 +0000263
264
265# Is a path a regular file?
266# This follows symbolic links, so both islink() and isdir() can be true
267# for the same path.
268
269def isfile(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000270 """Test whether a path is a regular file"""
271 try:
272 st = os.stat(path)
273 except os.error:
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000274 return False
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000275 return stat.S_ISREG(st.st_mode)
Guido van Rossum555915a1994-02-24 11:32:59 +0000276
277
Guido van Rossumf3c695c1999-04-06 19:32:19 +0000278# Is a path a mount point? Either a root (with or without drive letter)
279# or an UNC path with at most a / or \ after the mount point.
Guido van Rossum555915a1994-02-24 11:32:59 +0000280
281def ismount(path):
Guido van Rossumca99c2c1998-01-19 22:25:59 +0000282 """Test whether a path is a mount point (defined as root of drive)"""
Guido van Rossumf3c695c1999-04-06 19:32:19 +0000283 unc, rest = splitunc(path)
284 if unc:
285 return rest in ("", "/", "\\")
Guido van Rossumca99c2c1998-01-19 22:25:59 +0000286 p = splitdrive(path)[1]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000287 return len(p) == 1 and p[0] in '/\\'
Guido van Rossum555915a1994-02-24 11:32:59 +0000288
289
290# Directory tree walk.
291# For each directory under top (including top itself, but excluding
292# '.' and '..'), func(arg, dirname, filenames) is called, where
293# dirname is the name of the directory and filenames is the list
294# files files (and subdirectories etc.) in the directory.
295# The func may modify the filenames list, to implement a filter,
296# or to impose a different order of visiting.
297
298def walk(top, func, arg):
Tim Peterscf5e6a42001-10-10 04:16:20 +0000299 """Directory tree walk with callback function.
Guido van Rossum534972b1999-02-03 17:20:50 +0000300
Tim Peterscf5e6a42001-10-10 04:16:20 +0000301 For each directory in the directory tree rooted at top (including top
302 itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
303 dirname is the name of the directory, and fnames a list of the names of
304 the files and subdirectories in dirname (excluding '.' and '..'). func
305 may modify the fnames list in-place (e.g. via del or slice assignment),
306 and walk will only recurse into the subdirectories whose names remain in
307 fnames; this can be used to implement a filter, or to impose a specific
308 order of visiting. No semantics are defined for, or required of, arg,
309 beyond that arg is always passed to func. It can be used, e.g., to pass
310 a filename pattern, or a mutable object designed to accumulate
311 statistics. Passing None for arg is common."""
312
Guido van Rossum15e22e11997-12-05 19:03:01 +0000313 try:
314 names = os.listdir(top)
315 except os.error:
316 return
317 func(arg, top, names)
318 exceptions = ('.', '..')
319 for name in names:
320 if name not in exceptions:
321 name = join(top, name)
322 if isdir(name):
323 walk(name, func, arg)
Guido van Rossum555915a1994-02-24 11:32:59 +0000324
325
326# Expand paths beginning with '~' or '~user'.
327# '~' means $HOME; '~user' means that user's home directory.
328# If the path doesn't begin with '~', or if the user or $HOME is unknown,
329# the path is returned unchanged (leaving error reporting to whatever
330# function is called with the expanded path as argument).
331# See also module 'glob' for expansion of *, ? and [...] in pathnames.
332# (A function should also be defined to do full *sh-style environment
333# variable expansion.)
334
335def expanduser(path):
Guido van Rossum534972b1999-02-03 17:20:50 +0000336 """Expand ~ and ~user constructs.
337
338 If user or $HOME is unknown, do nothing."""
Fred Drake8152d322000-12-12 23:20:45 +0000339 if path[:1] != '~':
Guido van Rossum15e22e11997-12-05 19:03:01 +0000340 return path
341 i, n = 1, len(path)
342 while i < n and path[i] not in '/\\':
Fred Drakeb4e460a2000-09-28 16:25:20 +0000343 i = i + 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000344 if i == 1:
Raymond Hettinger54f02222002-06-01 14:18:47 +0000345 if 'HOME' in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000346 userhome = os.environ['HOME']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000347 elif not 'HOMEPATH' in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000348 return path
349 else:
350 try:
Fred Drakeb4e460a2000-09-28 16:25:20 +0000351 drive = os.environ['HOMEDRIVE']
Guido van Rossum15e22e11997-12-05 19:03:01 +0000352 except KeyError:
353 drive = ''
354 userhome = join(drive, os.environ['HOMEPATH'])
355 else:
356 return path
357 return userhome + path[i:]
Guido van Rossum555915a1994-02-24 11:32:59 +0000358
359
360# Expand paths containing shell variable substitutions.
361# The following rules apply:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000362# - no expansion within single quotes
363# - no escape character, except for '$$' which is translated into '$'
364# - ${varname} is accepted.
365# - varnames can be made out of letters, digits and the character '_'
Guido van Rossum555915a1994-02-24 11:32:59 +0000366# XXX With COMMAND.COM you can use any characters in a variable name,
367# XXX except '^|<>='.
368
Tim Peters2344fae2001-01-15 00:50:52 +0000369def expandvars(path):
Guido van Rossum534972b1999-02-03 17:20:50 +0000370 """Expand shell variables of form $var and ${var}.
371
372 Unknown variables are left unchanged."""
Guido van Rossum15e22e11997-12-05 19:03:01 +0000373 if '$' not in path:
374 return path
Fred Drakeb4e460a2000-09-28 16:25:20 +0000375 import string
Fred Drake79e75e12001-07-20 19:05:50 +0000376 varchars = string.ascii_letters + string.digits + '_-'
Guido van Rossum15e22e11997-12-05 19:03:01 +0000377 res = ''
378 index = 0
379 pathlen = len(path)
380 while index < pathlen:
381 c = path[index]
382 if c == '\'': # no expansion within single quotes
383 path = path[index + 1:]
384 pathlen = len(path)
385 try:
Fred Drakeb4e460a2000-09-28 16:25:20 +0000386 index = path.index('\'')
Guido van Rossum15e22e11997-12-05 19:03:01 +0000387 res = res + '\'' + path[:index + 1]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000388 except ValueError:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000389 res = res + path
Fred Drakeb4e460a2000-09-28 16:25:20 +0000390 index = pathlen - 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000391 elif c == '$': # variable or '$$'
392 if path[index + 1:index + 2] == '$':
393 res = res + c
394 index = index + 1
395 elif path[index + 1:index + 2] == '{':
396 path = path[index+2:]
397 pathlen = len(path)
398 try:
Fred Drakeb4e460a2000-09-28 16:25:20 +0000399 index = path.index('}')
Guido van Rossum15e22e11997-12-05 19:03:01 +0000400 var = path[:index]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000401 if var in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000402 res = res + os.environ[var]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000403 except ValueError:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000404 res = res + path
405 index = pathlen - 1
406 else:
407 var = ''
408 index = index + 1
409 c = path[index:index + 1]
410 while c != '' and c in varchars:
411 var = var + c
412 index = index + 1
413 c = path[index:index + 1]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000414 if var in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000415 res = res + os.environ[var]
416 if c != '':
417 res = res + c
418 else:
419 res = res + c
420 index = index + 1
421 return res
Guido van Rossum555915a1994-02-24 11:32:59 +0000422
423
Tim Peters54a14a32001-08-30 22:05:26 +0000424# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
Guido van Rossum3df7b5a1996-08-26 16:35:26 +0000425# Previously, this function also truncated pathnames to 8+3 format,
426# but as this module is called "ntpath", that's obviously wrong!
Guido van Rossum555915a1994-02-24 11:32:59 +0000427
428def normpath(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000429 """Normalize path, eliminating double slashes, etc."""
Fred Drakeb4e460a2000-09-28 16:25:20 +0000430 path = path.replace("/", "\\")
Guido van Rossum15e22e11997-12-05 19:03:01 +0000431 prefix, path = splitdrive(path)
Fred Drakeb4e460a2000-09-28 16:25:20 +0000432 while path[:1] == "\\":
433 prefix = prefix + "\\"
Guido van Rossum15e22e11997-12-05 19:03:01 +0000434 path = path[1:]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000435 comps = path.split("\\")
Guido van Rossum15e22e11997-12-05 19:03:01 +0000436 i = 0
437 while i < len(comps):
Tim Peters54a14a32001-08-30 22:05:26 +0000438 if comps[i] in ('.', ''):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000439 del comps[i]
Tim Peters54a14a32001-08-30 22:05:26 +0000440 elif comps[i] == '..':
441 if i > 0 and comps[i-1] != '..':
442 del comps[i-1:i+1]
443 i -= 1
444 elif i == 0 and prefix.endswith("\\"):
445 del comps[i]
446 else:
447 i += 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000448 else:
Tim Peters54a14a32001-08-30 22:05:26 +0000449 i += 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000450 # If the path is now empty, substitute '.'
451 if not prefix and not comps:
452 comps.append('.')
Fred Drakeb4e460a2000-09-28 16:25:20 +0000453 return prefix + "\\".join(comps)
Guido van Rossume294cf61999-01-29 18:05:18 +0000454
455
456# Return an absolute path.
457def abspath(path):
Guido van Rossum534972b1999-02-03 17:20:50 +0000458 """Return the absolute version of a path"""
Mark Hammondf717f052002-01-17 00:44:26 +0000459 try:
Mark Hammondef8b6542001-05-13 08:04:26 +0000460 from nt import _getfullpathname
Mark Hammondf717f052002-01-17 00:44:26 +0000461 except ImportError: # Not running on Windows - mock up something sensible.
462 global abspath
463 def _abspath(path):
464 if not isabs(path):
465 path = join(os.getcwd(), path)
466 return normpath(path)
467 abspath = _abspath
468 return _abspath(path)
469
470 if path: # Empty path must return current working directory.
Mark Hammond647d2fe2000-08-14 06:20:32 +0000471 try:
Mark Hammondef8b6542001-05-13 08:04:26 +0000472 path = _getfullpathname(path)
473 except WindowsError:
Fred Drakeda05e972001-05-15 15:23:01 +0000474 pass # Bad path - return unchanged.
Mark Hammond647d2fe2000-08-14 06:20:32 +0000475 else:
476 path = os.getcwd()
Guido van Rossum6dfc7921999-11-30 15:00:00 +0000477 return normpath(path)
Guido van Rossum83eeef42001-09-17 15:16:09 +0000478
479# realpath is a no-op on systems without islink support
480realpath = abspath
Mark Hammond8696ebc2002-10-08 02:44:31 +0000481# Win9x family and earlier have no Unicode filename support.
Tim Peters26bc25a2002-10-09 07:56:04 +0000482supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
483 sys.getwindowsversion()[3] >= 2)