blob: d376065a2376e4dede32c94d6d174850901810cd [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
Skip Montanaro4d5d5bf2000-07-13 01:01:03 +000010
Skip Montanaro269b83b2001-02-06 01:07:02 +000011__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
12 "basename","dirname","commonprefix","getsize","getmtime",
13 "getatime","islink","exists","isdir","isfile","ismount",
14 "walk","expanduser","expandvars","normpath","abspath","splitunc"]
Guido van Rossum555915a1994-02-24 11:32:59 +000015
Guido van Rossume2ad88c1997-08-12 14:46:58 +000016# Normalize the case of a pathname and map slashes to backslashes.
17# Other normalizations (such as optimizing '../' away) are not done
Guido van Rossum555915a1994-02-24 11:32:59 +000018# (this is done by normpath).
Guido van Rossume2ad88c1997-08-12 14:46:58 +000019
Guido van Rossum555915a1994-02-24 11:32:59 +000020def normcase(s):
Guido van Rossum16a0bc21998-02-18 13:48:31 +000021 """Normalize case of pathname.
22
Guido van Rossum534972b1999-02-03 17:20:50 +000023 Makes all characters lowercase and all slashes into backslashes."""
Fred Drakeb4e460a2000-09-28 16:25:20 +000024 return s.replace("/", "\\").lower()
Guido van Rossum555915a1994-02-24 11:32:59 +000025
Guido van Rossum77e1db31997-06-02 23:11:57 +000026
Fred Drakeef0b5dd2000-02-17 17:30:40 +000027# Return whether a path is absolute.
Guido van Rossum555915a1994-02-24 11:32:59 +000028# Trivial in Posix, harder on the Mac or MS-DOS.
29# For DOS it is absolute if it starts with a slash or backslash (current
Guido van Rossum534972b1999-02-03 17:20:50 +000030# volume), or if a pathname after the volume letter and colon / UNC resource
31# starts with a slash or backslash.
Guido van Rossum555915a1994-02-24 11:32:59 +000032
33def isabs(s):
Guido van Rossum15e22e11997-12-05 19:03:01 +000034 """Test whether a path is absolute"""
35 s = splitdrive(s)[1]
36 return s != '' and s[:1] in '/\\'
Guido van Rossum555915a1994-02-24 11:32:59 +000037
38
Guido van Rossum77e1db31997-06-02 23:11:57 +000039# Join two (or more) paths.
40
Barry Warsaw384d2491997-02-18 21:53:25 +000041def join(a, *p):
Guido van Rossum15e22e11997-12-05 19:03:01 +000042 """Join two or more pathname components, inserting "\\" as needed"""
43 path = a
44 for b in p:
Tim Peters33dc0a12001-07-27 08:09:54 +000045 b_wins = 0 # set to 1 iff b makes path irrelevant
46 if path == "":
47 b_wins = 1
Tim Peters1bdd0f22001-07-19 17:18:18 +000048
Tim Peters33dc0a12001-07-27 08:09:54 +000049 elif isabs(b):
50 # This probably wipes out path so far. However, it's more
51 # complicated if path begins with a drive letter:
52 # 1. join('c:', '/a') == 'c:/a'
53 # 2. join('c:/', '/a') == 'c:/a'
54 # But
55 # 3. join('c:/a', '/b') == '/b'
56 # 4. join('c:', 'd:/') = 'd:/'
57 # 5. join('c:/', 'd:/') = 'd:/'
58 if path[1:2] != ":" or b[1:2] == ":":
59 # Path doesn't start with a drive letter, or cases 4 and 5.
60 b_wins = 1
Tim Peters1bdd0f22001-07-19 17:18:18 +000061
Tim Peters33dc0a12001-07-27 08:09:54 +000062 # Else path has a drive letter, and b doesn't but is absolute.
63 elif len(path) > 3 or (len(path) == 3 and
64 path[-1] not in "/\\"):
65 # case 3
66 b_wins = 1
Tim Peters1bdd0f22001-07-19 17:18:18 +000067
Tim Peters33dc0a12001-07-27 08:09:54 +000068 if b_wins:
69 path = b
70 else:
71 # Join, and ensure there's a separator.
72 assert len(path) > 0
73 if path[-1] in "/\\":
74 if b and b[0] in "/\\":
75 path += b[1:]
76 else:
77 path += b
78 elif path[-1] == ":":
79 path += b
80 elif b:
81 if b[0] in "/\\":
82 path += b
83 else:
84 path += "\\" + b
Tim Peters6a3e5f12001-11-05 21:25:02 +000085 else:
86 # path is not empty and does not end with a backslash,
87 # but b is empty; since, e.g., split('a/') produces
88 # ('a', ''), it's best if join() adds a backslash in
89 # this case.
90 path += '\\'
Tim Peters1bdd0f22001-07-19 17:18:18 +000091
Guido van Rossum15e22e11997-12-05 19:03:01 +000092 return path
Guido van Rossum555915a1994-02-24 11:32:59 +000093
94
95# Split a path in a drive specification (a drive letter followed by a
Guido van Rossumf3c695c1999-04-06 19:32:19 +000096# colon) and the path specification.
Guido van Rossum555915a1994-02-24 11:32:59 +000097# It is always true that drivespec + pathspec == p
98def splitdrive(p):
Guido van Rossumf3c695c1999-04-06 19:32:19 +000099 """Split a pathname into drive and path specifiers. Returns a 2-tuple
100"(drive,path)"; either part may be empty"""
Guido van Rossum15e22e11997-12-05 19:03:01 +0000101 if p[1:2] == ':':
102 return p[0:2], p[2:]
Guido van Rossumf3c695c1999-04-06 19:32:19 +0000103 return '', p
104
105
106# Parse UNC paths
107def splitunc(p):
108 """Split a pathname into UNC mount point and relative path specifiers.
109
110 Return a 2-tuple (unc, rest); either part may be empty.
111 If unc is not empty, it has the form '//host/mount' (or similar
112 using backslashes). unc+rest is always the input path.
113 Paths containing drive letters never have an UNC part.
114 """
115 if p[1:2] == ':':
116 return '', p # Drive letter present
Guido van Rossum534972b1999-02-03 17:20:50 +0000117 firstTwo = p[0:2]
118 if firstTwo == '//' or firstTwo == '\\\\':
119 # is a UNC path:
120 # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
121 # \\machine\mountpoint\directories...
122 # directory ^^^^^^^^^^^^^^^
123 normp = normcase(p)
Fred Drakeb4e460a2000-09-28 16:25:20 +0000124 index = normp.find('\\', 2)
Guido van Rossum534972b1999-02-03 17:20:50 +0000125 if index == -1:
126 ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
127 return ("", p)
Fred Drakeb4e460a2000-09-28 16:25:20 +0000128 index = normp.find('\\', index + 1)
Guido van Rossum534972b1999-02-03 17:20:50 +0000129 if index == -1:
130 index = len(p)
131 return p[:index], p[index:]
Guido van Rossum15e22e11997-12-05 19:03:01 +0000132 return '', p
Guido van Rossum555915a1994-02-24 11:32:59 +0000133
134
135# Split a path in head (everything up to the last '/') and tail (the
Guido van Rossum8f0fa9e1999-03-19 21:05:12 +0000136# rest). After the trailing '/' is stripped, the invariant
Guido van Rossum555915a1994-02-24 11:32:59 +0000137# join(head, tail) == p holds.
138# The resulting head won't end in '/' unless it is the root.
139
140def split(p):
Guido van Rossum534972b1999-02-03 17:20:50 +0000141 """Split a pathname.
142
143 Return tuple (head, tail) where tail is everything after the final slash.
144 Either part may be empty."""
Guido van Rossum8f0fa9e1999-03-19 21:05:12 +0000145
Guido van Rossum15e22e11997-12-05 19:03:01 +0000146 d, p = splitdrive(p)
Guido van Rossum8f0fa9e1999-03-19 21:05:12 +0000147 # set i to index beyond p's last slash
148 i = len(p)
149 while i and p[i-1] not in '/\\':
150 i = i - 1
151 head, tail = p[:i], p[i:] # now tail has no slashes
152 # remove trailing slashes from head, unless it's all slashes
153 head2 = head
154 while head2 and head2[-1] in '/\\':
155 head2 = head2[:-1]
156 head = head2 or head
Guido van Rossum15e22e11997-12-05 19:03:01 +0000157 return d + head, tail
Guido van Rossum555915a1994-02-24 11:32:59 +0000158
159
160# Split a path in root and extension.
Guido van Rossum73e122f1997-01-22 00:17:26 +0000161# The extension is everything starting at the last dot in the last
Guido van Rossum555915a1994-02-24 11:32:59 +0000162# pathname component; the root is everything before that.
163# It is always true that root + ext == p.
164
165def splitext(p):
Guido van Rossum534972b1999-02-03 17:20:50 +0000166 """Split the extension from a pathname.
167
168 Extension is everything from the last dot to the end.
169 Return (root, ext), either part may be empty."""
Guido van Rossum15e22e11997-12-05 19:03:01 +0000170 root, ext = '', ''
171 for c in p:
172 if c in ['/','\\']:
173 root, ext = root + ext + c, ''
174 elif c == '.':
175 if ext:
176 root, ext = root + ext, c
177 else:
178 ext = c
179 elif ext:
180 ext = ext + c
181 else:
182 root = root + c
183 return root, ext
Guido van Rossum555915a1994-02-24 11:32:59 +0000184
185
186# Return the tail (basename) part of a path.
187
188def basename(p):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000189 """Returns the final component of a pathname"""
190 return split(p)[1]
Guido van Rossum555915a1994-02-24 11:32:59 +0000191
192
193# Return the head (dirname) part of a path.
194
195def dirname(p):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000196 """Returns the directory component of a pathname"""
197 return split(p)[0]
Guido van Rossum555915a1994-02-24 11:32:59 +0000198
199
200# Return the longest prefix of all list elements.
201
202def commonprefix(m):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000203 "Given a list of pathnames, returns the longest common leading component"
204 if not m: return ''
Skip Montanaro62358312000-08-22 13:01:53 +0000205 prefix = m[0]
206 for item in m:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000207 for i in range(len(prefix)):
Fred Drake8152d322000-12-12 23:20:45 +0000208 if prefix[:i+1] != item[:i+1]:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000209 prefix = prefix[:i]
210 if i == 0: return ''
211 break
Skip Montanaro62358312000-08-22 13:01:53 +0000212 return prefix
Guido van Rossum555915a1994-02-24 11:32:59 +0000213
214
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000215# Get size, mtime, atime of files.
216
217def getsize(filename):
Guido van Rossum534972b1999-02-03 17:20:50 +0000218 """Return the size of a file, reported by os.stat()"""
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000219 return os.stat(filename).st_size
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000220
221def getmtime(filename):
Guido van Rossum534972b1999-02-03 17:20:50 +0000222 """Return the last modification time of a file, reported by os.stat()"""
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000223 return os.stat(filename).st_mtime
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000224
225def getatime(filename):
Guido van Rossum534972b1999-02-03 17:20:50 +0000226 """Return the last access time of a file, reported by os.stat()"""
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000227 return os.stat(filename).st_atime
Guido van Rossum2bc1f8f1998-07-24 20:49:26 +0000228
229
Guido van Rossum555915a1994-02-24 11:32:59 +0000230# Is a path a symbolic link?
231# This will always return false on systems where posix.lstat doesn't exist.
232
233def islink(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000234 """Test for symbolic link. On WindowsNT/95 always returns false"""
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000235 return False
Guido van Rossum555915a1994-02-24 11:32:59 +0000236
237
238# Does a path exist?
239# This is false for dangling symbolic links.
240
241def exists(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000242 """Test whether a path exists"""
243 try:
244 st = os.stat(path)
245 except os.error:
Tim Petersbc0e9102002-04-04 22:55:58 +0000246 return False
247 return True
Guido van Rossum555915a1994-02-24 11:32:59 +0000248
249
250# Is a path a dos directory?
251# This follows symbolic links, so both islink() and isdir() can be true
252# for the same path.
253
254def isdir(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000255 """Test whether a path is a directory"""
256 try:
257 st = os.stat(path)
258 except os.error:
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000259 return False
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000260 return stat.S_ISDIR(st.st_mode)
Guido van Rossum555915a1994-02-24 11:32:59 +0000261
262
263# Is a path a regular file?
264# This follows symbolic links, so both islink() and isdir() can be true
265# for the same path.
266
267def isfile(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000268 """Test whether a path is a regular file"""
269 try:
270 st = os.stat(path)
271 except os.error:
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000272 return False
Raymond Hettinger32200ae2002-06-01 19:51:15 +0000273 return stat.S_ISREG(st.st_mode)
Guido van Rossum555915a1994-02-24 11:32:59 +0000274
275
Guido van Rossumf3c695c1999-04-06 19:32:19 +0000276# Is a path a mount point? Either a root (with or without drive letter)
277# or an UNC path with at most a / or \ after the mount point.
Guido van Rossum555915a1994-02-24 11:32:59 +0000278
279def ismount(path):
Guido van Rossumca99c2c1998-01-19 22:25:59 +0000280 """Test whether a path is a mount point (defined as root of drive)"""
Guido van Rossumf3c695c1999-04-06 19:32:19 +0000281 unc, rest = splitunc(path)
282 if unc:
283 return rest in ("", "/", "\\")
Guido van Rossumca99c2c1998-01-19 22:25:59 +0000284 p = splitdrive(path)[1]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000285 return len(p) == 1 and p[0] in '/\\'
Guido van Rossum555915a1994-02-24 11:32:59 +0000286
287
288# Directory tree walk.
289# For each directory under top (including top itself, but excluding
290# '.' and '..'), func(arg, dirname, filenames) is called, where
291# dirname is the name of the directory and filenames is the list
292# files files (and subdirectories etc.) in the directory.
293# The func may modify the filenames list, to implement a filter,
294# or to impose a different order of visiting.
295
296def walk(top, func, arg):
Tim Peterscf5e6a42001-10-10 04:16:20 +0000297 """Directory tree walk with callback function.
Guido van Rossum534972b1999-02-03 17:20:50 +0000298
Tim Peterscf5e6a42001-10-10 04:16:20 +0000299 For each directory in the directory tree rooted at top (including top
300 itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
301 dirname is the name of the directory, and fnames a list of the names of
302 the files and subdirectories in dirname (excluding '.' and '..'). func
303 may modify the fnames list in-place (e.g. via del or slice assignment),
304 and walk will only recurse into the subdirectories whose names remain in
305 fnames; this can be used to implement a filter, or to impose a specific
306 order of visiting. No semantics are defined for, or required of, arg,
307 beyond that arg is always passed to func. It can be used, e.g., to pass
308 a filename pattern, or a mutable object designed to accumulate
309 statistics. Passing None for arg is common."""
310
Guido van Rossum15e22e11997-12-05 19:03:01 +0000311 try:
312 names = os.listdir(top)
313 except os.error:
314 return
315 func(arg, top, names)
316 exceptions = ('.', '..')
317 for name in names:
318 if name not in exceptions:
319 name = join(top, name)
320 if isdir(name):
321 walk(name, func, arg)
Guido van Rossum555915a1994-02-24 11:32:59 +0000322
323
324# Expand paths beginning with '~' or '~user'.
325# '~' means $HOME; '~user' means that user's home directory.
326# If the path doesn't begin with '~', or if the user or $HOME is unknown,
327# the path is returned unchanged (leaving error reporting to whatever
328# function is called with the expanded path as argument).
329# See also module 'glob' for expansion of *, ? and [...] in pathnames.
330# (A function should also be defined to do full *sh-style environment
331# variable expansion.)
332
333def expanduser(path):
Guido van Rossum534972b1999-02-03 17:20:50 +0000334 """Expand ~ and ~user constructs.
335
336 If user or $HOME is unknown, do nothing."""
Fred Drake8152d322000-12-12 23:20:45 +0000337 if path[:1] != '~':
Guido van Rossum15e22e11997-12-05 19:03:01 +0000338 return path
339 i, n = 1, len(path)
340 while i < n and path[i] not in '/\\':
Fred Drakeb4e460a2000-09-28 16:25:20 +0000341 i = i + 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000342 if i == 1:
Raymond Hettinger54f02222002-06-01 14:18:47 +0000343 if 'HOME' in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000344 userhome = os.environ['HOME']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000345 elif not 'HOMEPATH' in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000346 return path
347 else:
348 try:
Fred Drakeb4e460a2000-09-28 16:25:20 +0000349 drive = os.environ['HOMEDRIVE']
Guido van Rossum15e22e11997-12-05 19:03:01 +0000350 except KeyError:
351 drive = ''
352 userhome = join(drive, os.environ['HOMEPATH'])
353 else:
354 return path
355 return userhome + path[i:]
Guido van Rossum555915a1994-02-24 11:32:59 +0000356
357
358# Expand paths containing shell variable substitutions.
359# The following rules apply:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000360# - no expansion within single quotes
361# - no escape character, except for '$$' which is translated into '$'
362# - ${varname} is accepted.
363# - varnames can be made out of letters, digits and the character '_'
Guido van Rossum555915a1994-02-24 11:32:59 +0000364# XXX With COMMAND.COM you can use any characters in a variable name,
365# XXX except '^|<>='.
366
Tim Peters2344fae2001-01-15 00:50:52 +0000367def expandvars(path):
Guido van Rossum534972b1999-02-03 17:20:50 +0000368 """Expand shell variables of form $var and ${var}.
369
370 Unknown variables are left unchanged."""
Guido van Rossum15e22e11997-12-05 19:03:01 +0000371 if '$' not in path:
372 return path
Fred Drakeb4e460a2000-09-28 16:25:20 +0000373 import string
Fred Drake79e75e12001-07-20 19:05:50 +0000374 varchars = string.ascii_letters + string.digits + '_-'
Guido van Rossum15e22e11997-12-05 19:03:01 +0000375 res = ''
376 index = 0
377 pathlen = len(path)
378 while index < pathlen:
379 c = path[index]
380 if c == '\'': # no expansion within single quotes
381 path = path[index + 1:]
382 pathlen = len(path)
383 try:
Fred Drakeb4e460a2000-09-28 16:25:20 +0000384 index = path.index('\'')
Guido van Rossum15e22e11997-12-05 19:03:01 +0000385 res = res + '\'' + path[:index + 1]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000386 except ValueError:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000387 res = res + path
Fred Drakeb4e460a2000-09-28 16:25:20 +0000388 index = pathlen - 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000389 elif c == '$': # variable or '$$'
390 if path[index + 1:index + 2] == '$':
391 res = res + c
392 index = index + 1
393 elif path[index + 1:index + 2] == '{':
394 path = path[index+2:]
395 pathlen = len(path)
396 try:
Fred Drakeb4e460a2000-09-28 16:25:20 +0000397 index = path.index('}')
Guido van Rossum15e22e11997-12-05 19:03:01 +0000398 var = path[:index]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000399 if var in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000400 res = res + os.environ[var]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000401 except ValueError:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000402 res = res + path
403 index = pathlen - 1
404 else:
405 var = ''
406 index = index + 1
407 c = path[index:index + 1]
408 while c != '' and c in varchars:
409 var = var + c
410 index = index + 1
411 c = path[index:index + 1]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000412 if var in os.environ:
Guido van Rossum15e22e11997-12-05 19:03:01 +0000413 res = res + os.environ[var]
414 if c != '':
415 res = res + c
416 else:
417 res = res + c
418 index = index + 1
419 return res
Guido van Rossum555915a1994-02-24 11:32:59 +0000420
421
Tim Peters54a14a32001-08-30 22:05:26 +0000422# 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 +0000423# Previously, this function also truncated pathnames to 8+3 format,
424# but as this module is called "ntpath", that's obviously wrong!
Guido van Rossum555915a1994-02-24 11:32:59 +0000425
426def normpath(path):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000427 """Normalize path, eliminating double slashes, etc."""
Fred Drakeb4e460a2000-09-28 16:25:20 +0000428 path = path.replace("/", "\\")
Guido van Rossum15e22e11997-12-05 19:03:01 +0000429 prefix, path = splitdrive(path)
Fred Drakeb4e460a2000-09-28 16:25:20 +0000430 while path[:1] == "\\":
431 prefix = prefix + "\\"
Guido van Rossum15e22e11997-12-05 19:03:01 +0000432 path = path[1:]
Fred Drakeb4e460a2000-09-28 16:25:20 +0000433 comps = path.split("\\")
Guido van Rossum15e22e11997-12-05 19:03:01 +0000434 i = 0
435 while i < len(comps):
Tim Peters54a14a32001-08-30 22:05:26 +0000436 if comps[i] in ('.', ''):
Guido van Rossum15e22e11997-12-05 19:03:01 +0000437 del comps[i]
Tim Peters54a14a32001-08-30 22:05:26 +0000438 elif comps[i] == '..':
439 if i > 0 and comps[i-1] != '..':
440 del comps[i-1:i+1]
441 i -= 1
442 elif i == 0 and prefix.endswith("\\"):
443 del comps[i]
444 else:
445 i += 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000446 else:
Tim Peters54a14a32001-08-30 22:05:26 +0000447 i += 1
Guido van Rossum15e22e11997-12-05 19:03:01 +0000448 # If the path is now empty, substitute '.'
449 if not prefix and not comps:
450 comps.append('.')
Fred Drakeb4e460a2000-09-28 16:25:20 +0000451 return prefix + "\\".join(comps)
Guido van Rossume294cf61999-01-29 18:05:18 +0000452
453
454# Return an absolute path.
455def abspath(path):
Guido van Rossum534972b1999-02-03 17:20:50 +0000456 """Return the absolute version of a path"""
Mark Hammondf717f052002-01-17 00:44:26 +0000457 try:
Mark Hammondef8b6542001-05-13 08:04:26 +0000458 from nt import _getfullpathname
Mark Hammondf717f052002-01-17 00:44:26 +0000459 except ImportError: # Not running on Windows - mock up something sensible.
460 global abspath
461 def _abspath(path):
462 if not isabs(path):
463 path = join(os.getcwd(), path)
464 return normpath(path)
465 abspath = _abspath
466 return _abspath(path)
467
468 if path: # Empty path must return current working directory.
Mark Hammond647d2fe2000-08-14 06:20:32 +0000469 try:
Mark Hammondef8b6542001-05-13 08:04:26 +0000470 path = _getfullpathname(path)
471 except WindowsError:
Fred Drakeda05e972001-05-15 15:23:01 +0000472 pass # Bad path - return unchanged.
Mark Hammond647d2fe2000-08-14 06:20:32 +0000473 else:
474 path = os.getcwd()
Guido van Rossum6dfc7921999-11-30 15:00:00 +0000475 return normpath(path)
Guido van Rossum83eeef42001-09-17 15:16:09 +0000476
477# realpath is a no-op on systems without islink support
478realpath = abspath