home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Software / TemaCD / activepython / ActivePython-2.1.1.msi / Python21_Lib_ntpath.py < prev    next >
Encoding:
Text File  |  2001-07-26  |  13.0 KB  |  425 lines

  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)
  425.