util.py revision 2689e3ddce70e8acc5bc231a80221980d5bdfec3
12689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward"""distutils.util 22689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 32689e3ddce70e8acc5bc231a80221980d5bdfec3Greg WardGeneral-purpose utility functions used throughout the Distutils 42689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward(especially in command classes). Mostly filesystem manipulation, but 52689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Wardnot limited to that. The functions in this module generally raise 62689e3ddce70e8acc5bc231a80221980d5bdfec3Greg WardDistutilsFileError when they have problems with the filesystem, because 72689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Wardos.error in pre-1.5.2 Python only gives the error message and not the 82689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Wardfile causing it.""" 92689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 102689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# created 1999/03/08, Greg Ward 112689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 122689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward__rcsid__ = "$Id$" 132689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 142689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Wardimport os 152689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Wardfrom distutils.errors import * 162689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 172689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 182689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# I don't use os.makedirs because a) it's new to Python 1.5.2, and 192689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# b) it blows up if the directory already exists (I want to silently 202689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# succeed in that case). 212689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Warddef mkpath (name, mode=0777, verbose=0): 222689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward """Create a directory and any missing ancestor directories. If the 232689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward directory already exists, return silently. Raise 242689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward DistutilsFileError if unable to create some directory along the 252689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward way (eg. some sub-path exists, but is a file rather than a 262689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward directory). If 'verbose' is true, print a one-line summary of 272689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward each mkdir to stdout.""" 282689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 292689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward # XXX what's the better way to handle verbosity? print as we create 302689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward # each directory in the path (the current behaviour), or only announce 312689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward # the creation of the whole path, and force verbose=0 on all sub-calls? 322689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 332689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if os.path.isdir (name): 342689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward return 352689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 362689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward (head, tail) = os.path.split (name) 372689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward tails = [tail] # stack of lone dirs to create 382689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 392689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward while head and tail and not os.path.isdir (head): 402689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward #print "splitting '%s': " % head, 412689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward (head, tail) = os.path.split (head) 422689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward #print "to ('%s','%s')" % (head, tail) 432689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward tails.insert (0, tail) # push next higher dir onto stack 442689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 452689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward #print "stack of tails:", tails 462689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 472689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward # now 'head' contains the highest directory that already exists 482689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward for d in tails: 492689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward #print "head = %s, d = %s: " % (head, d), 502689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward head = os.path.join (head, d) 512689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if verbose: 522689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward print "creating", head 532689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward try: 542689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward os.mkdir (head) 552689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward except os.error, (errno, errstr): 562689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, "%s: %s" % (head, errstr) 572689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 582689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# mkpath () 592689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 602689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 612689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Warddef newer (file1, file2): 622689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward """Return true if file1 exists and is more recently modified than 632689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward file2, or if file1 exists and file2 doesn't. Return false if both 642689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward exist and file2 is the same age or younger than file1. Raises 652689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward DistutilsFileError if file1 does not exist.""" 662689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 672689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if not os.path.exists (file1): 682689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, "file '%s' does not exist" % file1 692689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if not os.path.exists (file2): 702689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward return 1 712689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 722689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward from stat import * 732689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward mtime1 = os.stat(file1)[ST_MTIME] 742689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward mtime2 = os.stat(file2)[ST_MTIME] 752689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 762689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward return mtime1 > mtime2 772689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 782689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# newer () 792689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 802689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 812689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Warddef make_file (src, dst, func, args, 822689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward verbose=0, update_message=None, noupdate_message=None): 832689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward """Makes 'dst' from 'src' (both filenames) by calling 'func' with 842689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'args', but only if it needs to: i.e. if 'dst' does not exist or 852689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'src' is newer than 'dst'.""" 862689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 872689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if newer (src, dst): 882689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if verbose and update_message: 892689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward print update_message 902689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward apply (func, args) 912689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward else: 922689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if verbose and noupdate_message: 932689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward print noupdate_message 942689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 952689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# make_file () 962689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 972689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 982689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Warddef _copy_file_contents (src, dst, buffer_size=16*1024): 992689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward """Copy the file 'src' to 'dst'; both must be filenames. Any error 1002689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward opening either file, reading from 'src', or writing to 'dst', 1012689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raises DistutilsFileError. Data is read/written in chunks of 1022689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'buffer_size' bytes (default 16k). No attempt is made to handle 1032689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward anything apart from regular files.""" 1042689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1052689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward # Stolen from shutil module in the standard library, but with 1062689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward # custom error-handling added. 1072689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1082689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward fsrc = None 1092689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward fdst = None 1102689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward try: 1112689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward try: 1122689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward fsrc = open(src, 'rb') 1132689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward except os.error, (errno, errstr): 1142689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, "could not open %s: %s" % (src, errstr) 1152689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1162689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward try: 1172689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward fdst = open(dst, 'wb') 1182689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward except os.error, (errno, errstr): 1192689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, "could not create %s: %s" % (dst, errstr) 1202689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1212689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward while 1: 1222689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward try: 1232689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward buf = fsrc.read (buffer_size) 1242689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward except os.error, (errno, errstr): 1252689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, \ 1262689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward "could not read from %s: %s" % (src, errstr) 1272689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1282689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if not buf: 1292689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward break 1302689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1312689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward try: 1322689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward fdst.write(buf) 1332689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward except os.error, (errno, errstr): 1342689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, \ 1352689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward "could not write to %s: %s" % (dst, errstr) 1362689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1372689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward finally: 1382689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if fdst: 1392689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward fdst.close() 1402689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if fsrc: 1412689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward fsrc.close() 1422689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1432689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# _copy_file_contents() 1442689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1452689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1462689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Warddef copy_file (src, dst, 1472689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward preserve_mode=1, 1482689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward preserve_times=1, 1492689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward update=0, 1502689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward verbose=0): 1512689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1522689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward """Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' 1532689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward is copied there with the same name; otherwise, it must be a 1542689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward filename. (If the file exists, it will be ruthlessly clobbered.) 1552689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward If 'preserve_mode' is true (the default), the file's mode (type 1562689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward and permission bits, or whatever is analogous on the current 1572689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward platform) is copied. If 'preserve_times' is true (the default), 1582689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward the last-modified and last-access times are copied as well. If 1592689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'update' is true, 'src' will only be copied if 'dst' does not 1602689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward exist, or if 'dst' does exist but is older than 'src'. If 1612689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'verbose' is true, then a one-line summary of the copy will be 1622689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward printed to stdout.""" 1632689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1642689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward # XXX doesn't copy Mac-specific metadata 1652689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1662689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward from shutil import copyfile 1672689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward from stat import * 1682689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1692689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if not os.path.isfile (src): 1702689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, \ 1712689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward "can't copy %s:not a regular file" % src 1722689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1732689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if os.path.isdir (dst): 1742689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward dir = dst 1752689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward dst = os.path.join (dst, os.path.basename (src)) 1762689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward else: 1772689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward dir = os.path.dirname (dst) 1782689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1792689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if update and not newer (src, dst): 1802689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward return 1812689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1822689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if verbose: 1832689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward print "copying %s -> %s" % (src, dir) 1842689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1852689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward copyfile (src, dst) 1862689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if preserve_mode or preserve_times: 1872689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward st = os.stat (src) 1882689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if preserve_mode: 1892689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward os.chmod (dst, S_IMODE (st[ST_MODE])) 1902689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if preserve_times: 1912689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward os.utime (dst, (st[ST_ATIME], st[ST_MTIME])) 1922689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1932689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# copy_file () 1942689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1952689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 1962689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Warddef copy_tree (src, dst, 1972689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward preserve_mode=1, 1982689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward preserve_times=1, 1992689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward preserve_symlinks=0, 2002689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward update=0, 2012689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward verbose=0): 2022689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2032689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward """Copy an entire directory tree 'src' to a new location 'dst'. Both 2042689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'src' and 'dst' must be directory names. If 'src' is not a 2052689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward directory, raise DistutilsFileError. If 'dst' does not exist, it 2062689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward is created with 'mkpath'. The endresult of the copy is that 2072689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward every file in 'src' is copied to 'dst', and directories under 2082689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'src' are recursively copied to 'dst'. 2092689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2102689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'preserve_mode' and 'preserve_times' are the same as for 2112689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'copy_file'; note that they only apply to regular files, not to 2122689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward directories. If 'preserve_symlinks' is true, symlinks will be 2132689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward copied as symlinks (on platforms that support them!); otherwise 2142689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward (the default), the destination of the symlink will be copied. 2152689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 'update' and 'verbose' are the same as for 'copy_file'.""" 2162689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2172689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if not os.path.isdir (src): 2182689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, \ 2192689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward "cannot copy tree %s: not a directory" % src 2202689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward try: 2212689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward names = os.listdir (src) 2222689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward except os.error, (errno, errstr): 2232689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward raise DistutilsFileError, \ 2242689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward "error listing files in %s: %s" % (src, errstr) 2252689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2262689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2272689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward mkpath (dst, verbose=verbose) 2282689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2292689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward for n in names: 2302689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward src_name = os.path.join (src, n) 2312689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward dst_name = os.path.join (dst, n) 2322689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2332689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward if preserve_symlinks and os.path.islink (src_name): 2342689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward link_dest = os.readlink (src_name) 2352689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward os.symlink (link_dest, dst_name) 2362689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward elif os.path.isdir (src_name): 2372689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward copy_tree (src_name, dst_name, 2382689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward preserve_mode, preserve_times, preserve_symlinks, 2392689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward update, verbose) 2402689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward else: 2412689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward copy_file (src_name, dst_name, 2422689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward preserve_mode, preserve_times, 2432689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward update, verbose) 2442689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 2452689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# copy_tree () 246