10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Module 'ntpath' -- common operations on WinNT/Win95 pathnames
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""Common pathname manipulations, WindowsNT/95 version.
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiInstead of importing this module directly, import os and refer to this
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimodule as os.path.
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport os
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport stat
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport genericpath
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport warnings
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom genericpath import *
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "basename","dirname","commonprefix","getsize","getmtime",
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "getatime","getctime", "islink","exists","lexists","isdir","isfile",
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "ismount","walk","expanduser","expandvars","normpath","abspath",
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "extsep","devnull","realpath","supports_unicode_filenames","relpath"]
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# strings representing various path-related bits and pieces
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yicurdir = '.'
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipardir = '..'
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiextsep = '.'
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yisep = '\\'
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipathsep = ';'
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yialtsep = '/'
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefpath = '.;C:\\bin'
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif 'ce' in sys.builtin_module_names:
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    defpath = '\\Windows'
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yielif 'os2' in sys.builtin_module_names:
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # OS/2 w/ VACPP
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    altsep = '/'
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidevnull = 'nul'
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Normalize the case of a pathname and map slashes to backslashes.
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Other normalizations (such as optimizing '../' away) are not done
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# (this is done by normpath).
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef normcase(s):
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Normalize case of pathname.
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Makes all characters lowercase and all slashes into backslashes."""
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return s.replace("/", "\\").lower()
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Return whether a path is absolute.
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Trivial in Posix, harder on the Mac or MS-DOS.
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# For DOS it is absolute if it starts with a slash or backslash (current
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# volume), or if a pathname after the volume letter and colon / UNC resource
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# starts with a slash or backslash.
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef isabs(s):
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Test whether a path is absolute"""
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    s = splitdrive(s)[1]
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return s != '' and s[:1] in '/\\'
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Join two (or more) paths.
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef join(a, *p):
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Join two or more pathname components, inserting "\\" as needed.
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    If any component is an absolute path, all previous path components
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    will be discarded."""
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    path = a
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for b in p:
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        b_wins = 0  # set to 1 iff b makes path irrelevant
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if path == "":
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            b_wins = 1
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isabs(b):
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # This probably wipes out path so far.  However, it's more
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # complicated if path begins with a drive letter:
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            #     1. join('c:', '/a') == 'c:/a'
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            #     2. join('c:/', '/a') == 'c:/a'
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # But
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            #     3. join('c:/a', '/b') == '/b'
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            #     4. join('c:', 'd:/') = 'd:/'
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            #     5. join('c:/', 'd:/') = 'd:/'
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if path[1:2] != ":" or b[1:2] == ":":
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # Path doesn't start with a drive letter, or cases 4 and 5.
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                b_wins = 1
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # Else path has a drive letter, and b doesn't but is absolute.
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif len(path) > 3 or (len(path) == 3 and
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                   path[-1] not in "/\\"):
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # case 3
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                b_wins = 1
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if b_wins:
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            path = b
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # Join, and ensure there's a separator.
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            assert len(path) > 0
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if path[-1] in "/\\":
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if b and b[0] in "/\\":
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    path += b[1:]
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    path += b
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif path[-1] == ":":
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                path += b
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif b:
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if b[0] in "/\\":
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    path += b
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    path += "\\" + b
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # path is not empty and does not end with a backslash,
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # but b is empty; since, e.g., split('a/') produces
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # ('a', ''), it's best if join() adds a backslash in
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # this case.
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                path += '\\'
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return path
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Split a path in a drive specification (a drive letter followed by a
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# colon) and the path specification.
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# It is always true that drivespec + pathspec == p
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef splitdrive(p):
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Split a pathname into drive and path specifiers. Returns a 2-tuple
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"(drive,path)";  either part may be empty"""
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if p[1:2] == ':':
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return p[0:2], p[2:]
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return '', p
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Parse UNC paths
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef splitunc(p):
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Split a pathname into UNC mount point and relative path specifiers.
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Return a 2-tuple (unc, rest); either part may be empty.
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    If unc is not empty, it has the form '//host/mount' (or similar
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    using backslashes).  unc+rest is always the input path.
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Paths containing drive letters never have an UNC part.
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if p[1:2] == ':':
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return '', p # Drive letter present
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    firstTwo = p[0:2]
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if firstTwo == '//' or firstTwo == '\\\\':
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # is a UNC path:
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # \\machine\mountpoint\directories...
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #           directory ^^^^^^^^^^^^^^^
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        normp = normcase(p)
1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        index = normp.find('\\', 2)
1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if index == -1:
1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return ("", p)
1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        index = normp.find('\\', index + 1)
1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if index == -1:
1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            index = len(p)
1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return p[:index], p[index:]
1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return '', p
1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Split a path in head (everything up to the last '/') and tail (the
1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# rest).  After the trailing '/' is stripped, the invariant
1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# join(head, tail) == p holds.
1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The resulting head won't end in '/' unless it is the root.
1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef split(p):
1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Split a pathname.
1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Return tuple (head, tail) where tail is everything after the final slash.
1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Either part may be empty."""
1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    d, p = splitdrive(p)
1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # set i to index beyond p's last slash
1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    i = len(p)
1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    while i and p[i-1] not in '/\\':
1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        i = i - 1
1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    head, tail = p[:i], p[i:]  # now tail has no slashes
1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # remove trailing slashes from head, unless it's all slashes
1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    head2 = head
1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    while head2 and head2[-1] in '/\\':
1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        head2 = head2[:-1]
1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    head = head2 or head
1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return d + head, tail
1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Split a path in root and extension.
1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The extension is everything starting at the last dot in the last
1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# pathname component; the root is everything before that.
1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# It is always true that root + ext == p.
1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef splitext(p):
1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return genericpath._splitext(p, sep, altsep, extsep)
1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yisplitext.__doc__ = genericpath._splitext.__doc__
1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Return the tail (basename) part of a path.
1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef basename(p):
1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Returns the final component of a pathname"""
1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return split(p)[1]
1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Return the head (dirname) part of a path.
2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef dirname(p):
2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Returns the directory component of a pathname"""
2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return split(p)[0]
2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Is a path a symbolic link?
2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# This will always return false on systems where posix.lstat doesn't exist.
2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef islink(path):
2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Test for symbolic link.
2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    On WindowsNT/95 and OS/2 always returns false
2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return False
2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# alias exists to lexists
2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yilexists = exists
2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Is a path a mount point?  Either a root (with or without drive letter)
2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# or an UNC path with at most a / or \ after the mount point.
2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef ismount(path):
2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Test whether a path is a mount point (defined as root of drive)"""
2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    unc, rest = splitunc(path)
2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if unc:
2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return rest in ("", "/", "\\")
2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    p = splitdrive(path)[1]
2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return len(p) == 1 and p[0] in '/\\'
2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Directory tree walk.
2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# For each directory under top (including top itself, but excluding
2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# '.' and '..'), func(arg, dirname, filenames) is called, where
2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# dirname is the name of the directory and filenames is the list
2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# of files (and subdirectories etc.) in the directory.
2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The func may modify the filenames list, to implement a filter,
2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# or to impose a different order of visiting.
2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef walk(top, func, arg):
2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Directory tree walk with callback function.
2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    For each directory in the directory tree rooted at top (including top
2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    dirname is the name of the directory, and fnames a list of the names of
2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    the files and subdirectories in dirname (excluding '.' and '..').  func
2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    may modify the fnames list in-place (e.g. via del or slice assignment),
2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    and walk will only recurse into the subdirectories whose names remain in
2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    fnames; this can be used to implement a filter, or to impose a specific
2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    order of visiting.  No semantics are defined for, or required of, arg,
2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    beyond that arg is always passed to func.  It can be used, e.g., to pass
2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    a filename pattern, or a mutable object designed to accumulate
2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    statistics.  Passing None for arg is common."""
2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",
2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      stacklevel=2)
2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    try:
2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        names = os.listdir(top)
2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    except os.error:
2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return
2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    func(arg, top, names)
2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for name in names:
2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        name = join(top, name)
2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isdir(name):
2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            walk(name, func, arg)
2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Expand paths beginning with '~' or '~user'.
2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# '~' means $HOME; '~user' means that user's home directory.
2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# If the path doesn't begin with '~', or if the user or $HOME is unknown,
2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# the path is returned unchanged (leaving error reporting to whatever
2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# function is called with the expanded path as argument).
2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# See also module 'glob' for expansion of *, ? and [...] in pathnames.
2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# (A function should also be defined to do full *sh-style environment
2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# variable expansion.)
2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef expanduser(path):
2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Expand ~ and ~user constructs.
2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    If user or $HOME is unknown, do nothing."""
2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if path[:1] != '~':
2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return path
2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    i, n = 1, len(path)
2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    while i < n and path[i] not in '/\\':
2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        i = i + 1
2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if 'HOME' in os.environ:
2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        userhome = os.environ['HOME']
2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    elif 'USERPROFILE' in os.environ:
2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        userhome = os.environ['USERPROFILE']
2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    elif not 'HOMEPATH' in os.environ:
2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return path
2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    else:
2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            drive = os.environ['HOMEDRIVE']
2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except KeyError:
2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            drive = ''
2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        userhome = join(drive, os.environ['HOMEPATH'])
2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if i != 1: #~user
2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        userhome = join(dirname(userhome), path[1:i])
3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return userhome + path[i:]
3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Expand paths containing shell variable substitutions.
3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# The following rules apply:
3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#       - no expansion within single quotes
3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#       - '$$' is translated into '$'
3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#       - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%
3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#       - ${varname} is accepted.
3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#       - $varname is accepted.
3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#       - %varname% is accepted.
3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#       - varnames can be made out of letters, digits and the characters '_-'
3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#         (though is not verified in the ${varname} and %varname% cases)
3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# XXX With COMMAND.COM you can use any characters in a variable name,
3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# XXX except '^|<>='.
3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef expandvars(path):
3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Expand shell variables of the forms $var, ${var} and %var%.
3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Unknown variables are left unchanged."""
3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if '$' not in path and '%' not in path:
3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return path
3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    import string
3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    varchars = string.ascii_letters + string.digits + '_-'
3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    res = ''
3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    index = 0
3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    pathlen = len(path)
3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    while index < pathlen:
3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = path[index]
3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if c == '\'':   # no expansion within single quotes
3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            path = path[index + 1:]
3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pathlen = len(path)
3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                index = path.index('\'')
3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                res = res + '\'' + path[:index + 1]
3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except ValueError:
3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                res = res + path
3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                index = pathlen - 1
3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif c == '%':  # variable or '%'
3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if path[index + 1:index + 2] == '%':
3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                res = res + c
3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                index = index + 1
3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                path = path[index+1:]
3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pathlen = len(path)
3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                try:
3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    index = path.index('%')
3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                except ValueError:
3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    res = res + '%' + path
3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    index = pathlen - 1
3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    var = path[:index]
3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    if var in os.environ:
3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        res = res + os.environ[var]
3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    else:
3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        res = res + '%' + var + '%'
3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif c == '$':  # variable or '$$'
3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if path[index + 1:index + 2] == '$':
3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                res = res + c
3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                index = index + 1
3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif path[index + 1:index + 2] == '{':
3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                path = path[index+2:]
3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pathlen = len(path)
3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                try:
3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    index = path.index('}')
3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    var = path[:index]
3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    if var in os.environ:
3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        res = res + os.environ[var]
3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    else:
3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        res = res + '${' + var + '}'
3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                except ValueError:
3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    res = res + '${' + path
3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    index = pathlen - 1
3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                var = ''
3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                index = index + 1
3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                c = path[index:index + 1]
3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                while c != '' and c in varchars:
3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    var = var + c
3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    index = index + 1
3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    c = path[index:index + 1]
3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if var in os.environ:
3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    res = res + os.environ[var]
3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    res = res + '$' + var
3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if c != '':
3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    index = index - 1
3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            res = res + c
3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        index = index + 1
3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return res
3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
3950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Previously, this function also truncated pathnames to 8+3 format,
3960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# but as this module is called "ntpath", that's obviously wrong!
3970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef normpath(path):
3990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Normalize path, eliminating double slashes, etc."""
4000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Preserve unicode (if path is unicode)
4010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    backslash, dot = (u'\\', u'.') if isinstance(path, unicode) else ('\\', '.')
4020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if path.startswith(('\\\\.\\', '\\\\?\\')):
4030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # in the case of paths with these prefixes:
4040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # \\.\ -> device names
4050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # \\?\ -> literal paths
4060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # do not do any normalization, but return the path unchanged
4070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return path
4080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    path = path.replace("/", "\\")
4090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    prefix, path = splitdrive(path)
4100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # We need to be careful here. If the prefix is empty, and the path starts
4110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # with a backslash, it could either be an absolute path on the current
4120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
4130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # is therefore imperative NOT to collapse multiple backslashes blindly in
4140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # that case.
4150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # The code below preserves multiple backslashes when there is no drive
4160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # letter. This means that the invalid filename \\\a\b is preserved
4170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # unchanged, where a\\\b is normalised to a\b. It's not clear that there
4180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # is any better behaviour for such edge cases.
4190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if prefix == '':
4200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # No drive letter - preserve initial backslashes
4210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        while path[:1] == "\\":
4220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            prefix = prefix + backslash
4230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            path = path[1:]
4240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    else:
4250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # We have a drive letter - collapse initial backslashes
4260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if path.startswith("\\"):
4270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            prefix = prefix + backslash
4280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            path = path.lstrip("\\")
4290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    comps = path.split("\\")
4300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    i = 0
4310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    while i < len(comps):
4320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if comps[i] in ('.', ''):
4330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            del comps[i]
4340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif comps[i] == '..':
4350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if i > 0 and comps[i-1] != '..':
4360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                del comps[i-1:i+1]
4370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                i -= 1
4380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif i == 0 and prefix.endswith("\\"):
4390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                del comps[i]
4400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
4410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                i += 1
4420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
4430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            i += 1
4440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # If the path is now empty, substitute '.'
4450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if not prefix and not comps:
4460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        comps.append(dot)
4470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return prefix + backslash.join(comps)
4480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Return an absolute path.
4510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry:
4520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    from nt import _getfullpathname
4530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept ImportError: # not running on Windows - mock up something sensible
4550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def abspath(path):
4560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the absolute version of a path."""
4570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not isabs(path):
4580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(path, unicode):
4590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                cwd = os.getcwdu()
4600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
4610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                cwd = os.getcwd()
4620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            path = join(cwd, path)
4630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return normpath(path)
4640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yielse:  # use native Windows method on Windows
4660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def abspath(path):
4670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the absolute version of a path."""
4680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if path: # Empty path must return current working directory.
4700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
4710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                path = _getfullpathname(path)
4720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except WindowsError:
4730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass # Bad path - return unchanged.
4740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(path, unicode):
4750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            path = os.getcwdu()
4760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
4770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            path = os.getcwd()
4780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return normpath(path)
4790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# realpath is a no-op on systems without islink support
4810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yirealpath = abspath
4820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Win9x family and earlier have no Unicode filename support.
4830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yisupports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
4840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              sys.getwindowsversion()[3] >= 2)
4850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _abspath_split(path):
4870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    abs = abspath(normpath(path))
4880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    prefix, rest = splitunc(abs)
4890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    is_unc = bool(prefix)
4900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if not is_unc:
4910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        prefix, rest = splitdrive(abs)
4920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return is_unc, prefix, [x for x in rest.split(sep) if x]
4930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef relpath(path, start=curdir):
4950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Return a relative version of a path"""
4960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if not path:
4980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        raise ValueError("no path specified")
4990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    start_is_unc, start_prefix, start_list = _abspath_split(start)
5010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    path_is_unc, path_prefix, path_list = _abspath_split(path)
5020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if path_is_unc ^ start_is_unc:
5040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
5050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                            % (path, start))
5060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if path_prefix.lower() != start_prefix.lower():
5070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if path_is_unc:
5080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise ValueError("path is on UNC root %s, start on UNC root %s"
5090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                % (path_prefix, start_prefix))
5100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
5110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise ValueError("path is on drive %s, start on drive %s"
5120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                % (path_prefix, start_prefix))
5130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Work out how much of the filepath is shared by start and path.
5140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    i = 0
5150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for e1, e2 in zip(start_list, path_list):
5160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if e1.lower() != e2.lower():
5170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            break
5180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        i += 1
5190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
5210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if not rel_list:
5220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return curdir
5230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return join(*rel_list)
5240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry:
5260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # The genericpath.isdir implementation uses os.stat and checks the mode
5270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # attribute to tell whether or not the path is a directory.
5280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # This is overkill on Windows - just pass the path to GetFileAttributes
5290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # and check the attribute from there.
5300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    from nt import _isdir as isdir
5310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept ImportError:
5320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Use genericpath.isdir as imported above.
5330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    pass
534