1"""
2Path operations common to more than one OS
3Do not use directly.  The OS specific modules import the appropriate
4functions from this module themselves.
5"""
6import os
7import stat
8
9__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
10           'getsize', 'isdir', 'isfile']
11
12
13try:
14    _unicode = unicode
15except NameError:
16    # If Python is built without Unicode support, the unicode type
17    # will not exist. Fake one.
18    class _unicode(object):
19        pass
20
21# Does a path exist?
22# This is false for dangling symbolic links on systems that support them.
23def exists(path):
24    """Test whether a path exists.  Returns False for broken symbolic links"""
25    try:
26        os.stat(path)
27    except os.error:
28        return False
29    return True
30
31
32# This follows symbolic links, so both islink() and isdir() can be true
33# for the same path on systems that support symlinks
34def isfile(path):
35    """Test whether a path is a regular file"""
36    try:
37        st = os.stat(path)
38    except os.error:
39        return False
40    return stat.S_ISREG(st.st_mode)
41
42
43# Is a path a directory?
44# This follows symbolic links, so both islink() and isdir()
45# can be true for the same path on systems that support symlinks
46def isdir(s):
47    """Return true if the pathname refers to an existing directory."""
48    try:
49        st = os.stat(s)
50    except os.error:
51        return False
52    return stat.S_ISDIR(st.st_mode)
53
54
55def getsize(filename):
56    """Return the size of a file, reported by os.stat()."""
57    return os.stat(filename).st_size
58
59
60def getmtime(filename):
61    """Return the last modification time of a file, reported by os.stat()."""
62    return os.stat(filename).st_mtime
63
64
65def getatime(filename):
66    """Return the last access time of a file, reported by os.stat()."""
67    return os.stat(filename).st_atime
68
69
70def getctime(filename):
71    """Return the metadata change time of a file, reported by os.stat()."""
72    return os.stat(filename).st_ctime
73
74
75# Return the longest prefix of all list elements.
76def commonprefix(m):
77    "Given a list of pathnames, returns the longest common leading component"
78    if not m: return ''
79    s1 = min(m)
80    s2 = max(m)
81    for i, c in enumerate(s1):
82        if c != s2[i]:
83            return s1[:i]
84    return s1
85
86# Split a path in root and extension.
87# The extension is everything starting at the last dot in the last
88# pathname component; the root is everything before that.
89# It is always true that root + ext == p.
90
91# Generic implementation of splitext, to be parametrized with
92# the separators
93def _splitext(p, sep, altsep, extsep):
94    """Split the extension from a pathname.
95
96    Extension is everything from the last dot to the end, ignoring
97    leading dots.  Returns "(root, ext)"; ext may be empty."""
98
99    sepIndex = p.rfind(sep)
100    if altsep:
101        altsepIndex = p.rfind(altsep)
102        sepIndex = max(sepIndex, altsepIndex)
103
104    dotIndex = p.rfind(extsep)
105    if dotIndex > sepIndex:
106        # skip all leading dots
107        filenameIndex = sepIndex + 1
108        while filenameIndex < dotIndex:
109            if p[filenameIndex] != extsep:
110                return p[:dotIndex], p[dotIndex:]
111            filenameIndex += 1
112
113    return p, ''
114