10.10.shutil — High-level file operations

Source code:Lib/shutil.py


Theshutil module offers a number of high-level operations on files andcollections of files. In particular, functions are provided which support filecopying and removal. For operations on individual files, see also theos module.

Warning

Even the higher-level file copying functions (shutil.copy(),shutil.copy2()) can’t copy all file metadata.

On POSIX platforms, this means that file owner and group are lost as wellas ACLs. On Mac OS, the resource fork and other metadata are not used.This means that resources will be lost and file type and creator codes willnot be correct. On Windows, file owners, ACLs and alternate data streamsare not copied.

10.10.1.Directory and files operations

shutil.copyfileobj(fsrc,fdst[,length])

Copy the contents of the file-like objectfsrc to the file-like objectfdst.The integerlength, if given, is the buffer size. In particular, a negativelength value means to copy the data without looping over the source data inchunks; by default the data is read in chunks to avoid uncontrolled memoryconsumption. Note that if the current file position of thefsrc object is not0, only the contents from the current file position to the end of the file willbe copied.

shutil.copyfile(src,dst)

Copy the contents (no metadata) of the file namedsrc to a file nameddst.dst must be the complete target file name; look atshutil.copy() for a copy that accepts a target directory path. Ifsrc anddst are the same files,Error is raised.The destination location must be writable; otherwise, anIOError exceptionwill be raised. Ifdst already exists, it will be replaced. Special filessuch as character or block devices and pipes cannot be copied with thisfunction.src anddst are path names given as strings.

shutil.copymode(src,dst)

Copy the permission bits fromsrc todst. The file contents, owner, andgroup are unaffected.src anddst are path names given as strings.

shutil.copystat(src,dst)

Copy the permission bits, last access time, last modification time, and flagsfromsrc todst. The file contents, owner, and group are unaffected.srcanddst are path names given as strings.

shutil.copy(src,dst)

Copy the filesrc to the file or directorydst. Ifdst is a directory, afile with the same basename assrc is created (or overwritten) in thedirectory specified. Permission bits are copied.src anddst are pathnames given as strings.

shutil.copy2(src,dst)

Identical tocopy() except thatcopy2()also attempts to preserve file metadata.

copy2() usescopystat() to copy the file metadata.Please seecopystat() for more information.

shutil.ignore_patterns(*patterns)

This factory function creates a function that can be used as a callable forcopytree()’signore argument, ignoring files and directories thatmatch one of the glob-stylepatterns provided. See the example below.

New in version 2.6.

shutil.copytree(src,dst,symlinks=False,ignore=None)

Recursively copy an entire directory tree rooted atsrc. The destinationdirectory, named bydst, must not already exist; it will be created aswell as missing parent directories. Permissions and times of directoriesare copied withcopystat(), individual files are copied usingshutil.copy2().

Ifsymlinks is true, symbolic links in the source tree are represented assymbolic links in the new tree, but the metadata of the original links is NOTcopied; if false or omitted, the contents and metadata of the linked filesare copied to the new tree.

Ifignore is given, it must be a callable that will receive as itsarguments the directory being visited bycopytree(), and a list of itscontents, as returned byos.listdir(). Sincecopytree() iscalled recursively, theignore callable will be called once for eachdirectory that is copied. The callable must return a sequence of directoryand file names relative to the current directory (i.e. a subset of the itemsin its second argument); these names will then be ignored in the copyprocess.ignore_patterns() can be used to create such a callable thatignores names based on glob-style patterns.

If exception(s) occur, anError is raised with a list of reasons.

The source code for this should be considered an example rather than theultimate tool.

Changed in version 2.3:Error is raised if any exceptions occur during copying, rather thanprinting a message.

Changed in version 2.5:Create intermediate directories needed to createdst, rather than raising anerror. Copy permissions and times of directories usingcopystat().

Changed in version 2.6:Added theignore argument to be able to influence what is being copied.

shutil.rmtree(path[,ignore_errors[,onerror]])

Delete an entire directory tree;path must point to a directory (but not asymbolic link to a directory). Ifignore_errors is true, errors resultingfrom failed removals will be ignored; if false or omitted, such errors arehandled by calling a handler specified byonerror or, if that is omitted,they raise an exception.

Ifonerror is provided, it must be a callable that accepts threeparameters:function,path, andexcinfo. The first parameter,function, is the function which raised the exception; it will beos.path.islink(),os.listdir(),os.remove() oros.rmdir(). The second parameter,path, will be the path name passedtofunction. The third parameter,excinfo, will be the exceptioninformation return bysys.exc_info(). Exceptions raised byonerrorwill not be caught.

Changed in version 2.6:Explicitly check forpath being a symbolic link and raiseOSErrorin that case.

shutil.move(src,dst)

Recursively move a file or directory (src) to another location (dst).

If the destination is an existing directory, thensrc is moved inside thatdirectory. If the destination already exists but is not a directory, it maybe overwritten depending onos.rename() semantics.

If the destination is on the current filesystem, thenos.rename() isused. Otherwise,src is copied (usingshutil.copy2()) todst andthen removed.

New in version 2.3.

exceptionshutil.Error

This exception collects exceptions that are raised during a multi-fileoperation. Forcopytree(), the exception argument is a list of 3-tuples(srcname,dstname,exception).

New in version 2.3.

10.10.1.1.copytree example

This example is the implementation of thecopytree() function, describedabove, with the docstring omitted. It demonstrates many of the other functionsprovided by this module.

defcopytree(src,dst,symlinks=False,ignore=None):names=os.listdir(src)ifignoreisnotNone:ignored_names=ignore(src,names)else:ignored_names=set()os.makedirs(dst)errors=[]fornameinnames:ifnameinignored_names:continuesrcname=os.path.join(src,name)dstname=os.path.join(dst,name)try:ifsymlinksandos.path.islink(srcname):linkto=os.readlink(srcname)os.symlink(linkto,dstname)elifos.path.isdir(srcname):copytree(srcname,dstname,symlinks,ignore)else:copy2(srcname,dstname)# XXX What about devices, sockets etc.?except(IOError,os.error)aswhy:errors.append((srcname,dstname,str(why)))# catch the Error from the recursive copytree so that we can# continue with other filesexceptErroraserr:errors.extend(err.args[0])try:copystat(src,dst)exceptWindowsError:# can't copy file access times on WindowspassexceptOSErroraswhy:errors.extend((src,dst,str(why)))iferrors:raiseError(errors)

Another example that uses theignore_patterns() helper:

fromshutilimportcopytree,ignore_patternscopytree(source,destination,ignore=ignore_patterns('*.pyc','tmp*'))

This will copy everything except.pyc files and files or directories whosename starts withtmp.

Another example that uses theignore argument to add a logging call:

fromshutilimportcopytreeimportloggingdef_logpath(path,names):logging.info('Working in%s'%path)return[]# nothing will be ignoredcopytree(source,destination,ignore=_logpath)

10.10.2.Archiving operations

High-level utilities to create and read compressed and archived files are alsoprovided. They rely on thezipfile andtarfile modules.

shutil.make_archive(base_name,format[,root_dir[,base_dir[,verbose[,dry_run[,owner[,group[,logger]]]]]]])

Create an archive file (eg. zip or tar) and returns its name.

base_name is the name of the file to create, including the path, minusany format-specific extension.format is the archive format: one of“zip” (if thezlib module or externalzip executable isavailable), “tar”, “gztar” (if thezlib module is available), or“bztar” (if thebz2 module is available).

root_dir is a directory that will be the root directory of thearchive; ie. we typically chdir intoroot_dir before creating thearchive.

base_dir is the directory where we start archiving from;ie.base_dir will be the common prefix of all files anddirectories in the archive.

root_dir andbase_dir both default to the current directory.

owner andgroup are used when creating a tar archive. By default,uses the current owner and group.

logger must be an object compatible withPEP 282, usually an instance oflogging.Logger.

New in version 2.7.

shutil.get_archive_formats()

Return a list of supported formats for archiving.Each element of the returned sequence is a tuple(name,description).

By defaultshutil provides these formats:

  • zip: ZIP file (if thezlib module or externalzipexecutable is available).

  • tar: uncompressed tar file.

  • gztar: gzip’ed tar-file (if thezlib module is available).

  • bztar: bzip2’ed tar-file (if thebz2 module is available).

You can register new formats or provide your own archiver for any existingformats, by usingregister_archive_format().

New in version 2.7.

shutil.register_archive_format(name,function[,extra_args[,description]])

Register an archiver for the formatname.function is a callable thatwill be used to invoke the archiver.

If given,extra_args is a sequence of(name,value) that will beused as extra keywords arguments when the archiver callable is used.

description is used byget_archive_formats() which returns thelist of archivers. Defaults to an empty list.

New in version 2.7.

shutil.unregister_archive_format(name)

Remove the archive formatname from the list of supported formats.

New in version 2.7.

10.10.2.1.Archiving example

In this example, we create a gzip’ed tar-file archive containing all filesfound in the.ssh directory of the user:

>>>fromshutilimportmake_archive>>>importos>>>archive_name=os.path.expanduser(os.path.join('~','myarchive'))>>>root_dir=os.path.expanduser(os.path.join('~','.ssh'))>>>make_archive(archive_name,'gztar',root_dir)'/Users/tarek/myarchive.tar.gz'

The resulting archive contains:

$ tar -tzvf /Users/tarek/myarchive.tar.gzdrwx------ tarek/staff       0 2010-02-01 16:23:40 ./-rw-r--r-- tarek/staff     609 2008-06-09 13:26:54 ./authorized_keys-rwxr-xr-x tarek/staff      65 2008-06-09 13:26:54 ./config-rwx------ tarek/staff     668 2008-06-09 13:26:54 ./id_dsa-rwxr-xr-x tarek/staff     609 2008-06-09 13:26:54 ./id_dsa.pub-rw------- tarek/staff    1675 2008-06-09 13:26:54 ./id_rsa-rw-r--r-- tarek/staff     397 2008-06-09 13:26:54 ./id_rsa.pub-rw-r--r-- tarek/staff   37192 2010-02-06 18:23:10 ./known_hosts