symbian-qemu-0.9.1-12/python-2.6.1/Lib/posixpath.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Common operations on Posix pathnames.
       
     2 
       
     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).
       
     8 
       
     9 Some of this can actually be useful on non-Posix systems too, e.g.
       
    10 for manipulation of the pathname component of URLs.
       
    11 """
       
    12 
       
    13 import os
       
    14 import stat
       
    15 import genericpath
       
    16 import warnings
       
    17 from genericpath import *
       
    18 
       
    19 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
       
    20            "basename","dirname","commonprefix","getsize","getmtime",
       
    21            "getatime","getctime","islink","exists","lexists","isdir","isfile",
       
    22            "ismount","walk","expanduser","expandvars","normpath","abspath",
       
    23            "samefile","sameopenfile","samestat",
       
    24            "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
       
    25            "devnull","realpath","supports_unicode_filenames","relpath"]
       
    26 
       
    27 # strings representing various path-related bits and pieces
       
    28 curdir = '.'
       
    29 pardir = '..'
       
    30 extsep = '.'
       
    31 sep = '/'
       
    32 pathsep = ':'
       
    33 defpath = ':/bin:/usr/bin'
       
    34 altsep = None
       
    35 devnull = '/dev/null'
       
    36 
       
    37 # Normalize the case of a pathname.  Trivial in Posix, string.lower on Mac.
       
    38 # On MS-DOS this may also turn slashes into backslashes; however, other
       
    39 # normalizations (such as optimizing '../' away) are not allowed
       
    40 # (another function should be defined to do that).
       
    41 
       
    42 def normcase(s):
       
    43     """Normalize case of pathname.  Has no effect under Posix"""
       
    44     return s
       
    45 
       
    46 
       
    47 # Return whether a path is absolute.
       
    48 # Trivial in Posix, harder on the Mac or MS-DOS.
       
    49 
       
    50 def isabs(s):
       
    51     """Test whether a path is absolute"""
       
    52     return s.startswith('/')
       
    53 
       
    54 
       
    55 # Join pathnames.
       
    56 # Ignore the previous parts if a part is absolute.
       
    57 # Insert a '/' unless the first part is empty or already ends in '/'.
       
    58 
       
    59 def join(a, *p):
       
    60     """Join two or more pathname components, inserting '/' as needed.
       
    61     If any component is an absolute path, all previous path components
       
    62     will be discarded."""
       
    63     path = a
       
    64     for b in p:
       
    65         if b.startswith('/'):
       
    66             path = b
       
    67         elif path == '' or path.endswith('/'):
       
    68             path +=  b
       
    69         else:
       
    70             path += '/' + b
       
    71     return path
       
    72 
       
    73 
       
    74 # Split a path in head (everything up to the last '/') and tail (the
       
    75 # rest).  If the path ends in '/', tail will be empty.  If there is no
       
    76 # '/' in the path, head  will be empty.
       
    77 # Trailing '/'es are stripped from head unless it is the root.
       
    78 
       
    79 def split(p):
       
    80     """Split a pathname.  Returns tuple "(head, tail)" where "tail" is
       
    81     everything after the final slash.  Either part may be empty."""
       
    82     i = p.rfind('/') + 1
       
    83     head, tail = p[:i], p[i:]
       
    84     if head and head != '/'*len(head):
       
    85         head = head.rstrip('/')
       
    86     return head, tail
       
    87 
       
    88 
       
    89 # Split a path in root and extension.
       
    90 # The extension is everything starting at the last dot in the last
       
    91 # pathname component; the root is everything before that.
       
    92 # It is always true that root + ext == p.
       
    93 
       
    94 def splitext(p):
       
    95     return genericpath._splitext(p, sep, altsep, extsep)
       
    96 splitext.__doc__ = genericpath._splitext.__doc__
       
    97 
       
    98 # Split a pathname into a drive specification and the rest of the
       
    99 # path.  Useful on DOS/Windows/NT; on Unix, the drive is always empty.
       
   100 
       
   101 def splitdrive(p):
       
   102     """Split a pathname into drive and path. On Posix, drive is always
       
   103     empty."""
       
   104     return '', p
       
   105 
       
   106 
       
   107 # Return the tail (basename) part of a path, same as split(path)[1].
       
   108 
       
   109 def basename(p):
       
   110     """Returns the final component of a pathname"""
       
   111     i = p.rfind('/') + 1
       
   112     return p[i:]
       
   113 
       
   114 
       
   115 # Return the head (dirname) part of a path, same as split(path)[0].
       
   116 
       
   117 def dirname(p):
       
   118     """Returns the directory component of a pathname"""
       
   119     i = p.rfind('/') + 1
       
   120     head = p[:i]
       
   121     if head and head != '/'*len(head):
       
   122         head = head.rstrip('/')
       
   123     return head
       
   124 
       
   125 
       
   126 # Is a path a symbolic link?
       
   127 # This will always return false on systems where os.lstat doesn't exist.
       
   128 
       
   129 def islink(path):
       
   130     """Test whether a path is a symbolic link"""
       
   131     try:
       
   132         st = os.lstat(path)
       
   133     except (os.error, AttributeError):
       
   134         return False
       
   135     return stat.S_ISLNK(st.st_mode)
       
   136 
       
   137 # Being true for dangling symbolic links is also useful.
       
   138 
       
   139 def lexists(path):
       
   140     """Test whether a path exists.  Returns True for broken symbolic links"""
       
   141     try:
       
   142         st = os.lstat(path)
       
   143     except os.error:
       
   144         return False
       
   145     return True
       
   146 
       
   147 
       
   148 # Are two filenames really pointing to the same file?
       
   149 
       
   150 def samefile(f1, f2):
       
   151     """Test whether two pathnames reference the same actual file"""
       
   152     s1 = os.stat(f1)
       
   153     s2 = os.stat(f2)
       
   154     return samestat(s1, s2)
       
   155 
       
   156 
       
   157 # Are two open files really referencing the same file?
       
   158 # (Not necessarily the same file descriptor!)
       
   159 
       
   160 def sameopenfile(fp1, fp2):
       
   161     """Test whether two open file objects reference the same file"""
       
   162     s1 = os.fstat(fp1)
       
   163     s2 = os.fstat(fp2)
       
   164     return samestat(s1, s2)
       
   165 
       
   166 
       
   167 # Are two stat buffers (obtained from stat, fstat or lstat)
       
   168 # describing the same file?
       
   169 
       
   170 def samestat(s1, s2):
       
   171     """Test whether two stat buffers reference the same file"""
       
   172     return s1.st_ino == s2.st_ino and \
       
   173            s1.st_dev == s2.st_dev
       
   174 
       
   175 
       
   176 # Is a path a mount point?
       
   177 # (Does this work for all UNIXes?  Is it even guaranteed to work by Posix?)
       
   178 
       
   179 def ismount(path):
       
   180     """Test whether a path is a mount point"""
       
   181     try:
       
   182         s1 = os.lstat(path)
       
   183         s2 = os.lstat(join(path, '..'))
       
   184     except os.error:
       
   185         return False # It doesn't exist -- so not a mount point :-)
       
   186     dev1 = s1.st_dev
       
   187     dev2 = s2.st_dev
       
   188     if dev1 != dev2:
       
   189         return True     # path/.. on a different device as path
       
   190     ino1 = s1.st_ino
       
   191     ino2 = s2.st_ino
       
   192     if ino1 == ino2:
       
   193         return True     # path/.. is the same i-node as path
       
   194     return False
       
   195 
       
   196 
       
   197 # Directory tree walk.
       
   198 # For each directory under top (including top itself, but excluding
       
   199 # '.' and '..'), func(arg, dirname, filenames) is called, where
       
   200 # dirname is the name of the directory and filenames is the list
       
   201 # of files (and subdirectories etc.) in the directory.
       
   202 # The func may modify the filenames list, to implement a filter,
       
   203 # or to impose a different order of visiting.
       
   204 
       
   205 def walk(top, func, arg):
       
   206     """Directory tree walk with callback function.
       
   207 
       
   208     For each directory in the directory tree rooted at top (including top
       
   209     itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
       
   210     dirname is the name of the directory, and fnames a list of the names of
       
   211     the files and subdirectories in dirname (excluding '.' and '..').  func
       
   212     may modify the fnames list in-place (e.g. via del or slice assignment),
       
   213     and walk will only recurse into the subdirectories whose names remain in
       
   214     fnames; this can be used to implement a filter, or to impose a specific
       
   215     order of visiting.  No semantics are defined for, or required of, arg,
       
   216     beyond that arg is always passed to func.  It can be used, e.g., to pass
       
   217     a filename pattern, or a mutable object designed to accumulate
       
   218     statistics.  Passing None for arg is common."""
       
   219     warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.")
       
   220     try:
       
   221         names = os.listdir(top)
       
   222     except os.error:
       
   223         return
       
   224     func(arg, top, names)
       
   225     for name in names:
       
   226         name = join(top, name)
       
   227         try:
       
   228             st = os.lstat(name)
       
   229         except os.error:
       
   230             continue
       
   231         if stat.S_ISDIR(st.st_mode):
       
   232             walk(name, func, arg)
       
   233 
       
   234 
       
   235 # Expand paths beginning with '~' or '~user'.
       
   236 # '~' means $HOME; '~user' means that user's home directory.
       
   237 # If the path doesn't begin with '~', or if the user or $HOME is unknown,
       
   238 # the path is returned unchanged (leaving error reporting to whatever
       
   239 # function is called with the expanded path as argument).
       
   240 # See also module 'glob' for expansion of *, ? and [...] in pathnames.
       
   241 # (A function should also be defined to do full *sh-style environment
       
   242 # variable expansion.)
       
   243 
       
   244 def expanduser(path):
       
   245     """Expand ~ and ~user constructions.  If user or $HOME is unknown,
       
   246     do nothing."""
       
   247     if not path.startswith('~'):
       
   248         return path
       
   249     i = path.find('/', 1)
       
   250     if i < 0:
       
   251         i = len(path)
       
   252     if i == 1:
       
   253         if 'HOME' not in os.environ:
       
   254             import pwd
       
   255             userhome = pwd.getpwuid(os.getuid()).pw_dir
       
   256         else:
       
   257             userhome = os.environ['HOME']
       
   258     else:
       
   259         import pwd
       
   260         try:
       
   261             pwent = pwd.getpwnam(path[1:i])
       
   262         except KeyError:
       
   263             return path
       
   264         userhome = pwent.pw_dir
       
   265     userhome = userhome.rstrip('/')
       
   266     return userhome + path[i:]
       
   267 
       
   268 
       
   269 # Expand paths containing shell variable substitutions.
       
   270 # This expands the forms $variable and ${variable} only.
       
   271 # Non-existent variables are left unchanged.
       
   272 
       
   273 _varprog = None
       
   274 
       
   275 def expandvars(path):
       
   276     """Expand shell variables of form $var and ${var}.  Unknown variables
       
   277     are left unchanged."""
       
   278     global _varprog
       
   279     if '$' not in path:
       
   280         return path
       
   281     if not _varprog:
       
   282         import re
       
   283         _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
       
   284     i = 0
       
   285     while True:
       
   286         m = _varprog.search(path, i)
       
   287         if not m:
       
   288             break
       
   289         i, j = m.span(0)
       
   290         name = m.group(1)
       
   291         if name.startswith('{') and name.endswith('}'):
       
   292             name = name[1:-1]
       
   293         if name in os.environ:
       
   294             tail = path[j:]
       
   295             path = path[:i] + os.environ[name]
       
   296             i = len(path)
       
   297             path += tail
       
   298         else:
       
   299             i = j
       
   300     return path
       
   301 
       
   302 
       
   303 # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
       
   304 # It should be understood that this may change the meaning of the path
       
   305 # if it contains symbolic links!
       
   306 
       
   307 def normpath(path):
       
   308     """Normalize path, eliminating double slashes, etc."""
       
   309     if path == '':
       
   310         return '.'
       
   311     initial_slashes = path.startswith('/')
       
   312     # POSIX allows one or two initial slashes, but treats three or more
       
   313     # as single slash.
       
   314     if (initial_slashes and
       
   315         path.startswith('//') and not path.startswith('///')):
       
   316         initial_slashes = 2
       
   317     comps = path.split('/')
       
   318     new_comps = []
       
   319     for comp in comps:
       
   320         if comp in ('', '.'):
       
   321             continue
       
   322         if (comp != '..' or (not initial_slashes and not new_comps) or
       
   323              (new_comps and new_comps[-1] == '..')):
       
   324             new_comps.append(comp)
       
   325         elif new_comps:
       
   326             new_comps.pop()
       
   327     comps = new_comps
       
   328     path = '/'.join(comps)
       
   329     if initial_slashes:
       
   330         path = '/'*initial_slashes + path
       
   331     return path or '.'
       
   332 
       
   333 
       
   334 def abspath(path):
       
   335     """Return an absolute path."""
       
   336     if not isabs(path):
       
   337         path = join(os.getcwd(), path)
       
   338     return normpath(path)
       
   339 
       
   340 
       
   341 # Return a canonical path (i.e. the absolute location of a file on the
       
   342 # filesystem).
       
   343 
       
   344 def realpath(filename):
       
   345     """Return the canonical path of the specified filename, eliminating any
       
   346 symbolic links encountered in the path."""
       
   347     if isabs(filename):
       
   348         bits = ['/'] + filename.split('/')[1:]
       
   349     else:
       
   350         bits = [''] + filename.split('/')
       
   351 
       
   352     for i in range(2, len(bits)+1):
       
   353         component = join(*bits[0:i])
       
   354         # Resolve symbolic links.
       
   355         if islink(component):
       
   356             resolved = _resolve_link(component)
       
   357             if resolved is None:
       
   358                 # Infinite loop -- return original component + rest of the path
       
   359                 return abspath(join(*([component] + bits[i:])))
       
   360             else:
       
   361                 newpath = join(*([resolved] + bits[i:]))
       
   362                 return realpath(newpath)
       
   363 
       
   364     return abspath(filename)
       
   365 
       
   366 
       
   367 def _resolve_link(path):
       
   368     """Internal helper function.  Takes a path and follows symlinks
       
   369     until we either arrive at something that isn't a symlink, or
       
   370     encounter a path we've seen before (meaning that there's a loop).
       
   371     """
       
   372     paths_seen = []
       
   373     while islink(path):
       
   374         if path in paths_seen:
       
   375             # Already seen this path, so we must have a symlink loop
       
   376             return None
       
   377         paths_seen.append(path)
       
   378         # Resolve where the link points to
       
   379         resolved = os.readlink(path)
       
   380         if not isabs(resolved):
       
   381             dir = dirname(path)
       
   382             path = normpath(join(dir, resolved))
       
   383         else:
       
   384             path = normpath(resolved)
       
   385     return path
       
   386 
       
   387 supports_unicode_filenames = False
       
   388 
       
   389 def relpath(path, start=curdir):
       
   390     """Return a relative version of a path"""
       
   391 
       
   392     if not path:
       
   393         raise ValueError("no path specified")
       
   394 
       
   395     start_list = abspath(start).split(sep)
       
   396     path_list = abspath(path).split(sep)
       
   397 
       
   398     # Work out how much of the filepath is shared by start and path.
       
   399     i = len(commonprefix([start_list, path_list]))
       
   400 
       
   401     rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
       
   402     if not rel_list:
       
   403         return curdir
       
   404     return join(*rel_list)