cleaned distutils.file_util

This commit is contained in:
Tarek Ziadé 2009-07-03 19:14:49 +00:00
parent eea9d0d846
commit 9ad7bbc637
1 changed files with 51 additions and 68 deletions

View File

@ -10,49 +10,48 @@ from distutils.errors import DistutilsFileError
from distutils import log from distutils import log
# for generating verbose output in 'copy_file()' # for generating verbose output in 'copy_file()'
_copy_action = { None: 'copying', _copy_action = {None: 'copying',
'hard': 'hard linking', 'hard': 'hard linking',
'sym': 'symbolically linking' } 'sym': 'symbolically linking'}
def _copy_file_contents (src, dst, buffer_size=16*1024): def _copy_file_contents(src, dst, buffer_size=16*1024):
"""Copy the file 'src' to 'dst'; both must be filenames. Any error """Copy the file 'src' to 'dst'.
opening either file, reading from 'src', or writing to 'dst', raises
DistutilsFileError. Data is read/written in chunks of 'buffer_size' Both must be filenames. Any error opening either file, reading from
bytes (default 16k). No attempt is made to handle anything apart from 'src', or writing to 'dst', raises DistutilsFileError. Data is
regular files. read/written in chunks of 'buffer_size' bytes (default 16k). No attempt
is made to handle anything apart from regular files.
""" """
# Stolen from shutil module in the standard library, but with # Stolen from shutil module in the standard library, but with
# custom error-handling added. # custom error-handling added.
fsrc = None fsrc = None
fdst = None fdst = None
try: try:
try: try:
fsrc = open(src, 'rb') fsrc = open(src, 'rb')
except os.error, (errno, errstr): except os.error, (errno, errstr):
raise DistutilsFileError, \ raise DistutilsFileError("could not open '%s': %s" % (src, errstr))
"could not open '%s': %s" % (src, errstr)
if os.path.exists(dst): if os.path.exists(dst):
try: try:
os.unlink(dst) os.unlink(dst)
except os.error, (errno, errstr): except os.error, (errno, errstr):
raise DistutilsFileError, \ raise DistutilsFileError(
"could not delete '%s': %s" % (dst, errstr) "could not delete '%s': %s" % (dst, errstr))
try: try:
fdst = open(dst, 'wb') fdst = open(dst, 'wb')
except os.error, (errno, errstr): except os.error, (errno, errstr):
raise DistutilsFileError, \ raise DistutilsFileError(
"could not create '%s': %s" % (dst, errstr) "could not create '%s': %s" % (dst, errstr))
while 1: while 1:
try: try:
buf = fsrc.read(buffer_size) buf = fsrc.read(buffer_size)
except os.error, (errno, errstr): except os.error, (errno, errstr):
raise DistutilsFileError, \ raise DistutilsFileError(
"could not read from '%s': %s" % (src, errstr) "could not read from '%s': %s" % (src, errstr))
if not buf: if not buf:
break break
@ -60,8 +59,8 @@ def _copy_file_contents (src, dst, buffer_size=16*1024):
try: try:
fdst.write(buf) fdst.write(buf)
except os.error, (errno, errstr): except os.error, (errno, errstr):
raise DistutilsFileError, \ raise DistutilsFileError(
"could not write to '%s': %s" % (dst, errstr) "could not write to '%s': %s" % (dst, errstr))
finally: finally:
if fdst: if fdst:
@ -69,25 +68,18 @@ def _copy_file_contents (src, dst, buffer_size=16*1024):
if fsrc: if fsrc:
fsrc.close() fsrc.close()
# _copy_file_contents() def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0,
link=None, verbose=1, dry_run=0):
"""Copy a file 'src' to 'dst'.
def copy_file (src, dst, If 'dst' is a directory, then 'src' is copied there with the same name;
preserve_mode=1, otherwise, it must be a filename. (If the file exists, it will be
preserve_times=1, ruthlessly clobbered.) If 'preserve_mode' is true (the default),
update=0, the file's mode (type and permission bits, or whatever is analogous on
link=None, the current platform) is copied. If 'preserve_times' is true (the
verbose=1, default), the last-modified and last-access times are copied as well.
dry_run=0): If 'update' is true, 'src' will only be copied if 'dst' does not exist,
or if 'dst' does exist but is older than 'src'.
"""Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is
copied there with the same name; otherwise, it must be a filename. (If
the file exists, it will be ruthlessly clobbered.) If 'preserve_mode'
is true (the default), the file's mode (type and permission bits, or
whatever is analogous on the current platform) is copied. If
'preserve_times' is true (the default), the last-modified and
last-access times are copied as well. If 'update' is true, 'src' will
only be copied if 'dst' does not exist, or if 'dst' does exist but is
older than 'src'.
'link' allows you to make hard links (os.link) or symbolic links 'link' allows you to make hard links (os.link) or symbolic links
(os.symlink) instead of copying: set it to "hard" or "sym"; if it is (os.symlink) instead of copying: set it to "hard" or "sym"; if it is
@ -113,8 +105,8 @@ def copy_file (src, dst,
from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE
if not os.path.isfile(src): if not os.path.isfile(src):
raise DistutilsFileError, \ raise DistutilsFileError(
"can't copy '%s': doesn't exist or not a regular file" % src "can't copy '%s': doesn't exist or not a regular file" % src)
if os.path.isdir(dst): if os.path.isdir(dst):
dir = dst dir = dst
@ -130,8 +122,7 @@ def copy_file (src, dst,
try: try:
action = _copy_action[link] action = _copy_action[link]
except KeyError: except KeyError:
raise ValueError, \ raise ValueError("invalid value '%s' for 'link' argument" % link)
"invalid value '%s' for 'link' argument" % link
if verbose >= 1: if verbose >= 1:
if os.path.basename(dst) == os.path.basename(src): if os.path.basename(dst) == os.path.basename(src):
@ -148,8 +139,8 @@ def copy_file (src, dst,
try: try:
macostools.copy(src, dst, 0, preserve_times) macostools.copy(src, dst, 0, preserve_times)
except os.error, exc: except os.error, exc:
raise DistutilsFileError, \ raise DistutilsFileError(
"could not copy '%s' to '%s': %s" % (src, dst, exc[-1]) "could not copy '%s' to '%s': %s" % (src, dst, exc[-1]))
# If linking (hard or symbolic), use the appropriate system call # If linking (hard or symbolic), use the appropriate system call
# (Unix only, of course, but that's the caller's responsibility) # (Unix only, of course, but that's the caller's responsibility)
@ -176,17 +167,13 @@ def copy_file (src, dst,
return (dst, 1) return (dst, 1)
# copy_file ()
# XXX I suspect this is Unix-specific -- need porting help! # XXX I suspect this is Unix-specific -- need porting help!
def move_file (src, dst, def move_file (src, dst, verbose=1, dry_run=0):
verbose=1, """Move a file 'src' to 'dst'.
dry_run=0):
"""Move a file 'src' to 'dst'. If 'dst' is a directory, the file will If 'dst' is a directory, the file will be moved into it with the same
be moved into it with the same name; otherwise, 'src' is just renamed name; otherwise, 'src' is just renamed to 'dst'. Return the new
to 'dst'. Return the new full name of the file. full name of the file.
Handles cross-device moves on Unix using 'copy_file()'. What about Handles cross-device moves on Unix using 'copy_file()'. What about
other systems??? other systems???
@ -201,20 +188,19 @@ def move_file (src, dst,
return dst return dst
if not isfile(src): if not isfile(src):
raise DistutilsFileError, \ raise DistutilsFileError("can't move '%s': not a regular file" % src)
"can't move '%s': not a regular file" % src
if isdir(dst): if isdir(dst):
dst = os.path.join(dst, basename(src)) dst = os.path.join(dst, basename(src))
elif exists(dst): elif exists(dst):
raise DistutilsFileError, \ raise DistutilsFileError(
"can't move '%s': destination '%s' already exists" % \ "can't move '%s': destination '%s' already exists" %
(src, dst) (src, dst))
if not isdir(dirname(dst)): if not isdir(dirname(dst)):
raise DistutilsFileError, \ raise DistutilsFileError(
"can't move '%s': destination '%s' not a valid path" % \ "can't move '%s': destination '%s' not a valid path" % \
(src, dst) (src, dst))
copy_it = 0 copy_it = 0
try: try:
@ -223,8 +209,8 @@ def move_file (src, dst,
if num == errno.EXDEV: if num == errno.EXDEV:
copy_it = 1 copy_it = 1
else: else:
raise DistutilsFileError, \ raise DistutilsFileError(
"couldn't move '%s' to '%s': %s" % (src, dst, msg) "couldn't move '%s' to '%s': %s" % (src, dst, msg))
if copy_it: if copy_it:
copy_file(src, dst, verbose=verbose) copy_file(src, dst, verbose=verbose)
@ -235,15 +221,12 @@ def move_file (src, dst,
os.unlink(dst) os.unlink(dst)
except os.error: except os.error:
pass pass
raise DistutilsFileError, \ raise DistutilsFileError(
("couldn't move '%s' to '%s' by copy/delete: " + ("couldn't move '%s' to '%s' by copy/delete: " +
"delete '%s' failed: %s") % \ "delete '%s' failed: %s") %
(src, dst, src, msg) (src, dst, src, msg))
return dst return dst
# move_file ()
def write_file (filename, contents): def write_file (filename, contents):
"""Create a file with the specified name and write 'contents' (a """Create a file with the specified name and write 'contents' (a