1 """Common operations on Posix pathnames.
3 Instead of importing this module directly, import os and refer to
4 this module as os.path. The "os.path" name is an alias for this
5 module on Posix systems; on other systems (e.g. Mac, Windows),
6 os.path provides the same operations in a manner specific to that
7 platform, and is an alias to another module (e.g. macpath, ntpath).
9 Some of this can actually be useful on non-Posix systems too, e.g.
10 for manipulation of the pathname component of URLs.
16 __all__ = [
"normcase",
"isabs",
"join",
"splitdrive",
"split",
"splitext",
17 "basename",
"dirname",
"commonprefix",
"getsize",
"getmtime",
18 "getatime",
"islink",
"exists",
"isdir",
"isfile",
"ismount",
19 "walk",
"expanduser",
"expandvars",
"normpath",
"abspath",
20 "samefile",
"sameopenfile",
"samestat"]
28 """Normalize case of pathname. Has no effect under Posix"""
36 """Test whether a path is absolute"""
45 """Join two or more pathname components, inserting '/' as needed"""
50 elif path ==
'' or path[-1:] ==
'/':
63 """Split a pathname. Returns tuple "(head, tail)" where "tail" is
64 everything after the final slash. Either part may be empty."""
66 head, tail = p[:i], p[i:]
67 if head
and head !=
'/'*len(head):
68 while head[-1] ==
'/':
79 """Split the extension from a pathname. Extension is everything from the
80 last dot to the end. Returns "(root, ext)", either part may be empty."""
84 root, ext = root + ext + c,
''
87 root, ext = root + ext, c
101 """Split a pathname into drive and path. On Posix, drive is always
109 """Returns the final component of a pathname"""
116 """Returns the directory component of a pathname"""
123 "Given a list of pathnames, returns the longest common leading component"
127 for i
in range(len(prefix)):
128 if prefix[:i+1] != item[:i+1]:
138 """Return the size of a file, reported by os.stat()."""
139 st = os.stat(filename)
140 return st[stat.ST_SIZE]
143 """Return the last modification time of a file, reported by os.stat()."""
144 st = os.stat(filename)
145 return st[stat.ST_MTIME]
148 """Return the last access time of a file, reported by os.stat()."""
149 st = os.stat(filename)
150 return st[stat.ST_ATIME]
157 """Test whether a path is a symbolic link"""
160 except (os.error, AttributeError):
169 """Test whether a path exists. Returns false for broken symbolic links"""
182 """Test whether a path is a directory"""
195 """Test whether a path is a regular file"""
206 """Test whether two pathnames reference the same actual file"""
216 """Test whether two open file objects reference the same file"""
226 """Test whether two stat buffers reference the same file"""
227 return s1[stat.ST_INO] == s2[stat.ST_INO]
and \
228 s1[stat.ST_DEV] == s2[stat.ST_DEV]
235 """Test whether a path is a mount point"""
238 s2 = os.stat(
join(path,
'..'))
241 dev1 = s1[stat.ST_DEV]
242 dev2 = s2[stat.ST_DEV]
245 ino1 = s1[stat.ST_INO]
246 ino2 = s2[stat.ST_INO]
261 """Directory tree walk with callback function.
263 For each directory in the directory tree rooted at top (including top
264 itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
265 dirname is the name of the directory, and fnames a list of the names of
266 the files and subdirectories in dirname (excluding '.' and '..'). func
267 may modify the fnames list in-place (e.g. via del or slice assignment),
268 and walk will only recurse into the subdirectories whose names remain in
269 fnames; this can be used to implement a filter, or to impose a specific
270 order of visiting. No semantics are defined for, or required of, arg,
271 beyond that arg is always passed to func. It can be used, e.g., to pass
272 a filename pattern, or a mutable object designed to accumulate
273 statistics. Passing None for arg is common."""
276 names = os.listdir(top)
279 func(arg, top, names)
281 name =
join(top, name)
287 walk(name, func, arg)
300 """Expand ~ and ~user constructions. If user or $HOME is unknown,
305 while i < n
and path[i] !=
'/':
308 if not os.environ.has_key(
'HOME'):
310 userhome = os.environ[
'HOME']
314 pwent = pwd.getpwnam(path[1:i])
318 if userhome[-1:] ==
'/': i = i + 1
319 return userhome + path[i:]
329 """Expand shell variables of form $var and ${var}. Unknown variables
330 are left unchanged."""
336 _varprog = re.compile(
r'\$(\w+|\{[^}]*\})')
339 m = _varprog.search(path, i)
344 if name[:1] ==
'{' and name[-1:] ==
'}':
346 if os.environ.has_key(name):
348 path = path[:i] + os.environ[name]
361 """Normalize path, eliminating double slashes, etc."""
364 initial_slashes = path.startswith(
'/')
367 if (initial_slashes
and
368 path.startswith(
'//')
and not path.startswith(
'///')):
370 comps = path.split(
'/')
373 if comp
in (
'',
'.'):
375 if (comp !=
'..' or (
not initial_slashes
and not new_comps)
or
376 (new_comps
and new_comps[-1] ==
'..')):
377 new_comps.append(comp)
381 path =
'/'.
join(comps)
383 path =
'/'*initial_slashes + path
388 """Return an absolute path."""
390 path =
join(os.getcwd(), path)
398 """Return the canonical path of the specified filename, eliminating any
399 symbolic links encountered in the path."""
402 bits = [
'/'] + filename.split(
'/')[1:]
403 for i
in range(2, len(bits)+1):
404 component =
join(*bits[0:i])
406 resolved = os.readlink(component)
407 (dir, file) =
split(component)
409 newpath =
join(*([resolved] + bits[i:]))