root / tags / v1_0_2_Build_910 / extensions / extScripting / scripts / jython / Lib / ntpath.py @ 11275
History | View | Annotate | Download (12.6 KB)
1 |
# Module 'ntpath' -- common operations on WinNT/Win95 pathnames
|
---|---|
2 |
"""Common pathname manipulations, WindowsNT/95 version.
|
3 |
|
4 |
Instead of importing this module directly, import os and refer to this
|
5 |
module as os.path.
|
6 |
"""
|
7 |
|
8 |
import os |
9 |
import stat |
10 |
|
11 |
__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"] |
15 |
|
16 |
# Normalize the case of a pathname and map slashes to backslashes.
|
17 |
# Other normalizations (such as optimizing '../' away) are not done
|
18 |
# (this is done by normpath).
|
19 |
|
20 |
def normcase(s): |
21 |
"""Normalize case of pathname.
|
22 |
|
23 |
Makes all characters lowercase and all slashes into backslashes."""
|
24 |
return s.replace("/", "\\").lower() |
25 |
|
26 |
|
27 |
# Return whether a path is absolute.
|
28 |
# 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
|
30 |
# volume), or if a pathname after the volume letter and colon / UNC resource
|
31 |
# starts with a slash or backslash.
|
32 |
|
33 |
def isabs(s): |
34 |
"""Test whether a path is absolute"""
|
35 |
s = splitdrive(s)[1]
|
36 |
return s != '' and s[:1] in '/\\' |
37 |
|
38 |
|
39 |
# Join two (or more) paths.
|
40 |
|
41 |
def join(a, *p): |
42 |
"""Join two or more pathname components, inserting "\\" as needed"""
|
43 |
path = a |
44 |
for b in p: |
45 |
if isabs(b):
|
46 |
path = b |
47 |
elif path == '' or path[-1:] in '/\\:': |
48 |
path = path + b |
49 |
else:
|
50 |
path = path + "\\" + b
|
51 |
return path
|
52 |
|
53 |
|
54 |
# Split a path in a drive specification (a drive letter followed by a
|
55 |
# colon) and the path specification.
|
56 |
# It is always true that drivespec + pathspec == p
|
57 |
def splitdrive(p): |
58 |
"""Split a pathname into drive and path specifiers. Returns a 2-tuple
|
59 |
"(drive,path)"; either part may be empty"""
|
60 |
if p[1:2] == ':': |
61 |
return p[0:2], p[2:] |
62 |
return '', p |
63 |
|
64 |
|
65 |
# Parse UNC paths
|
66 |
def splitunc(p): |
67 |
"""Split a pathname into UNC mount point and relative path specifiers.
|
68 |
|
69 |
Return a 2-tuple (unc, rest); either part may be empty.
|
70 |
If unc is not empty, it has the form '//host/mount' (or similar
|
71 |
using backslashes). unc+rest is always the input path.
|
72 |
Paths containing drive letters never have an UNC part.
|
73 |
"""
|
74 |
if p[1:2] == ':': |
75 |
return '', p # Drive letter present |
76 |
firstTwo = p[0:2] |
77 |
if firstTwo == '//' or firstTwo == '\\\\': |
78 |
# is a UNC path:
|
79 |
# vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
|
80 |
# \\machine\mountpoint\directories...
|
81 |
# directory ^^^^^^^^^^^^^^^
|
82 |
normp = normcase(p) |
83 |
index = normp.find('\\', 2) |
84 |
if index == -1: |
85 |
##raise RuntimeError, 'illegal UNC path: "' + p + '"'
|
86 |
return ("", p) |
87 |
index = normp.find('\\', index + 1) |
88 |
if index == -1: |
89 |
index = len(p)
|
90 |
return p[:index], p[index:]
|
91 |
return '', p |
92 |
|
93 |
|
94 |
# Split a path in head (everything up to the last '/') and tail (the
|
95 |
# rest). After the trailing '/' is stripped, the invariant
|
96 |
# join(head, tail) == p holds.
|
97 |
# The resulting head won't end in '/' unless it is the root.
|
98 |
|
99 |
def split(p): |
100 |
"""Split a pathname.
|
101 |
|
102 |
Return tuple (head, tail) where tail is everything after the final slash.
|
103 |
Either part may be empty."""
|
104 |
|
105 |
d, p = splitdrive(p) |
106 |
# set i to index beyond p's last slash
|
107 |
i = len(p)
|
108 |
while i and p[i-1] not in '/\\': |
109 |
i = i - 1
|
110 |
head, tail = p[:i], p[i:] # now tail has no slashes
|
111 |
# remove trailing slashes from head, unless it's all slashes
|
112 |
head2 = head |
113 |
while head2 and head2[-1] in '/\\': |
114 |
head2 = head2[:-1]
|
115 |
head = head2 or head
|
116 |
return d + head, tail
|
117 |
|
118 |
|
119 |
# Split a path in root and extension.
|
120 |
# The extension is everything starting at the last dot in the last
|
121 |
# pathname component; the root is everything before that.
|
122 |
# It is always true that root + ext == p.
|
123 |
|
124 |
def splitext(p): |
125 |
"""Split the extension from a pathname.
|
126 |
|
127 |
Extension is everything from the last dot to the end.
|
128 |
Return (root, ext), either part may be empty."""
|
129 |
root, ext = '', '' |
130 |
for c in p: |
131 |
if c in ['/','\\']: |
132 |
root, ext = root + ext + c, ''
|
133 |
elif c == '.': |
134 |
if ext:
|
135 |
root, ext = root + ext, c |
136 |
else:
|
137 |
ext = c |
138 |
elif ext:
|
139 |
ext = ext + c |
140 |
else:
|
141 |
root = root + c |
142 |
return root, ext
|
143 |
|
144 |
|
145 |
# Return the tail (basename) part of a path.
|
146 |
|
147 |
def basename(p): |
148 |
"""Returns the final component of a pathname"""
|
149 |
return split(p)[1] |
150 |
|
151 |
|
152 |
# Return the head (dirname) part of a path.
|
153 |
|
154 |
def dirname(p): |
155 |
"""Returns the directory component of a pathname"""
|
156 |
return split(p)[0] |
157 |
|
158 |
|
159 |
# Return the longest prefix of all list elements.
|
160 |
|
161 |
def commonprefix(m): |
162 |
"Given a list of pathnames, returns the longest common leading component"
|
163 |
if not m: return '' |
164 |
prefix = m[0]
|
165 |
for item in m: |
166 |
for i in range(len(prefix)): |
167 |
if prefix[:i+1] != item[:i+1]: |
168 |
prefix = prefix[:i] |
169 |
if i == 0: return '' |
170 |
break
|
171 |
return prefix
|
172 |
|
173 |
|
174 |
# Get size, mtime, atime of files.
|
175 |
|
176 |
def getsize(filename): |
177 |
"""Return the size of a file, reported by os.stat()"""
|
178 |
st = os.stat(filename) |
179 |
return st[stat.ST_SIZE]
|
180 |
|
181 |
def getmtime(filename): |
182 |
"""Return the last modification time of a file, reported by os.stat()"""
|
183 |
st = os.stat(filename) |
184 |
return st[stat.ST_MTIME]
|
185 |
|
186 |
def getatime(filename): |
187 |
"""Return the last access time of a file, reported by os.stat()"""
|
188 |
st = os.stat(filename) |
189 |
return st[stat.ST_ATIME]
|
190 |
|
191 |
|
192 |
# Is a path a symbolic link?
|
193 |
# This will always return false on systems where posix.lstat doesn't exist.
|
194 |
|
195 |
def islink(path): |
196 |
"""Test for symbolic link. On WindowsNT/95 always returns false"""
|
197 |
return 0 |
198 |
|
199 |
|
200 |
# Does a path exist?
|
201 |
# This is false for dangling symbolic links.
|
202 |
|
203 |
def exists(path): |
204 |
"""Test whether a path exists"""
|
205 |
try:
|
206 |
st = os.stat(path) |
207 |
except os.error:
|
208 |
return 0 |
209 |
return 1 |
210 |
|
211 |
|
212 |
# Is a path a dos directory?
|
213 |
# This follows symbolic links, so both islink() and isdir() can be true
|
214 |
# for the same path.
|
215 |
|
216 |
def isdir(path): |
217 |
"""Test whether a path is a directory"""
|
218 |
try:
|
219 |
st = os.stat(path) |
220 |
except os.error:
|
221 |
return 0 |
222 |
return stat.S_ISDIR(st[stat.ST_MODE])
|
223 |
|
224 |
|
225 |
# Is a path a regular file?
|
226 |
# This follows symbolic links, so both islink() and isdir() can be true
|
227 |
# for the same path.
|
228 |
|
229 |
def isfile(path): |
230 |
"""Test whether a path is a regular file"""
|
231 |
try:
|
232 |
st = os.stat(path) |
233 |
except os.error:
|
234 |
return 0 |
235 |
return stat.S_ISREG(st[stat.ST_MODE])
|
236 |
|
237 |
|
238 |
# Is a path a mount point? Either a root (with or without drive letter)
|
239 |
# or an UNC path with at most a / or \ after the mount point.
|
240 |
|
241 |
def ismount(path): |
242 |
"""Test whether a path is a mount point (defined as root of drive)"""
|
243 |
unc, rest = splitunc(path) |
244 |
if unc:
|
245 |
return rest in ("", "/", "\\") |
246 |
p = splitdrive(path)[1]
|
247 |
return len(p) == 1 and p[0] in '/\\' |
248 |
|
249 |
|
250 |
# Directory tree walk.
|
251 |
# For each directory under top (including top itself, but excluding
|
252 |
# '.' and '..'), func(arg, dirname, filenames) is called, where
|
253 |
# dirname is the name of the directory and filenames is the list
|
254 |
# files files (and subdirectories etc.) in the directory.
|
255 |
# The func may modify the filenames list, to implement a filter,
|
256 |
# or to impose a different order of visiting.
|
257 |
|
258 |
def walk(top, func, arg): |
259 |
"""Directory tree walk whth callback function.
|
260 |
|
261 |
walk(top, func, arg) calls func(arg, d, files) for each directory d
|
262 |
in the tree rooted at top (including top itself); files is a list
|
263 |
of all the files and subdirs in directory d."""
|
264 |
try:
|
265 |
names = os.listdir(top) |
266 |
except os.error:
|
267 |
return
|
268 |
func(arg, top, names) |
269 |
exceptions = ('.', '..') |
270 |
for name in names: |
271 |
if name not in exceptions: |
272 |
name = join(top, name) |
273 |
if isdir(name):
|
274 |
walk(name, func, arg) |
275 |
|
276 |
|
277 |
# Expand paths beginning with '~' or '~user'.
|
278 |
# '~' means $HOME; '~user' means that user's home directory.
|
279 |
# If the path doesn't begin with '~', or if the user or $HOME is unknown,
|
280 |
# the path is returned unchanged (leaving error reporting to whatever
|
281 |
# function is called with the expanded path as argument).
|
282 |
# See also module 'glob' for expansion of *, ? and [...] in pathnames.
|
283 |
# (A function should also be defined to do full *sh-style environment
|
284 |
# variable expansion.)
|
285 |
|
286 |
def expanduser(path): |
287 |
"""Expand ~ and ~user constructs.
|
288 |
|
289 |
If user or $HOME is unknown, do nothing."""
|
290 |
if path[:1] != '~': |
291 |
return path
|
292 |
i, n = 1, len(path) |
293 |
while i < n and path[i] not in '/\\': |
294 |
i = i + 1
|
295 |
if i == 1: |
296 |
if os.environ.has_key('HOME'): |
297 |
userhome = os.environ['HOME']
|
298 |
elif not os.environ.has_key('HOMEPATH'): |
299 |
return path
|
300 |
else:
|
301 |
try:
|
302 |
drive = os.environ['HOMEDRIVE']
|
303 |
except KeyError: |
304 |
drive = ''
|
305 |
userhome = join(drive, os.environ['HOMEPATH'])
|
306 |
else:
|
307 |
return path
|
308 |
return userhome + path[i:]
|
309 |
|
310 |
|
311 |
# Expand paths containing shell variable substitutions.
|
312 |
# The following rules apply:
|
313 |
# - no expansion within single quotes
|
314 |
# - no escape character, except for '$$' which is translated into '$'
|
315 |
# - ${varname} is accepted.
|
316 |
# - varnames can be made out of letters, digits and the character '_'
|
317 |
# XXX With COMMAND.COM you can use any characters in a variable name,
|
318 |
# XXX except '^|<>='.
|
319 |
|
320 |
def expandvars(path): |
321 |
"""Expand shell variables of form $var and ${var}.
|
322 |
|
323 |
Unknown variables are left unchanged."""
|
324 |
if '$' not in path: |
325 |
return path
|
326 |
import string |
327 |
varchars = string.letters + string.digits + '_-'
|
328 |
res = ''
|
329 |
index = 0
|
330 |
pathlen = len(path)
|
331 |
while index < pathlen:
|
332 |
c = path[index] |
333 |
if c == '\'': # no expansion within single quotes |
334 |
path = path[index + 1:]
|
335 |
pathlen = len(path)
|
336 |
try:
|
337 |
index = path.index('\'')
|
338 |
res = res + '\'' + path[:index + 1] |
339 |
except ValueError: |
340 |
res = res + path |
341 |
index = pathlen - 1
|
342 |
elif c == '$': # variable or '$$' |
343 |
if path[index + 1:index + 2] == '$': |
344 |
res = res + c |
345 |
index = index + 1
|
346 |
elif path[index + 1:index + 2] == '{': |
347 |
path = path[index+2:]
|
348 |
pathlen = len(path)
|
349 |
try:
|
350 |
index = path.index('}')
|
351 |
var = path[:index] |
352 |
if os.environ.has_key(var):
|
353 |
res = res + os.environ[var] |
354 |
except ValueError: |
355 |
res = res + path |
356 |
index = pathlen - 1
|
357 |
else:
|
358 |
var = ''
|
359 |
index = index + 1
|
360 |
c = path[index:index + 1]
|
361 |
while c != '' and c in varchars: |
362 |
var = var + c |
363 |
index = index + 1
|
364 |
c = path[index:index + 1]
|
365 |
if os.environ.has_key(var):
|
366 |
res = res + os.environ[var] |
367 |
if c != '': |
368 |
res = res + c |
369 |
else:
|
370 |
res = res + c |
371 |
index = index + 1
|
372 |
return res
|
373 |
|
374 |
|
375 |
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
|
376 |
# Previously, this function also truncated pathnames to 8+3 format,
|
377 |
# but as this module is called "ntpath", that's obviously wrong!
|
378 |
|
379 |
def normpath(path): |
380 |
"""Normalize path, eliminating double slashes, etc."""
|
381 |
path = path.replace("/", "\\") |
382 |
prefix, path = splitdrive(path) |
383 |
while path[:1] == "\\": |
384 |
prefix = prefix + "\\"
|
385 |
path = path[1:]
|
386 |
comps = path.split("\\")
|
387 |
i = 0
|
388 |
while i < len(comps): |
389 |
if comps[i] == '.': |
390 |
del comps[i]
|
391 |
elif comps[i] == '..' and i > 0 and comps[i-1] not in ('', '..'): |
392 |
del comps[i-1:i+1] |
393 |
i = i - 1
|
394 |
elif comps[i] == '' and i > 0 and comps[i-1] != '': |
395 |
del comps[i]
|
396 |
else:
|
397 |
i = i + 1
|
398 |
# If the path is now empty, substitute '.'
|
399 |
if not prefix and not comps: |
400 |
comps.append('.')
|
401 |
return prefix + "\\".join(comps) |
402 |
|
403 |
|
404 |
# Return an absolute path.
|
405 |
def abspath(path): |
406 |
"""Return the absolute version of a path"""
|
407 |
try:
|
408 |
import win32api |
409 |
except ImportError: |
410 |
global abspath
|
411 |
def _abspath(path): |
412 |
if not isabs(path): |
413 |
path = join(os.getcwd(), path) |
414 |
return normpath(path)
|
415 |
abspath = _abspath |
416 |
return _abspath(path)
|
417 |
if path: # Empty path must return current working directory. |
418 |
try:
|
419 |
path = win32api.GetFullPathName(path) |
420 |
except win32api.error:
|
421 |
pass # Bad path - return unchanged. |
422 |
else:
|
423 |
path = os.getcwd() |
424 |
return normpath(path)
|