PyXR

c:\python24\lib \ ntpath.py



0001 # Module 'ntpath' -- common operations on WinNT/Win95 pathnames
0002 """Common pathname manipulations, WindowsNT/95 version.
0003 
0004 Instead of importing this module directly, import os and refer to this
0005 module as os.path.
0006 """
0007 
0008 import os
0009 import stat
0010 import sys
0011 
0012 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
0013            "basename","dirname","commonprefix","getsize","getmtime",
0014            "getatime","getctime", "islink","exists","isdir","isfile","ismount",
0015            "walk","expanduser","expandvars","normpath","abspath","splitunc",
0016            "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
0017            "devnull","realpath","supports_unicode_filenames"]
0018 
0019 # strings representing various path-related bits and pieces
0020 curdir = '.'
0021 pardir = '..'
0022 extsep = '.'
0023 sep = '\\'
0024 pathsep = ';'
0025 altsep = '/'
0026 defpath = '.;C:\\bin'
0027 if 'ce' in sys.builtin_module_names:
0028     defpath = '\\Windows'
0029 elif 'os2' in sys.builtin_module_names:
0030     # OS/2 w/ VACPP
0031     altsep = '/'
0032 devnull = 'nul'
0033 
0034 # Normalize the case of a pathname and map slashes to backslashes.
0035 # Other normalizations (such as optimizing '../' away) are not done
0036 # (this is done by normpath).
0037 
0038 def normcase(s):
0039     """Normalize case of pathname.
0040 
0041     Makes all characters lowercase and all slashes into backslashes."""
0042     return s.replace("/", "\\").lower()
0043 
0044 
0045 # Return whether a path is absolute.
0046 # Trivial in Posix, harder on the Mac or MS-DOS.
0047 # For DOS it is absolute if it starts with a slash or backslash (current
0048 # volume), or if a pathname after the volume letter and colon / UNC resource
0049 # starts with a slash or backslash.
0050 
0051 def isabs(s):
0052     """Test whether a path is absolute"""
0053     s = splitdrive(s)[1]
0054     return s != '' and s[:1] in '/\\'
0055 
0056 
0057 # Join two (or more) paths.
0058 
0059 def join(a, *p):
0060     """Join two or more pathname components, inserting "\\" as needed"""
0061     path = a
0062     for b in p:
0063         b_wins = 0  # set to 1 iff b makes path irrelevant
0064         if path == "":
0065             b_wins = 1
0066 
0067         elif isabs(b):
0068             # This probably wipes out path so far.  However, it's more
0069             # complicated if path begins with a drive letter:
0070             #     1. join('c:', '/a') == 'c:/a'
0071             #     2. join('c:/', '/a') == 'c:/a'
0072             # But
0073             #     3. join('c:/a', '/b') == '/b'
0074             #     4. join('c:', 'd:/') = 'd:/'
0075             #     5. join('c:/', 'd:/') = 'd:/'
0076             if path[1:2] != ":" or b[1:2] == ":":
0077                 # Path doesn't start with a drive letter, or cases 4 and 5.
0078                 b_wins = 1
0079 
0080             # Else path has a drive letter, and b doesn't but is absolute.
0081             elif len(path) > 3 or (len(path) == 3 and
0082                                    path[-1] not in "/\\"):
0083                 # case 3
0084                 b_wins = 1
0085 
0086         if b_wins:
0087             path = b
0088         else:
0089             # Join, and ensure there's a separator.
0090             assert len(path) > 0
0091             if path[-1] in "/\\":
0092                 if b and b[0] in "/\\":
0093                     path += b[1:]
0094                 else:
0095                     path += b
0096             elif path[-1] == ":":
0097                 path += b
0098             elif b:
0099                 if b[0] in "/\\":
0100                     path += b
0101                 else:
0102                     path += "\\" + b
0103             else:
0104                 # path is not empty and does not end with a backslash,
0105                 # but b is empty; since, e.g., split('a/') produces
0106                 # ('a', ''), it's best if join() adds a backslash in
0107                 # this case.
0108                 path += '\\'
0109 
0110     return path
0111 
0112 
0113 # Split a path in a drive specification (a drive letter followed by a
0114 # colon) and the path specification.
0115 # It is always true that drivespec + pathspec == p
0116 def splitdrive(p):
0117     """Split a pathname into drive and path specifiers. Returns a 2-tuple
0118 "(drive,path)";  either part may be empty"""
0119     if p[1:2] == ':':
0120         return p[0:2], p[2:]
0121     return '', p
0122 
0123 
0124 # Parse UNC paths
0125 def splitunc(p):
0126     """Split a pathname into UNC mount point and relative path specifiers.
0127 
0128     Return a 2-tuple (unc, rest); either part may be empty.
0129     If unc is not empty, it has the form '//host/mount' (or similar
0130     using backslashes).  unc+rest is always the input path.
0131     Paths containing drive letters never have an UNC part.
0132     """
0133     if p[1:2] == ':':
0134         return '', p # Drive letter present
0135     firstTwo = p[0:2]
0136     if firstTwo == '//' or firstTwo == '\\\\':
0137         # is a UNC path:
0138         # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
0139         # \\machine\mountpoint\directories...
0140         #           directory ^^^^^^^^^^^^^^^
0141         normp = normcase(p)
0142         index = normp.find('\\', 2)
0143         if index == -1:
0144             ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
0145             return ("", p)
0146         index = normp.find('\\', index + 1)
0147         if index == -1:
0148             index = len(p)
0149         return p[:index], p[index:]
0150     return '', p
0151 
0152 
0153 # Split a path in head (everything up to the last '/') and tail (the
0154 # rest).  After the trailing '/' is stripped, the invariant
0155 # join(head, tail) == p holds.
0156 # The resulting head won't end in '/' unless it is the root.
0157 
0158 def split(p):
0159     """Split a pathname.
0160 
0161     Return tuple (head, tail) where tail is everything after the final slash.
0162     Either part may be empty."""
0163 
0164     d, p = splitdrive(p)
0165     # set i to index beyond p's last slash
0166     i = len(p)
0167     while i and p[i-1] not in '/\\':
0168         i = i - 1
0169     head, tail = p[:i], p[i:]  # now tail has no slashes
0170     # remove trailing slashes from head, unless it's all slashes
0171     head2 = head
0172     while head2 and head2[-1] in '/\\':
0173         head2 = head2[:-1]
0174     head = head2 or head
0175     return d + head, tail
0176 
0177 
0178 # Split a path in root and extension.
0179 # The extension is everything starting at the last dot in the last
0180 # pathname component; the root is everything before that.
0181 # It is always true that root + ext == p.
0182 
0183 def splitext(p):
0184     """Split the extension from a pathname.
0185 
0186     Extension is everything from the last dot to the end.
0187     Return (root, ext), either part may be empty."""
0188 
0189     i = p.rfind('.')
0190     if i<=max(p.rfind('/'), p.rfind('\\')):
0191         return p, ''
0192     else:
0193         return p[:i], p[i:]
0194 
0195 
0196 # Return the tail (basename) part of a path.
0197 
0198 def basename(p):
0199     """Returns the final component of a pathname"""
0200     return split(p)[1]
0201 
0202 
0203 # Return the head (dirname) part of a path.
0204 
0205 def dirname(p):
0206     """Returns the directory component of a pathname"""
0207     return split(p)[0]
0208 
0209 
0210 # Return the longest prefix of all list elements.
0211 
0212 def commonprefix(m):
0213     "Given a list of pathnames, returns the longest common leading component"
0214     if not m: return ''
0215     prefix = m[0]
0216     for item in m:
0217         for i in range(len(prefix)):
0218             if prefix[:i+1] != item[:i+1]:
0219                 prefix = prefix[:i]
0220                 if i == 0: return ''
0221                 break
0222     return prefix
0223 
0224 
0225 # Get size, mtime, atime of files.
0226 
0227 def getsize(filename):
0228     """Return the size of a file, reported by os.stat()"""
0229     return os.stat(filename).st_size
0230 
0231 def getmtime(filename):
0232     """Return the last modification time of a file, reported by os.stat()"""
0233     return os.stat(filename).st_mtime
0234 
0235 def getatime(filename):
0236     """Return the last access time of a file, reported by os.stat()"""
0237     return os.stat(filename).st_atime
0238 
0239 def getctime(filename):
0240     """Return the creation time of a file, reported by os.stat()."""
0241     return os.stat(filename).st_ctime
0242 
0243 # Is a path a symbolic link?
0244 # This will always return false on systems where posix.lstat doesn't exist.
0245 
0246 def islink(path):
0247     """Test for symbolic link.  On WindowsNT/95 always returns false"""
0248     return False
0249 
0250 
0251 # Does a path exist?
0252 
0253 def exists(path):
0254     """Test whether a path exists"""
0255     try:
0256         st = os.stat(path)
0257     except os.error:
0258         return False
0259     return True
0260 
0261 lexists = exists
0262 
0263 
0264 # Is a path a dos directory?
0265 # This follows symbolic links, so both islink() and isdir() can be true
0266 # for the same path.
0267 
0268 def isdir(path):
0269     """Test whether a path is a directory"""
0270     try:
0271         st = os.stat(path)
0272     except os.error:
0273         return False
0274     return stat.S_ISDIR(st.st_mode)
0275 
0276 
0277 # Is a path a regular file?
0278 # This follows symbolic links, so both islink() and isdir() can be true
0279 # for the same path.
0280 
0281 def isfile(path):
0282     """Test whether a path is a regular file"""
0283     try:
0284         st = os.stat(path)
0285     except os.error:
0286         return False
0287     return stat.S_ISREG(st.st_mode)
0288 
0289 
0290 # Is a path a mount point?  Either a root (with or without drive letter)
0291 # or an UNC path with at most a / or \ after the mount point.
0292 
0293 def ismount(path):
0294     """Test whether a path is a mount point (defined as root of drive)"""
0295     unc, rest = splitunc(path)
0296     if unc:
0297         return rest in ("", "/", "\\")
0298     p = splitdrive(path)[1]
0299     return len(p) == 1 and p[0] in '/\\'
0300 
0301 
0302 # Directory tree walk.
0303 # For each directory under top (including top itself, but excluding
0304 # '.' and '..'), func(arg, dirname, filenames) is called, where
0305 # dirname is the name of the directory and filenames is the list
0306 # of files (and subdirectories etc.) in the directory.
0307 # The func may modify the filenames list, to implement a filter,
0308 # or to impose a different order of visiting.
0309 
0310 def walk(top, func, arg):
0311     """Directory tree walk with callback function.
0312 
0313     For each directory in the directory tree rooted at top (including top
0314     itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
0315     dirname is the name of the directory, and fnames a list of the names of
0316     the files and subdirectories in dirname (excluding '.' and '..').  func
0317     may modify the fnames list in-place (e.g. via del or slice assignment),
0318     and walk will only recurse into the subdirectories whose names remain in
0319     fnames; this can be used to implement a filter, or to impose a specific
0320     order of visiting.  No semantics are defined for, or required of, arg,
0321     beyond that arg is always passed to func.  It can be used, e.g., to pass
0322     a filename pattern, or a mutable object designed to accumulate
0323     statistics.  Passing None for arg is common."""
0324 
0325     try:
0326         names = os.listdir(top)
0327     except os.error:
0328         return
0329     func(arg, top, names)
0330     exceptions = ('.', '..')
0331     for name in names:
0332         if name not in exceptions:
0333             name = join(top, name)
0334             if isdir(name):
0335                 walk(name, func, arg)
0336 
0337 
0338 # Expand paths beginning with '~' or '~user'.
0339 # '~' means $HOME; '~user' means that user's home directory.
0340 # If the path doesn't begin with '~', or if the user or $HOME is unknown,
0341 # the path is returned unchanged (leaving error reporting to whatever
0342 # function is called with the expanded path as argument).
0343 # See also module 'glob' for expansion of *, ? and [...] in pathnames.
0344 # (A function should also be defined to do full *sh-style environment
0345 # variable expansion.)
0346 
0347 def expanduser(path):
0348     """Expand ~ and ~user constructs.
0349 
0350     If user or $HOME is unknown, do nothing."""
0351     if path[:1] != '~':
0352         return path
0353     i, n = 1, len(path)
0354     while i < n and path[i] not in '/\\':
0355         i = i + 1
0356     if i == 1:
0357         if 'HOME' in os.environ:
0358             userhome = os.environ['HOME']
0359         elif not 'HOMEPATH' in os.environ:
0360             return path
0361         else:
0362             try:
0363                 drive = os.environ['HOMEDRIVE']
0364             except KeyError:
0365                 drive = ''
0366             userhome = join(drive, os.environ['HOMEPATH'])
0367     else:
0368         return path
0369     return userhome + path[i:]
0370 
0371 
0372 # Expand paths containing shell variable substitutions.
0373 # The following rules apply:
0374 #       - no expansion within single quotes
0375 #       - no escape character, except for '$$' which is translated into '$'
0376 #       - ${varname} is accepted.
0377 #       - varnames can be made out of letters, digits and the character '_'
0378 # XXX With COMMAND.COM you can use any characters in a variable name,
0379 # XXX except '^|<>='.
0380 
0381 def expandvars(path):
0382     """Expand shell variables of form $var and ${var}.
0383 
0384     Unknown variables are left unchanged."""
0385     if '$' not in path:
0386         return path
0387     import string
0388     varchars = string.ascii_letters + string.digits + '_-'
0389     res = ''
0390     index = 0
0391     pathlen = len(path)
0392     while index < pathlen:
0393         c = path[index]
0394         if c == '\'':   # no expansion within single quotes
0395             path = path[index + 1:]
0396             pathlen = len(path)
0397             try:
0398                 index = path.index('\'')
0399                 res = res + '\'' + path[:index + 1]
0400             except ValueError:
0401                 res = res + path
0402                 index = pathlen - 1
0403         elif c == '$':  # variable or '$$'
0404             if path[index + 1:index + 2] == '$':
0405                 res = res + c
0406                 index = index + 1
0407             elif path[index + 1:index + 2] == '{':
0408                 path = path[index+2:]
0409                 pathlen = len(path)
0410                 try:
0411                     index = path.index('}')
0412                     var = path[:index]
0413                     if var in os.environ:
0414                         res = res + os.environ[var]
0415                 except ValueError:
0416                     res = res + path
0417                     index = pathlen - 1
0418             else:
0419                 var = ''
0420                 index = index + 1
0421                 c = path[index:index + 1]
0422                 while c != '' and c in varchars:
0423                     var = var + c
0424                     index = index + 1
0425                     c = path[index:index + 1]
0426                 if var in os.environ:
0427                     res = res + os.environ[var]
0428                 if c != '':
0429                     res = res + c
0430         else:
0431             res = res + c
0432         index = index + 1
0433     return res
0434 
0435 
0436 # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
0437 # Previously, this function also truncated pathnames to 8+3 format,
0438 # but as this module is called "ntpath", that's obviously wrong!
0439 
0440 def normpath(path):
0441     """Normalize path, eliminating double slashes, etc."""
0442     path = path.replace("/", "\\")
0443     prefix, path = splitdrive(path)
0444     # We need to be careful here. If the prefix is empty, and the path starts
0445     # with a backslash, it could either be an absolute path on the current
0446     # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
0447     # is therefore imperative NOT to collapse multiple backslashes blindly in
0448     # that case.
0449     # The code below preserves multiple backslashes when there is no drive
0450     # letter. This means that the invalid filename \\\a\b is preserved
0451     # unchanged, where a\\\b is normalised to a\b. It's not clear that there
0452     # is any better behaviour for such edge cases.
0453     if prefix == '':
0454         # No drive letter - preserve initial backslashes
0455         while path[:1] == "\\":
0456             prefix = prefix + "\\"
0457             path = path[1:]
0458     else:
0459         # We have a drive letter - collapse initial backslashes
0460         if path.startswith("\\"):
0461             prefix = prefix + "\\"
0462             path = path.lstrip("\\")
0463     comps = path.split("\\")
0464     i = 0
0465     while i < len(comps):
0466         if comps[i] in ('.', ''):
0467             del comps[i]
0468         elif comps[i] == '..':
0469             if i > 0 and comps[i-1] != '..':
0470                 del comps[i-1:i+1]
0471                 i -= 1
0472             elif i == 0 and prefix.endswith("\\"):
0473                 del comps[i]
0474             else:
0475                 i += 1
0476         else:
0477             i += 1
0478     # If the path is now empty, substitute '.'
0479     if not prefix and not comps:
0480         comps.append('.')
0481     return prefix + "\\".join(comps)
0482 
0483 
0484 # Return an absolute path.
0485 def abspath(path):
0486     """Return the absolute version of a path"""
0487     try:
0488         from nt import _getfullpathname
0489     except ImportError: # Not running on Windows - mock up something sensible.
0490         global abspath
0491         def _abspath(path):
0492             if not isabs(path):
0493                 path = join(os.getcwd(), path)
0494             return normpath(path)
0495         abspath = _abspath
0496         return _abspath(path)
0497 
0498     if path: # Empty path must return current working directory.
0499         try:
0500             path = _getfullpathname(path)
0501         except WindowsError:
0502             pass # Bad path - return unchanged.
0503     else:
0504         path = os.getcwd()
0505     return normpath(path)
0506 
0507 # realpath is a no-op on systems without islink support
0508 realpath = abspath
0509 # Win9x family and earlier have no Unicode filename support.
0510 supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
0511                               sys.getwindowsversion()[3] >= 2)
0512 

Generated by PyXR 0.9.4
SourceForge.net Logo