Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
5340db38
Commit
5340db38
authored
Apr 19, 2010
by
Tarek Ziadé
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed #1540112: now shutil.copytree will let you provide your own copy() function
parent
5fb313bb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
51 additions
and
27 deletions
+51
-27
Doc/library/shutil.rst
Doc/library/shutil.rst
+8
-3
Lib/shutil.py
Lib/shutil.py
+8
-5
Lib/test/test_shutil.py
Lib/test/test_shutil.py
+32
-19
Misc/NEWS
Misc/NEWS
+3
-0
No files found.
Doc/library/shutil.rst
View file @
5340db38
...
...
@@ -87,7 +87,7 @@ Directory and files operations
match one of the glob-style *patterns* provided. See the example below.
.. function:: copytree(src, dst, symlinks=False, ignore=None)
.. function:: copytree(src, dst, symlinks=False, ignore=None
, copy_function=copy2
)
Recursively copy an entire directory tree rooted at *src*. The destination
directory, named by *dst*, must not already exist; it will be created as well
...
...
@@ -111,9 +111,14 @@ Directory and files operations
If exception(s) occur, an :exc:`Error` is raised with a list of reasons.
The source code for this should be considered an example rather than the
ultimate tool.
If *copy_function* is given, it must be a callable that will be used
to copy each file. It will be called with the source path and the
destination path as arguments. By default, :func:`copy2` is used, but any
function that supports the same signature (like :func:`copy`) can be used.
.. versionchanged:: 3.2
Added the *copy_function* argument to be able to provide a custom copy
function.
.. function:: rmtree(path, ignore_errors=False, onerror=None)
...
...
Lib/shutil.py
View file @
5340db38
...
...
@@ -147,8 +147,8 @@ def ignore_patterns(*patterns):
return
set
(
ignored_names
)
return
_ignore_patterns
def
copytree
(
src
,
dst
,
symlinks
=
False
,
ignore
=
None
):
"""Recursively copy a directory tree
using copy2()
.
def
copytree
(
src
,
dst
,
symlinks
=
False
,
ignore
=
None
,
copy_function
=
copy2
):
"""Recursively copy a directory tree.
The destination directory must not already exist.
If exception(s) occur, an Error is raised with a list of reasons.
...
...
@@ -170,7 +170,10 @@ def copytree(src, dst, symlinks=False, ignore=None):
list of names relative to the `src` directory that should
not be copied.
XXX Consider this example code rather than the ultimate tool.
The optional copy_function argument is a callable that will be used
to copy each file. It will be called with the source path and the
destination path as arguments. By default, copy2() is used, but any
function that supports the same signature (like copy()) can be used.
"""
names
=
os
.
listdir
(
src
)
...
...
@@ -191,10 +194,10 @@ def copytree(src, dst, symlinks=False, ignore=None):
linkto
=
os
.
readlink
(
srcname
)
os
.
symlink
(
linkto
,
dstname
)
elif
os
.
path
.
isdir
(
srcname
):
copytree
(
srcname
,
dstname
,
symlinks
,
ignore
)
copytree
(
srcname
,
dstname
,
symlinks
,
ignore
,
copy_function
)
else
:
# Will raise a SpecialFileError for unsupported file types
copy
2
(
srcname
,
dstname
)
copy
_function
(
srcname
,
dstname
)
# catch the Error from the recursive copytree so that we can
# continue with other files
except
Error
as
err
:
...
...
Lib/test/test_shutil.py
View file @
5340db38
...
...
@@ -74,6 +74,7 @@ class TestShutil(unittest.TestCase):
d
=
tempfile
.
mkdtemp
()
self
.
tempdirs
.
append
(
d
)
return
d
def
test_rmtree_errors
(
self
):
# filename is guaranteed not to exist
filename
=
tempfile
.
mktemp
()
...
...
@@ -140,11 +141,12 @@ class TestShutil(unittest.TestCase):
self
.
assertRaises
(
OSError
,
shutil
.
rmtree
,
path
)
os
.
remove
(
path
)
def
_write_data
(
self
,
path
,
data
):
f
=
open
(
path
,
"w"
)
f
.
write
(
data
)
f
.
close
()
def
test_copytree_simple
(
self
):
def
write_data
(
path
,
data
):
f
=
open
(
path
,
"w"
)
f
.
write
(
data
)
f
.
close
()
def
read_data
(
path
):
f
=
open
(
path
)
...
...
@@ -154,11 +156,9 @@ class TestShutil(unittest.TestCase):
src_dir
=
tempfile
.
mkdtemp
()
dst_dir
=
os
.
path
.
join
(
tempfile
.
mkdtemp
(),
'destination'
)
write_data
(
os
.
path
.
join
(
src_dir
,
'test.txt'
),
'123'
)
self
.
_write_data
(
os
.
path
.
join
(
src_dir
,
'test.txt'
),
'123'
)
os
.
mkdir
(
os
.
path
.
join
(
src_dir
,
'test_dir'
))
write_data
(
os
.
path
.
join
(
src_dir
,
'test_dir'
,
'test.txt'
),
'456'
)
self
.
_
write_data
(
os
.
path
.
join
(
src_dir
,
'test_dir'
,
'test.txt'
),
'456'
)
try
:
shutil
.
copytree
(
src_dir
,
dst_dir
)
...
...
@@ -187,11 +187,6 @@ class TestShutil(unittest.TestCase):
def
test_copytree_with_exclude
(
self
):
def
write_data
(
path
,
data
):
f
=
open
(
path
,
"w"
)
f
.
write
(
data
)
f
.
close
()
def
read_data
(
path
):
f
=
open
(
path
)
data
=
f
.
read
()
...
...
@@ -204,16 +199,18 @@ class TestShutil(unittest.TestCase):
src_dir
=
tempfile
.
mkdtemp
()
try
:
dst_dir
=
join
(
tempfile
.
mkdtemp
(),
'destination'
)
write_data
(
join
(
src_dir
,
'test.txt'
),
'123'
)
write_data
(
join
(
src_dir
,
'test.tmp'
),
'123'
)
self
.
_
write_data
(
join
(
src_dir
,
'test.txt'
),
'123'
)
self
.
_
write_data
(
join
(
src_dir
,
'test.tmp'
),
'123'
)
os
.
mkdir
(
join
(
src_dir
,
'test_dir'
))
write_data
(
join
(
src_dir
,
'test_dir'
,
'test.txt'
),
'456'
)
self
.
_
write_data
(
join
(
src_dir
,
'test_dir'
,
'test.txt'
),
'456'
)
os
.
mkdir
(
join
(
src_dir
,
'test_dir2'
))
write_data
(
join
(
src_dir
,
'test_dir2'
,
'test.txt'
),
'456'
)
self
.
_
write_data
(
join
(
src_dir
,
'test_dir2'
,
'test.txt'
),
'456'
)
os
.
mkdir
(
join
(
src_dir
,
'test_dir2'
,
'subdir'
))
os
.
mkdir
(
join
(
src_dir
,
'test_dir2'
,
'subdir2'
))
write_data
(
join
(
src_dir
,
'test_dir2'
,
'subdir'
,
'test.txt'
),
'456'
)
write_data
(
join
(
src_dir
,
'test_dir2'
,
'subdir2'
,
'test.py'
),
'456'
)
self
.
_write_data
(
join
(
src_dir
,
'test_dir2'
,
'subdir'
,
'test.txt'
),
'456'
)
self
.
_write_data
(
join
(
src_dir
,
'test_dir2'
,
'subdir2'
,
'test.py'
),
'456'
)
# testing glob-like patterns
...
...
@@ -339,6 +336,21 @@ class TestShutil(unittest.TestCase):
shutil
.
rmtree
(
TESTFN
,
ignore_errors
=
True
)
shutil
.
rmtree
(
TESTFN2
,
ignore_errors
=
True
)
def
test_copytree_special_func
(
self
):
src_dir
=
self
.
mkdtemp
()
dst_dir
=
os
.
path
.
join
(
self
.
mkdtemp
(),
'destination'
)
self
.
_write_data
(
os
.
path
.
join
(
src_dir
,
'test.txt'
),
'123'
)
os
.
mkdir
(
os
.
path
.
join
(
src_dir
,
'test_dir'
))
self
.
_write_data
(
os
.
path
.
join
(
src_dir
,
'test_dir'
,
'test.txt'
),
'456'
)
copied
=
[]
def
_copy
(
src
,
dst
):
copied
.
append
((
src
,
dst
))
shutil
.
copytree
(
src_dir
,
dst_dir
,
copy_function
=
_copy
)
self
.
assertEquals
(
len
(
copied
),
2
)
@
unittest
.
skipUnless
(
zlib
,
"requires zlib"
)
def
test_make_tarball
(
self
):
# creating something to tar
...
...
@@ -728,6 +740,7 @@ class TestMove(unittest.TestCase):
finally
:
shutil
.
rmtree
(
TESTFN
,
ignore_errors
=
True
)
def
test_main
():
support
.
run_unittest
(
TestShutil
,
TestMove
)
...
...
Misc/NEWS
View file @
5340db38
...
...
@@ -318,6 +318,9 @@ C-API
Library
-------
- Issue #1540112: Now allowing the choice of a copy function in
shutil.copytree.
- Issue #4814: timeout parameter is now applied also for connections resulting
from PORT/EPRT commands.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment