]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/ntpath.py
AppPkg/.../Python-2.7.10: AppPkg.dsc, pyconfig.h, PyMod-2.7.10
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / PyMod-2.7.10 / Lib / ntpath.py
1
2 # Module 'ntpath' -- common operations on WinNT/Win95 and UEFI pathnames.
3 #
4 # Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
5 # Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
6 # This program and the accompanying materials are licensed and made available under
7 # the terms and conditions of the BSD License that accompanies this distribution.
8 # The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14
15 """Common pathname manipulations, WindowsNT/95 and UEFI version.
16
17 Instead of importing this module directly, import os and refer to this
18 module as os.path.
19 """
20
21 import os
22 import sys
23 import stat
24 import genericpath
25 import warnings
26
27 from genericpath import *
28 from genericpath import _unicode
29
30 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
31 "basename","dirname","commonprefix","getsize","getmtime",
32 "getatime","getctime", "islink","exists","lexists","isdir","isfile",
33 "ismount","walk","expanduser","expandvars","normpath","abspath",
34 "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
35 "extsep","devnull","realpath","supports_unicode_filenames","relpath"]
36
37 # strings representing various path-related bits and pieces
38 curdir = '.'
39 pardir = '..'
40 extsep = '.'
41 sep = '\\'
42 pathsep = ';'
43 altsep = '/'
44 defpath = '.;C:\\bin'
45 if 'ce' in sys.builtin_module_names:
46 defpath = '\\Windows'
47 elif 'os2' in sys.builtin_module_names:
48 # OS/2 w/ VACPP
49 altsep = '/'
50 devnull = 'nul'
51
52 # Normalize the case of a pathname and map slashes to backslashes.
53 # Other normalizations (such as optimizing '../' away) are not done
54 # (this is done by normpath).
55
56 def normcase(s):
57 """Normalize case of pathname.
58
59 Makes all characters lowercase and all slashes into backslashes."""
60 return s.replace("/", "\\").lower()
61
62
63 # Return whether a path is absolute.
64 # Trivial in Posix, harder on the Mac or MS-DOS.
65 # For DOS it is absolute if it starts with a slash or backslash (current
66 # volume), or if a pathname after the volume letter and colon / UNC resource
67 # starts with a slash or backslash.
68
69 def isabs(s):
70 """Test whether a path is absolute"""
71 s = splitdrive(s)[1]
72 return s != '' and s[:1] in '/\\'
73
74
75 # Join two (or more) paths.
76 def join(path, *paths):
77 """Join two or more pathname components, inserting "\\" as needed."""
78 result_drive, result_path = splitdrive(path)
79 for p in paths:
80 p_drive, p_path = splitdrive(p)
81 if p_path and p_path[0] in '\\/':
82 # Second path is absolute
83 if p_drive or not result_drive:
84 result_drive = p_drive
85 result_path = p_path
86 continue
87 elif p_drive and p_drive != result_drive:
88 if p_drive.lower() != result_drive.lower():
89 # Different drives => ignore the first path entirely
90 result_drive = p_drive
91 result_path = p_path
92 continue
93 # Same drive in different case
94 result_drive = p_drive
95 # Second path is relative to the first
96 if result_path and result_path[-1] not in '\\/':
97 result_path = result_path + '\\'
98 result_path = result_path + p_path
99 ## add separator between UNC and non-absolute path
100 if (result_path and result_path[0] not in '\\/' and
101 result_drive and result_drive[-1:] != ':'):
102 return result_drive + sep + result_path
103 return result_drive + result_path
104
105
106 # Split a path in a drive specification (a drive letter followed by a
107 # colon) and the path specification.
108 # It is always true that drivespec + pathspec == p
109 # NOTE: for UEFI (and even Windows) you can have multiple characters to the left
110 # of the ':' for the device or drive spec. This is reflected in the modifications
111 # to splitdrive() and splitunc().
112 def splitdrive(p):
113 """Split a pathname into drive/UNC sharepoint and relative path specifiers.
114 Returns a 2-tuple (drive_or_unc, path); either part may be empty.
115
116 If you assign
117 result = splitdrive(p)
118 It is always true that:
119 result[0] + result[1] == p
120
121 If the path contained a drive letter, drive_or_unc will contain everything
122 up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir")
123
124 If the path contained a UNC path, the drive_or_unc will contain the host name
125 and share up to but not including the fourth directory separator character.
126 e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir")
127
128 Paths cannot contain both a drive letter and a UNC path.
129
130 """
131 if len(p) > 1:
132 normp = p.replace(altsep, sep)
133 if (normp[0:2] == sep*2) and (normp[2:3] != sep):
134 # is a UNC path:
135 # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
136 # \\machine\mountpoint\directory\etc\...
137 # directory ^^^^^^^^^^^^^^^
138 index = normp.find(sep, 2)
139 if index == -1:
140 return '', p
141 index2 = normp.find(sep, index + 1)
142 # a UNC path can't have two slashes in a row
143 # (after the initial two)
144 if index2 == index + 1:
145 return '', p
146 if index2 == -1:
147 index2 = len(p)
148 return p[:index2], p[index2:]
149 index = p.find(':')
150 if index != -1:
151 index = index + 1
152 return p[:index], p[index:]
153 return '', p
154
155 # Parse UNC paths
156 def splitunc(p):
157 """Split a pathname into UNC mount point and relative path specifiers.
158
159 Return a 2-tuple (unc, rest); either part may be empty.
160 If unc is not empty, it has the form '//host/mount' (or similar
161 using backslashes). unc+rest is always the input path.
162 Paths containing drive letters never have an UNC part.
163 """
164 if ':' in p:
165 return '', p # Drive letter or device name present
166 firstTwo = p[0:2]
167 if firstTwo == '//' or firstTwo == '\\\\':
168 # is a UNC path:
169 # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
170 # \\machine\mountpoint\directories...
171 # directory ^^^^^^^^^^^^^^^
172 normp = p.replace('\\', '/')
173 index = normp.find('/', 2)
174 if index <= 2:
175 return '', p
176 index2 = normp.find('/', index + 1)
177 # a UNC path can't have two slashes in a row
178 # (after the initial two)
179 if index2 == index + 1:
180 return '', p
181 if index2 == -1:
182 index2 = len(p)
183 return p[:index2], p[index2:]
184 return '', p
185
186
187 # Split a path in head (everything up to the last '/') and tail (the
188 # rest). After the trailing '/' is stripped, the invariant
189 # join(head, tail) == p holds.
190 # The resulting head won't end in '/' unless it is the root.
191
192 def split(p):
193 """Split a pathname.
194
195 Return tuple (head, tail) where tail is everything after the final slash.
196 Either part may be empty."""
197
198 d, p = splitdrive(p)
199 # set i to index beyond p's last slash
200 i = len(p)
201 while i and p[i-1] not in '/\\':
202 i = i - 1
203 head, tail = p[:i], p[i:] # now tail has no slashes
204 # remove trailing slashes from head, unless it's all slashes
205 head2 = head
206 while head2 and head2[-1] in '/\\':
207 head2 = head2[:-1]
208 head = head2 or head
209 return d + head, tail
210
211
212 # Split a path in root and extension.
213 # The extension is everything starting at the last dot in the last
214 # pathname component; the root is everything before that.
215 # It is always true that root + ext == p.
216
217 def splitext(p):
218 return genericpath._splitext(p, sep, altsep, extsep)
219 splitext.__doc__ = genericpath._splitext.__doc__
220
221
222 # Return the tail (basename) part of a path.
223
224 def basename(p):
225 """Returns the final component of a pathname"""
226 return split(p)[1]
227
228
229 # Return the head (dirname) part of a path.
230
231 def dirname(p):
232 """Returns the directory component of a pathname"""
233 return split(p)[0]
234
235 # Is a path a symbolic link?
236 # This will always return false on systems where posix.lstat doesn't exist.
237
238 def islink(path):
239 """Test for symbolic link.
240 On WindowsNT/95 and OS/2 always returns false
241 """
242 return False
243
244 # alias exists to lexists
245 lexists = exists
246
247 # Is a path a mount point? Either a root (with or without drive letter)
248 # or an UNC path with at most a / or \ after the mount point.
249
250 def ismount(path):
251 """Test whether a path is a mount point (defined as root of drive)"""
252 unc, rest = splitunc(path)
253 if unc:
254 return rest in ("", "/", "\\")
255 p = splitdrive(path)[1]
256 return len(p) == 1 and p[0] in '/\\'
257
258
259 # Directory tree walk.
260 # For each directory under top (including top itself, but excluding
261 # '.' and '..'), func(arg, dirname, filenames) is called, where
262 # dirname is the name of the directory and filenames is the list
263 # of files (and subdirectories etc.) in the directory.
264 # The func may modify the filenames list, to implement a filter,
265 # or to impose a different order of visiting.
266
267 def walk(top, func, arg):
268 """Directory tree walk with callback function.
269
270 For each directory in the directory tree rooted at top (including top
271 itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
272 dirname is the name of the directory, and fnames a list of the names of
273 the files and subdirectories in dirname (excluding '.' and '..'). func
274 may modify the fnames list in-place (e.g. via del or slice assignment),
275 and walk will only recurse into the subdirectories whose names remain in
276 fnames; this can be used to implement a filter, or to impose a specific
277 order of visiting. No semantics are defined for, or required of, arg,
278 beyond that arg is always passed to func. It can be used, e.g., to pass
279 a filename pattern, or a mutable object designed to accumulate
280 statistics. Passing None for arg is common."""
281 warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",
282 stacklevel=2)
283 try:
284 names = os.listdir(top)
285 except os.error:
286 return
287 func(arg, top, names)
288 for name in names:
289 name = join(top, name)
290 if isdir(name):
291 walk(name, func, arg)
292
293
294 # Expand paths beginning with '~' or '~user'.
295 # '~' means $HOME; '~user' means that user's home directory.
296 # If the path doesn't begin with '~', or if the user or $HOME is unknown,
297 # the path is returned unchanged (leaving error reporting to whatever
298 # function is called with the expanded path as argument).
299 # See also module 'glob' for expansion of *, ? and [...] in pathnames.
300 # (A function should also be defined to do full *sh-style environment
301 # variable expansion.)
302
303 def expanduser(path):
304 """Expand ~ and ~user constructs.
305
306 If user or $HOME is unknown, do nothing."""
307 if path[:1] != '~':
308 return path
309 i, n = 1, len(path)
310 while i < n and path[i] not in '/\\':
311 i = i + 1
312
313 if 'HOME' in os.environ:
314 userhome = os.environ['HOME']
315 elif 'USERPROFILE' in os.environ:
316 userhome = os.environ['USERPROFILE']
317 elif not 'HOMEPATH' in os.environ:
318 return path
319 else:
320 try:
321 drive = os.environ['HOMEDRIVE']
322 except KeyError:
323 drive = ''
324 userhome = join(drive, os.environ['HOMEPATH'])
325
326 if i != 1: #~user
327 userhome = join(dirname(userhome), path[1:i])
328
329 return userhome + path[i:]
330
331
332 # Expand paths containing shell variable substitutions.
333 # The following rules apply:
334 # - no expansion within single quotes
335 # - '$$' is translated into '$'
336 # - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%
337 # - ${varname} is accepted.
338 # - $varname is accepted.
339 # - %varname% is accepted.
340 # - varnames can be made out of letters, digits and the characters '_-'
341 # (though is not verified in the ${varname} and %varname% cases)
342 # XXX With COMMAND.COM you can use any characters in a variable name,
343 # XXX except '^|<>='.
344
345 def expandvars(path):
346 """Expand shell variables of the forms $var, ${var} and %var%.
347
348 Unknown variables are left unchanged."""
349 if '$' not in path and '%' not in path:
350 return path
351 import string
352 varchars = string.ascii_letters + string.digits + '_-'
353 if isinstance(path, _unicode):
354 encoding = sys.getfilesystemencoding()
355 def getenv(var):
356 return os.environ[var.encode(encoding)].decode(encoding)
357 else:
358 def getenv(var):
359 return os.environ[var]
360 res = ''
361 index = 0
362 pathlen = len(path)
363 while index < pathlen:
364 c = path[index]
365 if c == '\'': # no expansion within single quotes
366 path = path[index + 1:]
367 pathlen = len(path)
368 try:
369 index = path.index('\'')
370 res = res + '\'' + path[:index + 1]
371 except ValueError:
372 res = res + c + path
373 index = pathlen - 1
374 elif c == '%': # variable or '%'
375 if path[index + 1:index + 2] == '%':
376 res = res + c
377 index = index + 1
378 else:
379 path = path[index+1:]
380 pathlen = len(path)
381 try:
382 index = path.index('%')
383 except ValueError:
384 res = res + '%' + path
385 index = pathlen - 1
386 else:
387 var = path[:index]
388 try:
389 res = res + getenv(var)
390 except KeyError:
391 res = res + '%' + var + '%'
392 elif c == '$': # variable or '$$'
393 if path[index + 1:index + 2] == '$':
394 res = res + c
395 index = index + 1
396 elif path[index + 1:index + 2] == '{':
397 path = path[index+2:]
398 pathlen = len(path)
399 try:
400 index = path.index('}')
401 var = path[:index]
402 try:
403 res = res + getenv(var)
404 except KeyError:
405 res = res + '${' + var + '}'
406 except ValueError:
407 res = res + '${' + path
408 index = pathlen - 1
409 else:
410 var = ''
411 index = index + 1
412 c = path[index:index + 1]
413 while c != '' and c in varchars:
414 var = var + c
415 index = index + 1
416 c = path[index:index + 1]
417 try:
418 res = res + getenv(var)
419 except KeyError:
420 res = res + '$' + var
421 if c != '':
422 index = index - 1
423 else:
424 res = res + c
425 index = index + 1
426 return res
427
428
429 # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
430 # Previously, this function also truncated pathnames to 8+3 format,
431 # but as this module is called "ntpath", that's obviously wrong!
432
433 def normpath(path):
434 """Normalize path, eliminating double slashes, etc."""
435 # Preserve unicode (if path is unicode)
436 backslash, dot = (u'\\', u'.') if isinstance(path, _unicode) else ('\\', '.')
437 if path.startswith(('\\\\.\\', '\\\\?\\')):
438 # in the case of paths with these prefixes:
439 # \\.\ -> device names
440 # \\?\ -> literal paths
441 # do not do any normalization, but return the path unchanged
442 return path
443 path = path.replace("/", "\\")
444 prefix, path = splitdrive(path)
445 # We need to be careful here. If the prefix is empty, and the path starts
446 # with a backslash, it could either be an absolute path on the current
447 # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
448 # is therefore imperative NOT to collapse multiple backslashes blindly in
449 # that case.
450 # The code below preserves multiple backslashes when there is no drive
451 # letter. This means that the invalid filename \\\a\b is preserved
452 # unchanged, where a\\\b is normalised to a\b. It's not clear that there
453 # is any better behaviour for such edge cases.
454 if prefix == '':
455 # No drive letter - preserve initial backslashes
456 while path[:1] == "\\":
457 prefix = prefix + backslash
458 path = path[1:]
459 else:
460 # We have a drive letter - collapse initial backslashes
461 if path.startswith("\\"):
462 prefix = prefix + backslash
463 path = path.lstrip("\\")
464 comps = path.split("\\")
465 i = 0
466 while i < len(comps):
467 if comps[i] in ('.', ''):
468 del comps[i]
469 elif comps[i] == '..':
470 if i > 0 and comps[i-1] != '..':
471 del comps[i-1:i+1]
472 i -= 1
473 elif i == 0 and prefix.endswith("\\"):
474 del comps[i]
475 else:
476 i += 1
477 else:
478 i += 1
479 # If the path is now empty, substitute '.'
480 if not prefix and not comps:
481 comps.append(dot)
482 return prefix + backslash.join(comps)
483
484
485 # Return an absolute path.
486 try:
487 from nt import _getfullpathname
488
489 except ImportError: # not running on Windows - mock up something sensible
490 def abspath(path):
491 """Return the absolute version of a path."""
492 if not isabs(path):
493 if isinstance(path, _unicode):
494 cwd = os.getcwdu()
495 else:
496 cwd = os.getcwd()
497 path = join(cwd, path)
498 return normpath(path)
499
500 else: # use native Windows method on Windows
501 def abspath(path):
502 """Return the absolute version of a path."""
503
504 if path: # Empty path must return current working directory.
505 try:
506 path = _getfullpathname(path)
507 except WindowsError:
508 pass # Bad path - return unchanged.
509 elif isinstance(path, _unicode):
510 path = os.getcwdu()
511 else:
512 path = os.getcwd()
513 return normpath(path)
514
515 # realpath is a no-op on systems without islink support
516 realpath = abspath
517 # Win9x family and earlier have no Unicode filename support.
518 supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
519 sys.getwindowsversion()[3] >= 2)
520
521 def _abspath_split(path):
522 abs = abspath(normpath(path))
523 prefix, rest = splitunc(abs)
524 is_unc = bool(prefix)
525 if not is_unc:
526 prefix, rest = splitdrive(abs)
527 return is_unc, prefix, [x for x in rest.split(sep) if x]
528
529 def relpath(path, start=curdir):
530 """Return a relative version of a path"""
531
532 if not path:
533 raise ValueError("no path specified")
534
535 start_is_unc, start_prefix, start_list = _abspath_split(start)
536 path_is_unc, path_prefix, path_list = _abspath_split(path)
537
538 if path_is_unc ^ start_is_unc:
539 raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
540 % (path, start))
541 if path_prefix.lower() != start_prefix.lower():
542 if path_is_unc:
543 raise ValueError("path is on UNC root %s, start on UNC root %s"
544 % (path_prefix, start_prefix))
545 else:
546 raise ValueError("path is on drive %s, start on drive %s"
547 % (path_prefix, start_prefix))
548 # Work out how much of the filepath is shared by start and path.
549 i = 0
550 for e1, e2 in zip(start_list, path_list):
551 if e1.lower() != e2.lower():
552 break
553 i += 1
554
555 rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
556 if not rel_list:
557 return curdir
558 return join(*rel_list)
559
560 try:
561 # The genericpath.isdir implementation uses os.stat and checks the mode
562 # attribute to tell whether or not the path is a directory.
563 # This is overkill on Windows - just pass the path to GetFileAttributes
564 # and check the attribute from there.
565 from nt import _isdir as isdir
566 except ImportError:
567 # Use genericpath.isdir as imported above.
568 pass