[Python-checkins] cpython: Fix #14772: Return the destination from some shutil functions.
brian.curtin
python-checkins at python.org
Tue Jun 19 01:41:44 CEST 2012
http://hg.python.org/cpython/rev/8281233ec648
changeset: 77514:8281233ec648
user: Brian Curtin <brian at python.org>
date: Mon Jun 18 18:41:07 2012 -0500
summary:
Fix #14772: Return the destination from some shutil functions.
files:
Doc/library/shutil.rst | 14 ++++++---
Lib/shutil.py | 13 +++++++--
Lib/test/test_shutil.py | 41 +++++++++++++++++++++++++++++
Misc/NEWS | 2 +
4 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst
--- a/Doc/library/shutil.rst
+++ b/Doc/library/shutil.rst
@@ -50,7 +50,7 @@
.. function:: copyfile(src, dst, symlinks=False)
Copy the contents (no metadata) of the file named *src* to a file named
- *dst*. *dst* must be the complete target file name; look at
+ *dst* and return *dst*. *dst* must be the complete target file name; look at
:func:`shutil.copy` for a copy that accepts a target directory path. If
*src* and *dst* are the same files, :exc:`Error` is raised.
@@ -91,7 +91,8 @@
.. function:: copy(src, dst, symlinks=False))
- Copy the file *src* to the file or directory *dst*. If *dst* is a directory, a
+ Copy the file *src* to the file or directory *dst* and return the file's
+ destination. If *dst* is a directory, a
file with the same basename as *src* is created (or overwritten) in the
directory specified. Permission bits are copied. *src* and *dst* are path
names given as strings. If *symlinks* is true, symbolic links won't be
@@ -102,7 +103,8 @@
.. function:: copy2(src, dst, symlinks=False)
- Similar to :func:`shutil.copy`, but metadata is copied as well. This is
+ Similar to :func:`shutil.copy`, including that the destination is
+ returned, but metadata is copied as well. This is
similar to the Unix command :program:`cp -p`. If *symlinks* is true,
symbolic links won't be followed but recreated instead -- this resembles
GNU's :program:`cp -P`.
@@ -120,7 +122,8 @@
.. function:: copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False)
- Recursively copy an entire directory tree rooted at *src*. The destination
+ Recursively copy an entire directory tree rooted at *src*, returning the
+ destination directory. The destination
directory, named by *dst*, must not already exist; it will be created as
well as missing parent directories. Permissions and times of directories
are copied with :func:`copystat`, individual files are copied using
@@ -189,7 +192,8 @@
.. function:: move(src, dst)
- Recursively move a file or directory (*src*) to another location (*dst*).
+ Recursively move a file or directory (*src*) to another location (*dst*)
+ and return the destination.
If the destination is a directory or a symlink to a directory, then *src* is
moved inside that directory.
diff --git a/Lib/shutil.py b/Lib/shutil.py
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -109,6 +109,7 @@
with open(src, 'rb') as fsrc:
with open(dst, 'wb') as fdst:
copyfileobj(fsrc, fdst)
+ return dst
def copymode(src, dst, symlinks=False):
"""Copy mode bits from src to dst.
@@ -197,7 +198,7 @@
pass
def copy(src, dst, symlinks=False):
- """Copy data and mode bits ("cp src dst").
+ """Copy data and mode bits ("cp src dst"). Return the file's destination.
The destination may be a directory.
@@ -209,9 +210,11 @@
dst = os.path.join(dst, os.path.basename(src))
copyfile(src, dst, symlinks=symlinks)
copymode(src, dst, symlinks=symlinks)
+ return dst
def copy2(src, dst, symlinks=False):
- """Copy data and all stat info ("cp -p src dst").
+ """Copy data and all stat info ("cp -p src dst"). Return the file's
+ destination."
The destination may be a directory.
@@ -224,6 +227,7 @@
copyfile(src, dst, symlinks=symlinks)
copystat(src, dst, symlinks=symlinks)
_copyxattr(src, dst, symlinks=symlinks)
+ return dst
def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
@@ -322,6 +326,7 @@
errors.extend((src, dst, str(why)))
if errors:
raise Error(errors)
+ return dst
def rmtree(path, ignore_errors=False, onerror=None):
"""Recursively delete a directory tree.
@@ -379,7 +384,8 @@
def move(src, dst):
"""Recursively move a file or directory to another location. This is
- similar to the Unix "mv" command.
+ similar to the Unix "mv" command. Return the file or directory's
+ destination.
If the destination is a directory or a symlink to a directory, the source
is moved inside the directory. The destination path must not already
@@ -423,6 +429,7 @@
else:
copy2(src, real_dst)
os.unlink(src)
+ return real_dst
def _destinsrc(src, dst):
src = abspath(src)
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -1095,6 +1095,38 @@
shutil.chown(dirname, user, group)
check_chown(dirname, uid, gid)
+ def test_copy_return_value(self):
+ # copy and copy2 both return their destination path.
+ for fn in (shutil.copy, shutil.copy2):
+ src_dir = self.mkdtemp()
+ dst_dir = self.mkdtemp()
+ src = os.path.join(src_dir, 'foo')
+ write_file(src, 'foo')
+ rv = fn(src, dst_dir)
+ self.assertEqual(rv, os.path.join(dst_dir, 'foo'))
+ rv = fn(src, os.path.join(dst_dir, 'bar'))
+ self.assertEqual(rv, os.path.join(dst_dir, 'bar'))
+
+ def test_copyfile_return_value(self):
+ # copytree returns its destination path.
+ src_dir = self.mkdtemp()
+ dst_dir = self.mkdtemp()
+ dst_file = os.path.join(dst_dir, 'bar')
+ src_file = os.path.join(src_dir, 'foo')
+ write_file(src_file, 'foo')
+ rv = shutil.copyfile(src_file, dst_file)
+ self.assertTrue(os.path.exists(rv))
+ self.assertEqual(read_file(src_file), read_file(dst_file))
+
+ def test_copytree_return_value(self):
+ # copytree returns its destination path.
+ src_dir = self.mkdtemp()
+ dst_dir = src_dir + "dest"
+ src = os.path.join(src_dir, 'foo')
+ write_file(src, 'foo')
+ rv = shutil.copytree(src_dir, dst_dir)
+ self.assertEqual(['foo'], os.listdir(rv))
+
class TestMove(unittest.TestCase):
@@ -1251,6 +1283,15 @@
self.assertTrue(os.path.islink(dst_link))
self.assertTrue(os.path.samefile(src, dst_link))
+ def test_move_return_value(self):
+ rv = shutil.move(self.src_file, self.dst_dir)
+ self.assertEqual(rv,
+ os.path.join(self.dst_dir, os.path.basename(self.src_file)))
+
+ def test_move_as_rename_return_value(self):
+ rv = shutil.move(self.src_file, os.path.join(self.dst_dir, 'bar'))
+ self.assertEqual(rv, os.path.join(self.dst_dir, 'bar'))
+
class TestCopyFile(unittest.TestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -31,6 +31,8 @@
Library
-------
+- Issue #14772: Return destination values from some shutil functions.
+
- Issue #15064: Implement context manager protocol for multiprocessing types
- Issue #15101: Make pool finalizer avoid joining current thread.
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list