PyXR

c:\python24\lib \ posixpath.py



0001 """Common operations on Posix pathnames.
0002 
0003 Instead of importing this module directly, import os and refer to
0004 this module as os.path.  The "os.path" name is an alias for this
0005 module on Posix systems; on other systems (e.g. Mac, Windows),
0006 os.path provides the same operations in a manner specific to that
0007 platform, and is an alias to another module (e.g. macpath, ntpath).
0008 
0009 Some of this can actually be useful on non-Posix systems too, e.g.
0010 for manipulation of the pathname component of URLs.
0011 """
0012 
0013 import os
0014 import stat
0015 
0016 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
0017            "basename","dirname","commonprefix","getsize","getmtime",
0018            "getatime","getctime","islink","exists","isdir","isfile","ismount",
0019            "walk","expanduser","expandvars","normpath","abspath",
0020            "samefile","sameopenfile","samestat",
0021            "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
0022            "devnull","realpath","supports_unicode_filenames"]
0023 
0024 # strings representing various path-related bits and pieces
0025 curdir = '.'
0026 pardir = '..'
0027 extsep = '.'
0028 sep = '/'
0029 pathsep = ':'
0030 defpath = ':/bin:/usr/bin'
0031 altsep = None
0032 devnull = '/dev/null'
0033 
0034 # Normalize the case of a pathname.  Trivial in Posix, string.lower on Mac.
0035 # On MS-DOS this may also turn slashes into backslashes; however, other
0036 # normalizations (such as optimizing '../' away) are not allowed
0037 # (another function should be defined to do that).
0038 
0039 def normcase(s):
0040     """Normalize case of pathname.  Has no effect under Posix"""
0041     return s
0042 
0043 
0044 # Return whether a path is absolute.
0045 # Trivial in Posix, harder on the Mac or MS-DOS.
0046 
0047 def isabs(s):
0048     """Test whether a path is absolute"""
0049     return s.startswith('/')
0050 
0051 
0052 # Join pathnames.
0053 # Ignore the previous parts if a part is absolute.
0054 # Insert a '/' unless the first part is empty or already ends in '/'.
0055 
0056 def join(a, *p):
0057     """Join two or more pathname components, inserting '/' as needed"""
0058     path = a
0059     for b in p:
0060         if b.startswith('/'):
0061             path = b
0062         elif path == '' or path.endswith('/'):
0063             path +=  b
0064         else:
0065             path += '/' + b
0066     return path
0067 
0068 
0069 # Split a path in head (everything up to the last '/') and tail (the
0070 # rest).  If the path ends in '/', tail will be empty.  If there is no
0071 # '/' in the path, head  will be empty.
0072 # Trailing '/'es are stripped from head unless it is the root.
0073 
0074 def split(p):
0075     """Split a pathname.  Returns tuple "(head, tail)" where "tail" is
0076     everything after the final slash.  Either part may be empty."""
0077     i = p.rfind('/') + 1
0078     head, tail = p[:i], p[i:]
0079     if head and head != '/'*len(head):
0080         head = head.rstrip('/')
0081     return head, tail
0082 
0083 
0084 # Split a path in root and extension.
0085 # The extension is everything starting at the last dot in the last
0086 # pathname component; the root is everything before that.
0087 # It is always true that root + ext == p.
0088 
0089 def splitext(p):
0090     """Split the extension from a pathname.  Extension is everything from the
0091     last dot to the end.  Returns "(root, ext)", either part may be empty."""
0092     i = p.rfind('.')
0093     if i<=p.rfind('/'):
0094         return p, ''
0095     else:
0096         return p[:i], p[i:]
0097 
0098 
0099 # Split a pathname into a drive specification and the rest of the
0100 # path.  Useful on DOS/Windows/NT; on Unix, the drive is always empty.
0101 
0102 def splitdrive(p):
0103     """Split a pathname into drive and path. On Posix, drive is always
0104     empty."""
0105     return '', p
0106 
0107 
0108 # Return the tail (basename) part of a path.
0109 
0110 def basename(p):
0111     """Returns the final component of a pathname"""
0112     return split(p)[1]
0113 
0114 
0115 # Return the head (dirname) part of a path.
0116 
0117 def dirname(p):
0118     """Returns the directory component of a pathname"""
0119     return split(p)[0]
0120 
0121 
0122 # Return the longest prefix of all list elements.
0123 
0124 def commonprefix(m):
0125     "Given a list of pathnames, returns the longest common leading component"
0126     if not m: return ''
0127     s1 = min(m)
0128     s2 = max(m)
0129     n = min(len(s1), len(s2))
0130     for i in xrange(n):
0131         if s1[i] != s2[i]:
0132             return s1[:i]
0133     return s1[:n]
0134 
0135 # Get size, mtime, atime of files.
0136 
0137 def getsize(filename):
0138     """Return the size of a file, reported by os.stat()."""
0139     return os.stat(filename).st_size
0140 
0141 def getmtime(filename):
0142     """Return the last modification time of a file, reported by os.stat()."""
0143     return os.stat(filename).st_mtime
0144 
0145 def getatime(filename):
0146     """Return the last access time of a file, reported by os.stat()."""
0147     return os.stat(filename).st_atime
0148 
0149 def getctime(filename):
0150     """Return the metadata change time of a file, reported by os.stat()."""
0151     return os.stat(filename).st_ctime
0152 
0153 # Is a path a symbolic link?
0154 # This will always return false on systems where os.lstat doesn't exist.
0155 
0156 def islink(path):
0157     """Test whether a path is a symbolic link"""
0158     try:
0159         st = os.lstat(path)
0160     except (os.error, AttributeError):
0161         return False
0162     return stat.S_ISLNK(st.st_mode)
0163 
0164 
0165 # Does a path exist?
0166 # This is false for dangling symbolic links.
0167 
0168 def exists(path):
0169     """Test whether a path exists.  Returns False for broken symbolic links"""
0170     try:
0171         st = os.stat(path)
0172     except os.error:
0173         return False
0174     return True
0175 
0176 
0177 # Being true for dangling symbolic links is also useful.
0178 
0179 def lexists(path):
0180     """Test whether a path exists.  Returns True for broken symbolic links"""
0181     try:
0182         st = os.lstat(path)
0183     except os.error:
0184         return False
0185     return True
0186 
0187 
0188 # Is a path a directory?
0189 # This follows symbolic links, so both islink() and isdir() can be true
0190 # for the same path.
0191 
0192 def isdir(path):
0193     """Test whether a path is a directory"""
0194     try:
0195         st = os.stat(path)
0196     except os.error:
0197         return False
0198     return stat.S_ISDIR(st.st_mode)
0199 
0200 
0201 # Is a path a regular file?
0202 # This follows symbolic links, so both islink() and isfile() can be true
0203 # for the same path.
0204 
0205 def isfile(path):
0206     """Test whether a path is a regular file"""
0207     try:
0208         st = os.stat(path)
0209     except os.error:
0210         return False
0211     return stat.S_ISREG(st.st_mode)
0212 
0213 
0214 # Are two filenames really pointing to the same file?
0215 
0216 def samefile(f1, f2):
0217     """Test whether two pathnames reference the same actual file"""
0218     s1 = os.stat(f1)
0219     s2 = os.stat(f2)
0220     return samestat(s1, s2)
0221 
0222 
0223 # Are two open files really referencing the same file?
0224 # (Not necessarily the same file descriptor!)
0225 
0226 def sameopenfile(fp1, fp2):
0227     """Test whether two open file objects reference the same file"""
0228     s1 = os.fstat(fp1)
0229     s2 = os.fstat(fp2)
0230     return samestat(s1, s2)
0231 
0232 
0233 # Are two stat buffers (obtained from stat, fstat or lstat)
0234 # describing the same file?
0235 
0236 def samestat(s1, s2):
0237     """Test whether two stat buffers reference the same file"""
0238     return s1.st_ino == s2.st_ino and \
0239            s1.st_dev == s2.st_dev
0240 
0241 
0242 # Is a path a mount point?
0243 # (Does this work for all UNIXes?  Is it even guaranteed to work by Posix?)
0244 
0245 def ismount(path):
0246     """Test whether a path is a mount point"""
0247     try:
0248         s1 = os.stat(path)
0249         s2 = os.stat(join(path, '..'))
0250     except os.error:
0251         return False # It doesn't exist -- so not a mount point :-)
0252     dev1 = s1.st_dev
0253     dev2 = s2.st_dev
0254     if dev1 != dev2:
0255         return True     # path/.. on a different device as path
0256     ino1 = s1.st_ino
0257     ino2 = s2.st_ino
0258     if ino1 == ino2:
0259         return True     # path/.. is the same i-node as path
0260     return False
0261 
0262 
0263 # Directory tree walk.
0264 # For each directory under top (including top itself, but excluding
0265 # '.' and '..'), func(arg, dirname, filenames) is called, where
0266 # dirname is the name of the directory and filenames is the list
0267 # of files (and subdirectories etc.) in the directory.
0268 # The func may modify the filenames list, to implement a filter,
0269 # or to impose a different order of visiting.
0270 
0271 def walk(top, func, arg):
0272     """Directory tree walk with callback function.
0273 
0274     For each directory in the directory tree rooted at top (including top
0275     itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
0276     dirname is the name of the directory, and fnames a list of the names of
0277     the files and subdirectories in dirname (excluding '.' and '..').  func
0278     may modify the fnames list in-place (e.g. via del or slice assignment),
0279     and walk will only recurse into the subdirectories whose names remain in
0280     fnames; this can be used to implement a filter, or to impose a specific
0281     order of visiting.  No semantics are defined for, or required of, arg,
0282     beyond that arg is always passed to func.  It can be used, e.g., to pass
0283     a filename pattern, or a mutable object designed to accumulate
0284     statistics.  Passing None for arg is common."""
0285 
0286     try:
0287         names = os.listdir(top)
0288     except os.error:
0289         return
0290     func(arg, top, names)
0291     for name in names:
0292         name = join(top, name)
0293         try:
0294             st = os.lstat(name)
0295         except os.error:
0296             continue
0297         if stat.S_ISDIR(st.st_mode):
0298             walk(name, func, arg)
0299 
0300 
0301 # Expand paths beginning with '~' or '~user'.
0302 # '~' means $HOME; '~user' means that user's home directory.
0303 # If the path doesn't begin with '~', or if the user or $HOME is unknown,
0304 # the path is returned unchanged (leaving error reporting to whatever
0305 # function is called with the expanded path as argument).
0306 # See also module 'glob' for expansion of *, ? and [...] in pathnames.
0307 # (A function should also be defined to do full *sh-style environment
0308 # variable expansion.)
0309 
0310 def expanduser(path):
0311     """Expand ~ and ~user constructions.  If user or $HOME is unknown,
0312     do nothing."""
0313     if not path.startswith('~'):
0314         return path
0315     i = path.find('/', 1)
0316     if i < 0:
0317         i = len(path)
0318     if i == 1:
0319         if 'HOME' not in os.environ:
0320             import pwd
0321             userhome = pwd.getpwuid(os.getuid()).pw_dir
0322         else:
0323             userhome = os.environ['HOME']
0324     else:
0325         import pwd
0326         try:
0327             pwent = pwd.getpwnam(path[1:i])
0328         except KeyError:
0329             return path
0330         userhome = pwent.pw_dir
0331     if userhome.endswith('/'):
0332         i += 1
0333     return userhome + path[i:]
0334 
0335 
0336 # Expand paths containing shell variable substitutions.
0337 # This expands the forms $variable and ${variable} only.
0338 # Non-existent variables are left unchanged.
0339 
0340 _varprog = None
0341 
0342 def expandvars(path):
0343     """Expand shell variables of form $var and ${var}.  Unknown variables
0344     are left unchanged."""
0345     global _varprog
0346     if '$' not in path:
0347         return path
0348     if not _varprog:
0349         import re
0350         _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
0351     i = 0
0352     while True:
0353         m = _varprog.search(path, i)
0354         if not m:
0355             break
0356         i, j = m.span(0)
0357         name = m.group(1)
0358         if name.startswith('{') and name.endswith('}'):
0359             name = name[1:-1]
0360         if name in os.environ:
0361             tail = path[j:]
0362             path = path[:i] + os.environ[name]
0363             i = len(path)
0364             path += tail
0365         else:
0366             i = j
0367     return path
0368 
0369 
0370 # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
0371 # It should be understood that this may change the meaning of the path
0372 # if it contains symbolic links!
0373 
0374 def normpath(path):
0375     """Normalize path, eliminating double slashes, etc."""
0376     if path == '':
0377         return '.'
0378     initial_slashes = path.startswith('/')
0379     # POSIX allows one or two initial slashes, but treats three or more
0380     # as single slash.
0381     if (initial_slashes and
0382         path.startswith('//') and not path.startswith('///')):
0383         initial_slashes = 2
0384     comps = path.split('/')
0385     new_comps = []
0386     for comp in comps:
0387         if comp in ('', '.'):
0388             continue
0389         if (comp != '..' or (not initial_slashes and not new_comps) or
0390              (new_comps and new_comps[-1] == '..')):
0391             new_comps.append(comp)
0392         elif new_comps:
0393             new_comps.pop()
0394     comps = new_comps
0395     path = '/'.join(comps)
0396     if initial_slashes:
0397         path = '/'*initial_slashes + path
0398     return path or '.'
0399 
0400 
0401 def abspath(path):
0402     """Return an absolute path."""
0403     if not isabs(path):
0404         path = join(os.getcwd(), path)
0405     return normpath(path)
0406 
0407 
0408 # Return a canonical path (i.e. the absolute location of a file on the
0409 # filesystem).
0410 
0411 def realpath(filename):
0412     """Return the canonical path of the specified filename, eliminating any
0413 symbolic links encountered in the path."""
0414     if isabs(filename):
0415         bits = ['/'] + filename.split('/')[1:]
0416     else:
0417         bits = filename.split('/')
0418 
0419     for i in range(2, len(bits)+1):
0420         component = join(*bits[0:i])
0421         # Resolve symbolic links.
0422         if islink(component):
0423             resolved = _resolve_link(component)
0424             if resolved is None:
0425                 # Infinite loop -- return original component + rest of the path
0426                 return abspath(join(*([component] + bits[i:])))
0427             else:
0428                 newpath = join(*([resolved] + bits[i:]))
0429                 return realpath(newpath)
0430 
0431     return abspath(filename)
0432 
0433 
0434 def _resolve_link(path):
0435     """Internal helper function.  Takes a path and follows symlinks
0436     until we either arrive at something that isn't a symlink, or
0437     encounter a path we've seen before (meaning that there's a loop).
0438     """
0439     paths_seen = []
0440     while islink(path):
0441         if path in paths_seen:
0442             # Already seen this path, so we must have a symlink loop
0443             return None
0444         paths_seen.append(path)
0445         # Resolve where the link points to
0446         resolved = os.readlink(path)
0447         if not isabs(resolved):
0448             dir = dirname(path)
0449             path = normpath(join(dir, resolved))
0450         else:
0451             path = normpath(resolved)
0452     return path
0453 
0454 supports_unicode_filenames = False
0455 

Generated by PyXR 0.9.4
SourceForge.net Logo