10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""Common operations on Posix pathnames. 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 30a8c90248264a8b26970b4473770bcc3df8515fJosh GaoInstead of importing this module directly, import os and refer to 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaothis module as os.path. The "os.path" name is an alias for this 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaomodule on Posix systems; on other systems (e.g. Mac, Windows), 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoos.path provides the same operations in a manner specific to that 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoplatform, and is an alias to another module (e.g. macpath, ntpath). 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 90a8c90248264a8b26970b4473770bcc3df8515fJosh GaoSome of this can actually be useful on non-Posix systems too, e.g. 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofor manipulation of the pathname component of URLs. 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao""" 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport stat 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport genericpath 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport warnings 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom genericpath import * 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry: 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _unicode = unicode 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept NameError: 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # If Python is built without Unicode support, the unicode type 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # will not exist. Fake one. 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class _unicode(object): 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__all__ = ["normcase","isabs","join","splitdrive","split","splitext", 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "basename","dirname","commonprefix","getsize","getmtime", 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "getatime","getctime","islink","exists","lexists","isdir","isfile", 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "ismount","walk","expanduser","expandvars","normpath","abspath", 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "samefile","sameopenfile","samestat", 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "curdir","pardir","sep","pathsep","defpath","altsep","extsep", 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "devnull","realpath","supports_unicode_filenames","relpath"] 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# strings representing various path-related bits and pieces 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gaocurdir = '.' 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gaopardir = '..' 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoextsep = '.' 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gaosep = '/' 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaopathsep = ':' 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodefpath = ':/bin:/usr/bin' 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoaltsep = None 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodevnull = '/dev/null' 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Normalize the case of a pathname. Trivial in Posix, string.lower on Mac. 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# On MS-DOS this may also turn slashes into backslashes; however, other 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# normalizations (such as optimizing '../' away) are not allowed 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# (another function should be defined to do that). 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef normcase(s): 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Normalize case of pathname. Has no effect under Posix""" 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return s 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Return whether a path is absolute. 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Trivial in Posix, harder on the Mac or MS-DOS. 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef isabs(s): 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Test whether a path is absolute""" 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return s.startswith('/') 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Join pathnames. 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Ignore the previous parts if a part is absolute. 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Insert a '/' unless the first part is empty or already ends in '/'. 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef join(a, *p): 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Join two or more pathname components, inserting '/' as needed. 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If any component is an absolute path, all previous path components 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao will be discarded. An empty last part will result in a path that 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ends with a separator.""" 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = a 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for b in p: 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if b.startswith('/'): 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = b 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif path == '' or path.endswith('/'): 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path += b 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path += '/' + b 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return path 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Split a path in head (everything up to the last '/') and tail (the 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# rest). If the path ends in '/', tail will be empty. If there is no 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# '/' in the path, head will be empty. 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Trailing '/'es are stripped from head unless it is the root. 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef split(p): 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Split a pathname. Returns tuple "(head, tail)" where "tail" is 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao everything after the final slash. Either part may be empty.""" 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = p.rfind('/') + 1 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao head, tail = p[:i], p[i:] 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if head and head != '/'*len(head): 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao head = head.rstrip('/') 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return head, tail 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Split a path in root and extension. 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# The extension is everything starting at the last dot in the last 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# pathname component; the root is everything before that. 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# It is always true that root + ext == p. 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef splitext(p): 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return genericpath._splitext(p, sep, altsep, extsep) 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gaosplitext.__doc__ = genericpath._splitext.__doc__ 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Split a pathname into a drive specification and the rest of the 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# path. Useful on DOS/Windows/NT; on Unix, the drive is always empty. 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef splitdrive(p): 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Split a pathname into drive and path. On Posix, drive is always 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao empty.""" 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return '', p 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Return the tail (basename) part of a path, same as split(path)[1]. 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef basename(p): 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Returns the final component of a pathname""" 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = p.rfind('/') + 1 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return p[i:] 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Return the head (dirname) part of a path, same as split(path)[0]. 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef dirname(p): 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Returns the directory component of a pathname""" 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = p.rfind('/') + 1 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao head = p[:i] 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if head and head != '/'*len(head): 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao head = head.rstrip('/') 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return head 1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Is a path a symbolic link? 1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This will always return false on systems where os.lstat doesn't exist. 1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef islink(path): 1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Test whether a path is a symbolic link""" 1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao st = os.lstat(path) 1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (os.error, AttributeError): 1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return False 1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return stat.S_ISLNK(st.st_mode) 1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Being true for dangling symbolic links is also useful. 1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef lexists(path): 1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Test whether a path exists. Returns True for broken symbolic links""" 1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao os.lstat(path) 1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except os.error: 1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return False 1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True 1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Are two filenames really pointing to the same file? 1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef samefile(f1, f2): 1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Test whether two pathnames reference the same actual file""" 1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s1 = os.stat(f1) 1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s2 = os.stat(f2) 1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return samestat(s1, s2) 1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Are two open files really referencing the same file? 1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# (Not necessarily the same file descriptor!) 1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef sameopenfile(fp1, fp2): 1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Test whether two open file objects reference the same file""" 1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s1 = os.fstat(fp1) 1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s2 = os.fstat(fp2) 1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return samestat(s1, s2) 1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Are two stat buffers (obtained from stat, fstat or lstat) 1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# describing the same file? 1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef samestat(s1, s2): 1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Test whether two stat buffers reference the same file""" 1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return s1.st_ino == s2.st_ino and \ 1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s1.st_dev == s2.st_dev 1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Is a path a mount point? 1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# (Does this work for all UNIXes? Is it even guaranteed to work by Posix?) 1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef ismount(path): 1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Test whether a path is a mount point""" 1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if islink(path): 1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # A symlink can never be a mount point 1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return False 1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s1 = os.lstat(path) 1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s2 = os.lstat(join(path, '..')) 1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except os.error: 1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return False # It doesn't exist -- so not a mount point :-) 1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dev1 = s1.st_dev 2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dev2 = s2.st_dev 2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if dev1 != dev2: 2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True # path/.. on a different device as path 2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ino1 = s1.st_ino 2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ino2 = s2.st_ino 2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if ino1 == ino2: 2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True # path/.. is the same i-node as path 2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return False 2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Directory tree walk. 2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# For each directory under top (including top itself, but excluding 2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# '.' and '..'), func(arg, dirname, filenames) is called, where 2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# dirname is the name of the directory and filenames is the list 2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# of files (and subdirectories etc.) in the directory. 2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# The func may modify the filenames list, to implement a filter, 2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# or to impose a different order of visiting. 2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef walk(top, func, arg): 2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Directory tree walk with callback function. 2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao For each directory in the directory tree rooted at top (including top 2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao itself, but excluding '.' and '..'), call func(arg, dirname, fnames). 2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dirname is the name of the directory, and fnames a list of the names of 2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao the files and subdirectories in dirname (excluding '.' and '..'). func 2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao may modify the fnames list in-place (e.g. via del or slice assignment), 2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao and walk will only recurse into the subdirectories whose names remain in 2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fnames; this can be used to implement a filter, or to impose a specific 2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao order of visiting. No semantics are defined for, or required of, arg, 2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao beyond that arg is always passed to func. It can be used, e.g., to pass 2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao a filename pattern, or a mutable object designed to accumulate 2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao statistics. Passing None for arg is common.""" 2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.", 2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao stacklevel=2) 2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao names = os.listdir(top) 2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except os.error: 2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao func(arg, top, names) 2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for name in names: 2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao name = join(top, name) 2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao st = os.lstat(name) 2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except os.error: 2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if stat.S_ISDIR(st.st_mode): 2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao walk(name, func, arg) 2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Expand paths beginning with '~' or '~user'. 2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# '~' means $HOME; '~user' means that user's home directory. 2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# If the path doesn't begin with '~', or if the user or $HOME is unknown, 2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# the path is returned unchanged (leaving error reporting to whatever 2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# function is called with the expanded path as argument). 2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# See also module 'glob' for expansion of *, ? and [...] in pathnames. 2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# (A function should also be defined to do full *sh-style environment 2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# variable expansion.) 2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef expanduser(path): 2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Expand ~ and ~user constructions. If user or $HOME is unknown, 2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao do nothing.""" 2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not path.startswith('~'): 2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return path 2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = path.find('/', 1) 2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if i < 0: 2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = len(path) 2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if i == 1: 2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 'HOME' not in os.environ: 2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import pwd 2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao userhome = pwd.getpwuid(os.getuid()).pw_dir 2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao userhome = os.environ['HOME'] 2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import pwd 2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pwent = pwd.getpwnam(path[1:i]) 2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except KeyError: 2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return path 2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao userhome = pwent.pw_dir 2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao userhome = userhome.rstrip('/') 2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return (userhome + path[i:]) or '/' 2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Expand paths containing shell variable substitutions. 2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This expands the forms $variable and ${variable} only. 2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Non-existent variables are left unchanged. 2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_varprog = None 2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef expandvars(path): 2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Expand shell variables of form $var and ${var}. Unknown variables 2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao are left unchanged.""" 2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao global _varprog 2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if '$' not in path: 2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return path 2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not _varprog: 2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import re 2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _varprog = re.compile(r'\$(\w+|\{[^}]*\})') 2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = 0 2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while True: 3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao m = _varprog.search(path, i) 3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not m: 3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i, j = m.span(0) 3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao name = m.group(1) 3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name.startswith('{') and name.endswith('}'): 3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao name = name[1:-1] 3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name in os.environ: 3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao tail = path[j:] 3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = path[:i] + os.environ[name] 3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = len(path) 3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path += tail 3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = j 3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return path 3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. 3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# It should be understood that this may change the meaning of the path 3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# if it contains symbolic links! 3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef normpath(path): 3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Normalize path, eliminating double slashes, etc.""" 3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Preserve unicode (if path is unicode) 3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao slash, dot = (u'/', u'.') if isinstance(path, _unicode) else ('/', '.') 3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if path == '': 3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return dot 3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao initial_slashes = path.startswith('/') 3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # POSIX allows one or two initial slashes, but treats three or more 3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # as single slash. 3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if (initial_slashes and 3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path.startswith('//') and not path.startswith('///')): 3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao initial_slashes = 2 3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao comps = path.split('/') 3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao new_comps = [] 3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for comp in comps: 3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if comp in ('', '.'): 3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if (comp != '..' or (not initial_slashes and not new_comps) or 3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (new_comps and new_comps[-1] == '..')): 3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao new_comps.append(comp) 3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif new_comps: 3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao new_comps.pop() 3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao comps = new_comps 3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = slash.join(comps) 3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if initial_slashes: 3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = slash*initial_slashes + path 3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return path or dot 3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef abspath(path): 3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Return an absolute path.""" 3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not isabs(path): 3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if isinstance(path, _unicode): 3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cwd = os.getcwdu() 3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cwd = os.getcwd() 3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = join(cwd, path) 3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return normpath(path) 3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Return a canonical path (i.e. the absolute location of a file on the 3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# filesystem). 3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef realpath(filename): 3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Return the canonical path of the specified filename, eliminating any 3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaosymbolic links encountered in the path.""" 3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path, ok = _joinrealpath('', filename, {}) 3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return abspath(path) 3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Join two paths, normalizing ang eliminating any symbolic links 3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# encountered in the second path. 3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _joinrealpath(path, rest, seen): 3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if isabs(rest): 3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao rest = rest[1:] 3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = sep 3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while rest: 3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao name, _, rest = rest.partition(sep) 3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not name or name == curdir: 3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # current dir 3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name == pardir: 3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # parent dir 3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if path: 3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path, name = split(path) 3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name == pardir: 3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = join(path, pardir, pardir) 3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = pardir 3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao newpath = join(path, name) 3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not islink(newpath): 3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = newpath 3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Resolve the symbolic link 3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if newpath in seen: 3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Already seen this path 3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = seen[newpath] 3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if path is not None: 4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # use cached value 4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # The symlink is not resolved, so we must have a symlink loop. 4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Return already resolved part + rest of the path unchanged. 4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return join(newpath, rest), False 4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao seen[newpath] = None # not resolved symlink 4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path, ok = _joinrealpath(path, os.readlink(newpath), seen) 4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not ok: 4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return join(path, rest), False 4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao seen[newpath] = path # resolved symlink 4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return path, True 4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaosupports_unicode_filenames = (sys.platform == 'darwin') 4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef relpath(path, start=curdir): 4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Return a relative version of a path""" 4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not path: 4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise ValueError("no path specified") 4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao start_list = [x for x in abspath(start).split(sep) if x] 4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path_list = [x for x in abspath(path).split(sep) if x] 4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Work out how much of the filepath is shared by start and path. 4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao i = len(commonprefix([start_list, path_list])) 4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao rel_list = [pardir] * (len(start_list)-i) + path_list[i:] 4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not rel_list: 4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return curdir 4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return join(*rel_list) 432