"""distutils.dir_utilUtility functions for manipulating directories and directory trees."""import osimport errnofrom distutils.errors import DistutilsFileError, DistutilsInternalErrorfrom distutils import log# cache for by mkpath() -- in addition to cheapening redundant calls,# eliminates redundant "creating /foo/bar/baz" messages in dry-run mode_path_created = {}# I don't use os.makedirs because a) it's new to Python 1.5.2, and# b) it blows up if the directory already exists (I want to silently# succeed in that case).def mkpath(name, mode=0o777, verbose=1, dry_run=0):"""Create a directory and any missing ancestor directories.If the directory already exists (or if 'name' is the empty string, whichmeans the current directory, which of course exists), then do nothing.Raise DistutilsFileError if unable to create some directory along the way(eg. some sub-path exists, but is a file rather than a directory).If 'verbose' is true, print a one-line summary of each mkdir to stdout.Return the list of directories actually created."""global _path_created# Detect a common bug -- name is Noneif not isinstance(name, str):raise DistutilsInternalError("mkpath: 'name' must be a string (got %r)" % (name,))# XXX what's the better way to handle verbosity? print as we create# each directory in the path (the current behaviour), or only announce# the creation of the whole path? (quite easy to do the latter since# we're not using a recursive algorithm)name = os.path.normpath(name)created_dirs = []if os.path.isdir(name) or name == '':return created_dirsif _path_created.get(os.path.abspath(name)):return created_dirs(head, tail) = os.path.split(name)tails = [tail] # stack of lone dirs to createwhile head and tail and not os.path.isdir(head):(head, tail) = os.path.split(head)tails.insert(0, tail) # push next higher dir onto stack# now 'head' contains the deepest directory that already exists# (that is, the child of 'head' in 'name' is the highest directory# that does *not* exist)for d in tails:#print "head = %s, d = %s: " % (head, d),head = os.path.join(head, d)abs_head = os.path.abspath(head)if _path_created.get(abs_head):continueif verbose >= 1:log.info("creating %s", head)if not dry_run:try:os.mkdir(head, mode)except OSError as exc:if not (exc.errno == errno.EEXIST and os.path.isdir(head)):raise DistutilsFileError("could not create '%s': %s" % (head, exc.args[-1]))created_dirs.append(head)_path_created[abs_head] = 1return created_dirsdef create_tree(base_dir, files, mode=0o777, verbose=1, dry_run=0):"""Create all the empty directories under 'base_dir' needed to put 'files'there.'base_dir' is just the name of a directory which doesn't necessarilyexist yet; 'files' is a list of filenames to be interpreted relative to'base_dir'. 'base_dir' + the directory portion of every file in 'files'will be created if it doesn't already exist. 'mode', 'verbose' and'dry_run' flags are as for 'mkpath()'."""# First get the list of directories to createneed_dir = set()for file in files:need_dir.add(os.path.join(base_dir, os.path.dirname(file)))# Now create themfor dir in sorted(need_dir):mkpath(dir, mode, verbose=verbose, dry_run=dry_run)def copy_tree(src, dst, preserve_mode=1, preserve_times=1,preserve_symlinks=0, update=0, verbose=1, dry_run=0):"""Copy an entire directory tree 'src' to a new location 'dst'.Both 'src' and 'dst' must be directory names. If 'src' is not adirectory, raise DistutilsFileError. If 'dst' does not exist, it iscreated with 'mkpath()'. The end result of the copy is that everyfile in 'src' is copied to 'dst', and directories under 'src' arerecursively copied to 'dst'. Return the list of files that werecopied or might have been copied, using their output name. Thereturn value is unaffected by 'update' or 'dry_run': it is simplythe list of all files under 'src', with the names changed to beunder 'dst'.'preserve_mode' and 'preserve_times' are the same as for'copy_file'; note that they only apply to regular files, not todirectories. If 'preserve_symlinks' is true, symlinks will becopied as symlinks (on platforms that support them!); otherwise(the default), the destination of the symlink will be copied.'update' and 'verbose' are the same as for 'copy_file'."""from distutils.file_util import copy_fileif not dry_run and not os.path.isdir(src):raise DistutilsFileError("cannot copy tree '%s': not a directory" % src)try:names = os.listdir(src)except OSError as e:if dry_run:names = []else:raise DistutilsFileError("error listing files in '%s': %s" % (src, e.strerror))if not dry_run:mkpath(dst, verbose=verbose)outputs = []for n in names:src_name = os.path.join(src, n)dst_name = os.path.join(dst, n)if n.startswith('.nfs'):# skip NFS rename filescontinueif preserve_symlinks and os.path.islink(src_name):link_dest = os.readlink(src_name)if verbose >= 1:log.info("linking %s -> %s", dst_name, link_dest)if not dry_run:os.symlink(link_dest, dst_name)outputs.append(dst_name)elif os.path.isdir(src_name):outputs.extend(copy_tree(src_name, dst_name, preserve_mode,preserve_times, preserve_symlinks, update,verbose=verbose, dry_run=dry_run))else:copy_file(src_name, dst_name, preserve_mode,preserve_times, update, verbose=verbose,dry_run=dry_run)outputs.append(dst_name)return outputsdef _build_cmdtuple(path, cmdtuples):"""Helper for remove_tree()."""for f in os.listdir(path):real_f = os.path.join(path,f)if os.path.isdir(real_f) and not os.path.islink(real_f):_build_cmdtuple(real_f, cmdtuples)else:cmdtuples.append((os.remove, real_f))cmdtuples.append((os.rmdir, path))def remove_tree(directory, verbose=1, dry_run=0):"""Recursively remove an entire directory tree.Any errors are ignored (apart from being reported to stdout if 'verbose'is true)."""global _path_createdif verbose >= 1:log.info("removing '%s' (and everything under it)", directory)if dry_run:returncmdtuples = []_build_cmdtuple(directory, cmdtuples)for cmd in cmdtuples:try:cmd[0](cmd[1])# remove dir from cache if it's already thereabspath = os.path.abspath(cmd[1])if abspath in _path_created:del _path_created[abspath]except OSError as exc:log.warn("error removing %s: %s", directory, exc)def ensure_relative(path):"""Take the full path 'path', and make it a relative path.This is useful to make 'path' the second argument to os.path.join()."""drive, path = os.path.splitdrive(path)if path[0:1] == os.sep:path = drive + path[1:]return path
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。