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