Mercurial > cpython-lru_cache-weakref
annotate Lib/shutil.py @ 80661:94de77bd0b4b 2.7
Issue #16194: document imp.load_dynamic problems
when read several extension modules from the same binary object file.
| author | Andrew Svetlov <andrew.svetlov@gmail.com> |
|---|---|
| date | Thu, 29 Nov 2012 19:51:28 +0200 |
| parents | fe3d113e139d |
| children |
| rev | line source |
|---|---|
|
59058
b52e3ff0a4c8
completed the __all__ list and changed the module doctest
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59053
diff
changeset
|
1 """Utility functions for copying and archiving files and directory trees. |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
2 |
|
11202
7eeeb0d2b0a4
Typo in comment (on Mac, it's the *resource* fork that's not copied,
Guido van Rossum <guido@python.org>
parents:
10289
diff
changeset
|
3 XXX The functions here don't copy the resource fork or other metadata on Mac. |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
4 |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
5 """ |
| 5 | 6 |
| 771 | 7 import os |
|
10289
1e766de714de
Add import sys, needed by reference to sys.exc_info() in rmtree().
Guido van Rossum <guido@python.org>
parents:
9872
diff
changeset
|
8 import sys |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
9 import stat |
|
32386
686e5d38be42
shutil.move() will raise an exception when trying to move a directory into
Brett Cannon <bcannon@gmail.com>
parents:
28025
diff
changeset
|
10 from os.path import abspath |
|
47888
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
11 import fnmatch |
|
59431
e2d41079d059
Fix some py3k warnings in the standard library.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
59058
diff
changeset
|
12 import collections |
|
59917
e3fdfdb1a8ff
Merged revisions 79299 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
51179
diff
changeset
|
13 import errno |
| 5 | 14 |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
15 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
16 from pwd import getpwnam |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
17 except ImportError: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
18 getpwnam = None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
19 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
20 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
21 from grp import getgrnam |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
22 except ImportError: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
23 getgrnam = None |
| 5 | 24 |
|
59058
b52e3ff0a4c8
completed the __all__ list and changed the module doctest
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59053
diff
changeset
|
25 __all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", |
|
b52e3ff0a4c8
completed the __all__ list and changed the module doctest
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59053
diff
changeset
|
26 "copytree", "move", "rmtree", "Error", "SpecialFileError", |
|
b52e3ff0a4c8
completed the __all__ list and changed the module doctest
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59053
diff
changeset
|
27 "ExecError", "make_archive", "get_archive_formats", |
|
72087
bb214afa366f
Add missing name in shutil.__all__
Éric Araujo <merwok@netwok.org>
parents:
71956
diff
changeset
|
28 "register_archive_format", "unregister_archive_format", |
|
bb214afa366f
Add missing name in shutil.__all__
Éric Araujo <merwok@netwok.org>
parents:
71956
diff
changeset
|
29 "ignore_patterns"] |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
30 |
|
35505
26ba3d4f4fc4
No need to import exceptions, they are builtins
Neal Norwitz <nnorwitz@gmail.com>
parents:
35501
diff
changeset
|
31 class Error(EnvironmentError): |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
32 pass |
| 5 | 33 |
|
53652
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
34 class SpecialFileError(EnvironmentError): |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
35 """Raised when trying to do a kind of operation (e.g. copying) which is |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
36 not supported on a special file (e.g. a named pipe)""" |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
37 |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
38 class ExecError(EnvironmentError): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
39 """Raised when a command could not be executed""" |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
40 |
|
48216
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
41 try: |
|
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
42 WindowsError |
|
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
43 except NameError: |
|
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
44 WindowsError = None |
|
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
45 |
|
13571
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
46 def copyfileobj(fsrc, fdst, length=16*1024): |
|
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
47 """copy data from file-like object fsrc to file-like object fdst""" |
|
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
48 while 1: |
|
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
49 buf = fsrc.read(length) |
|
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
50 if not buf: |
|
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
51 break |
|
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
52 fdst.write(buf) |
|
3a8c670309a2
apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents:
12285
diff
changeset
|
53 |
|
33124
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
54 def _samefile(src, dst): |
|
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
55 # Macintosh, Unix. |
| 60725 | 56 if hasattr(os.path, 'samefile'): |
|
33128
c2384601a241
Catch OSError raised when src or dst argument to os.path.samefile doesn't
Johannes Gijsbers <jlg@dds.nl>
parents:
33124
diff
changeset
|
57 try: |
|
c2384601a241
Catch OSError raised when src or dst argument to os.path.samefile doesn't
Johannes Gijsbers <jlg@dds.nl>
parents:
33124
diff
changeset
|
58 return os.path.samefile(src, dst) |
|
c2384601a241
Catch OSError raised when src or dst argument to os.path.samefile doesn't
Johannes Gijsbers <jlg@dds.nl>
parents:
33124
diff
changeset
|
59 except OSError: |
|
c2384601a241
Catch OSError raised when src or dst argument to os.path.samefile doesn't
Johannes Gijsbers <jlg@dds.nl>
parents:
33124
diff
changeset
|
60 return False |
|
33124
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
61 |
|
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
62 # All other platforms: check for same pathname. |
|
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
63 return (os.path.normcase(os.path.abspath(src)) == |
|
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
64 os.path.normcase(os.path.abspath(dst))) |
|
15872
3685ef2a55a4
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
13571
diff
changeset
|
65 |
| 5 | 66 def copyfile(src, dst): |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
67 """Copy data from src to dst""" |
|
33124
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
68 if _samefile(src, dst): |
|
61285
f0fa944b15c0
Merged revisions 80830 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59917
diff
changeset
|
69 raise Error("`%s` and `%s` are the same file" % (src, dst)) |
|
33124
dc647df53921
Raise an exception when src and dst refer to the same file via a hard link or a
Johannes Gijsbers <jlg@dds.nl>
parents:
32652
diff
changeset
|
70 |
|
53652
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
71 for fn in [src, dst]: |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
72 try: |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
73 st = os.stat(fn) |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
74 except OSError: |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
75 # File most likely does not exist |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
76 pass |
|
54593
602559fa5297
only test for named pipe when os.stat doesn't raise #6209
Benjamin Peterson <benjamin@python.org>
parents:
53652
diff
changeset
|
77 else: |
|
602559fa5297
only test for named pipe when os.stat doesn't raise #6209
Benjamin Peterson <benjamin@python.org>
parents:
53652
diff
changeset
|
78 # XXX What about other special files? (sockets, devices...) |
|
602559fa5297
only test for named pipe when os.stat doesn't raise #6209
Benjamin Peterson <benjamin@python.org>
parents:
53652
diff
changeset
|
79 if stat.S_ISFIFO(st.st_mode): |
|
602559fa5297
only test for named pipe when os.stat doesn't raise #6209
Benjamin Peterson <benjamin@python.org>
parents:
53652
diff
changeset
|
80 raise SpecialFileError("`%s` is a named pipe" % fn) |
|
61291
e3e466f53f9e
removed non needed lines
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
61284
diff
changeset
|
81 |
|
61285
f0fa944b15c0
Merged revisions 80830 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59917
diff
changeset
|
82 with open(src, 'rb') as fsrc: |
|
f0fa944b15c0
Merged revisions 80830 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59917
diff
changeset
|
83 with open(dst, 'wb') as fdst: |
|
f0fa944b15c0
Merged revisions 80830 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
59917
diff
changeset
|
84 copyfileobj(fsrc, fdst) |
| 5 | 85 |
| 86 def copymode(src, dst): | |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
87 """Copy mode bits from src to dst""" |
|
16084
4c307a12dcb9
Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents:
15872
diff
changeset
|
88 if hasattr(os, 'chmod'): |
|
4c307a12dcb9
Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents:
15872
diff
changeset
|
89 st = os.stat(src) |
|
23697
c0e8c07ae1d6
Replace obsolete stat module constants with
Walter Dörwald <walter@livinglogic.de>
parents:
23627
diff
changeset
|
90 mode = stat.S_IMODE(st.st_mode) |
|
16084
4c307a12dcb9
Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents:
15872
diff
changeset
|
91 os.chmod(dst, mode) |
| 5 | 92 |
| 93 def copystat(src, dst): | |
|
40872
53fd144a3f1a
Patch #1490190: posixmodule now includes os.chflags() and os.lchflags()
Martin v. Löwis <martin@v.loewis.de>
parents:
39307
diff
changeset
|
94 """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" |
|
5348
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
95 st = os.stat(src) |
|
23697
c0e8c07ae1d6
Replace obsolete stat module constants with
Walter Dörwald <walter@livinglogic.de>
parents:
23627
diff
changeset
|
96 mode = stat.S_IMODE(st.st_mode) |
|
16084
4c307a12dcb9
Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents:
15872
diff
changeset
|
97 if hasattr(os, 'utime'): |
|
23697
c0e8c07ae1d6
Replace obsolete stat module constants with
Walter Dörwald <walter@livinglogic.de>
parents:
23627
diff
changeset
|
98 os.utime(dst, (st.st_atime, st.st_mtime)) |
|
16084
4c307a12dcb9
Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents:
15872
diff
changeset
|
99 if hasattr(os, 'chmod'): |
|
4c307a12dcb9
Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents:
15872
diff
changeset
|
100 os.chmod(dst, mode) |
|
40872
53fd144a3f1a
Patch #1490190: posixmodule now includes os.chflags() and os.lchflags()
Martin v. Löwis <martin@v.loewis.de>
parents:
39307
diff
changeset
|
101 if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): |
|
59917
e3fdfdb1a8ff
Merged revisions 79299 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
51179
diff
changeset
|
102 try: |
|
e3fdfdb1a8ff
Merged revisions 79299 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
51179
diff
changeset
|
103 os.chflags(dst, st.st_flags) |
|
e3fdfdb1a8ff
Merged revisions 79299 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
51179
diff
changeset
|
104 except OSError, why: |
|
76869
e12efebc3ba6
Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents:
72087
diff
changeset
|
105 for err in 'EOPNOTSUPP', 'ENOTSUP': |
|
e12efebc3ba6
Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents:
72087
diff
changeset
|
106 if hasattr(errno, err) and why.errno == getattr(errno, err): |
|
e12efebc3ba6
Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents:
72087
diff
changeset
|
107 break |
|
e12efebc3ba6
Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents:
72087
diff
changeset
|
108 else: |
|
59917
e3fdfdb1a8ff
Merged revisions 79299 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
51179
diff
changeset
|
109 raise |
| 5 | 110 |
| 111 def copy(src, dst): | |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
112 """Copy data and mode bits ("cp src dst"). |
|
15872
3685ef2a55a4
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
13571
diff
changeset
|
113 |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
114 The destination may be a directory. |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
115 |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
116 """ |
|
5348
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
117 if os.path.isdir(dst): |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
118 dst = os.path.join(dst, os.path.basename(src)) |
|
5348
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
119 copyfile(src, dst) |
|
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
120 copymode(src, dst) |
| 5 | 121 |
| 122 def copy2(src, dst): | |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
123 """Copy data and all stat info ("cp -p src dst"). |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
124 |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
125 The destination may be a directory. |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
126 |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
127 """ |
|
5348
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
128 if os.path.isdir(dst): |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
129 dst = os.path.join(dst, os.path.basename(src)) |
|
5348
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
130 copyfile(src, dst) |
|
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
131 copystat(src, dst) |
| 5 | 132 |
|
47888
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
133 def ignore_patterns(*patterns): |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
134 """Function that can be used as copytree() ignore parameter. |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
135 |
|
47888
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
136 Patterns is a sequence of glob-style patterns |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
137 that are used to exclude files""" |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
138 def _ignore_patterns(path, names): |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
139 ignored_names = [] |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
140 for pattern in patterns: |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
141 ignored_names.extend(fnmatch.filter(names, pattern)) |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
142 return set(ignored_names) |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
143 return _ignore_patterns |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
144 |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
145 def copytree(src, dst, symlinks=False, ignore=None): |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
146 """Recursively copy a directory tree using copy2(). |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
147 |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
148 The destination directory must not already exist. |
|
28025
e63f1eccd250
Fix SF bug #691276, shutil.copytree documentation bug
Neal Norwitz <nnorwitz@gmail.com>
parents:
27361
diff
changeset
|
149 If exception(s) occur, an Error is raised with a list of reasons. |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
150 |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
151 If the optional symlinks flag is true, symbolic links in the |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
152 source tree result in symbolic links in the destination tree; if |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
153 it is false, the contents of the files pointed to by symbolic |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
154 links are copied. |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
155 |
|
47888
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
156 The optional ignore argument is a callable. If given, it |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
157 is called with the `src` parameter, which is the directory |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
158 being visited by copytree(), and `names` which is the list of |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
159 `src` contents, as returned by os.listdir(): |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
160 |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
161 callable(src, names) -> ignored_names |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
162 |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
163 Since copytree() is called recursively, the callable will be |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
164 called once for each directory that is copied. It returns a |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
165 list of names relative to the `src` directory that should |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
166 not be copied. |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
167 |
|
5349
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
168 XXX Consider this example code rather than the ultimate tool. |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
169 |
|
6ab392d7a52f
Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents:
5348
diff
changeset
|
170 """ |
|
5348
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
171 names = os.listdir(src) |
|
47888
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
172 if ignore is not None: |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
173 ignored_names = ignore(src, names) |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
174 else: |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
175 ignored_names = set() |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
176 |
| 34364 | 177 os.makedirs(dst) |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
178 errors = [] |
|
5348
ae02ed2aac3f
Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents:
5347
diff
changeset
|
179 for name in names: |
|
47888
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
180 if name in ignored_names: |
|
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
181 continue |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
182 srcname = os.path.join(src, name) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
183 dstname = os.path.join(dst, name) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
184 try: |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
185 if symlinks and os.path.islink(srcname): |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
186 linkto = os.readlink(srcname) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
187 os.symlink(linkto, dstname) |
|
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
188 elif os.path.isdir(srcname): |
|
47888
d7526670ff0a
#2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.
Georg Brandl <georg@python.org>
parents:
45858
diff
changeset
|
189 copytree(srcname, dstname, symlinks, ignore) |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
190 else: |
|
53652
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
191 # Will raise a SpecialFileError for unsupported file types |
|
7755
fb4b4d069cc7
Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents:
7203
diff
changeset
|
192 copy2(srcname, dstname) |
|
35501
ed65e0ad2215
patch [ 1242454 ] shutil.copytree() quits too soon after an error.
Georg Brandl <georg@python.org>
parents:
34485
diff
changeset
|
193 # catch the Error from the recursive copytree so that we can |
|
ed65e0ad2215
patch [ 1242454 ] shutil.copytree() quits too soon after an error.
Georg Brandl <georg@python.org>
parents:
34485
diff
changeset
|
194 # continue with other files |
|
ed65e0ad2215
patch [ 1242454 ] shutil.copytree() quits too soon after an error.
Georg Brandl <georg@python.org>
parents:
34485
diff
changeset
|
195 except Error, err: |
|
ed65e0ad2215
patch [ 1242454 ] shutil.copytree() quits too soon after an error.
Georg Brandl <georg@python.org>
parents:
34485
diff
changeset
|
196 errors.extend(err.args[0]) |
|
53652
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
197 except EnvironmentError, why: |
|
409448d455e3
Issue #3002: `shutil.copyfile()` and `shutil.copytree()` now raise an
Antoine Pitrou <solipsis@pitrou.net>
parents:
51446
diff
changeset
|
198 errors.append((srcname, dstname, str(why))) |
|
39307
9377c6604542
Don't copy directory stat times in shutil.copytree on Windows
Martin v. Löwis <martin@v.loewis.de>
parents:
38032
diff
changeset
|
199 try: |
|
9377c6604542
Don't copy directory stat times in shutil.copytree on Windows
Martin v. Löwis <martin@v.loewis.de>
parents:
38032
diff
changeset
|
200 copystat(src, dst) |
|
9377c6604542
Don't copy directory stat times in shutil.copytree on Windows
Martin v. Löwis <martin@v.loewis.de>
parents:
38032
diff
changeset
|
201 except OSError, why: |
|
48216
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
202 if WindowsError is not None and isinstance(why, WindowsError): |
|
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
203 # Copying file access times may fail on Windows |
|
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
204 pass |
|
ef41dae30f35
#3134: shutil referenced undefined WindowsError symbol
Georg Brandl <georg@python.org>
parents:
39307
diff
changeset
|
205 else: |
|
78763
fe3d113e139d
Fix wrong way of adding Error information in shutil.copytree.
Georg Brandl <georg@python.org>
parents:
76869
diff
changeset
|
206 errors.append((src, dst, str(why))) |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
207 if errors: |
|
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
208 raise Error, errors |
|
7203
8c129a567867
Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents:
5349
diff
changeset
|
209 |
|
27361
891ec4d266d1
rmtree(): Make implementation agree with documentation (both latex and
Barry Warsaw <barry@python.org>
parents:
27096
diff
changeset
|
210 def rmtree(path, ignore_errors=False, onerror=None): |
|
7203
8c129a567867
Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents:
5349
diff
changeset
|
211 """Recursively delete a directory tree. |
|
8c129a567867
Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents:
5349
diff
changeset
|
212 |
|
33865
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
213 If ignore_errors is set, errors are ignored; otherwise, if onerror |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
214 is set, it is called to handle the error with arguments (func, |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
215 path, exc_info) where func is os.listdir, os.remove, or os.rmdir; |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
216 path is the argument to that function that caused it to fail; and |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
217 exc_info is a tuple returned by sys.exc_info(). If ignore_errors |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
218 is false and onerror is None, an exception is raised. |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
219 |
|
7203
8c129a567867
Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents:
5349
diff
changeset
|
220 """ |
|
33865
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
221 if ignore_errors: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
222 def onerror(*args): |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
223 pass |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
224 elif onerror is None: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
225 def onerror(*args): |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
226 raise |
|
44823
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
227 try: |
|
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
228 if os.path.islink(path): |
|
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
229 # symlinks to directories are forbidden, see bug #1669 |
|
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
230 raise OSError("Cannot call rmtree on a symbolic link") |
|
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
231 except OSError: |
|
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
232 onerror(os.path.islink, path, sys.exc_info()) |
|
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
233 # can't continue even if onerror hook returns |
|
eaca2367ecc9
#1669: don't allow shutil.rmtree() to be called on a symlink.
Georg Brandl <georg@python.org>
parents:
40872
diff
changeset
|
234 return |
|
33865
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
235 names = [] |
|
27361
891ec4d266d1
rmtree(): Make implementation agree with documentation (both latex and
Barry Warsaw <barry@python.org>
parents:
27096
diff
changeset
|
236 try: |
|
33865
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
237 names = os.listdir(path) |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
238 except os.error, err: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
239 onerror(os.listdir, path, sys.exc_info()) |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
240 for name in names: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
241 fullname = os.path.join(path, name) |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
242 try: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
243 mode = os.lstat(fullname).st_mode |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
244 except os.error: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
245 mode = 0 |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
246 if stat.S_ISDIR(mode): |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
247 rmtree(fullname, ignore_errors, onerror) |
|
27361
891ec4d266d1
rmtree(): Make implementation agree with documentation (both latex and
Barry Warsaw <barry@python.org>
parents:
27096
diff
changeset
|
248 else: |
|
33865
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
249 try: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
250 os.remove(fullname) |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
251 except os.error, err: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
252 onerror(os.remove, fullname, sys.exc_info()) |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
253 try: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
254 os.rmdir(path) |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
255 except os.error: |
|
f196716ea0db
Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents:
33687
diff
changeset
|
256 onerror(os.rmdir, path, sys.exc_info()) |
|
7203
8c129a567867
Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents:
5349
diff
changeset
|
257 |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
258 |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
259 def _basename(path): |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
260 # A basename() variant which first strips the trailing slash, if present. |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
261 # Thus we always get the last component of the path, even for directories. |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
262 return os.path.basename(path.rstrip(os.path.sep)) |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
263 |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
264 def move(src, dst): |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
265 """Recursively move a file or directory to another location. This is |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
266 similar to the Unix "mv" command. |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
267 |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
268 If the destination is a directory or a symlink to a directory, the source |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
269 is moved inside the directory. The destination path must not already |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
270 exist. |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
271 |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
272 If the destination already exists but is not a directory, it may be |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
273 overwritten depending on os.rename() semantics. |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
274 |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
275 If the destination is on our current filesystem, then rename() is used. |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
276 Otherwise, src is copied to the destination and then removed. |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
277 A lot more could be done here... A look at a mv.c shows a lot of |
|
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
278 the issues this implementation glosses over. |
|
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
279 |
|
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
280 """ |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
281 real_dst = dst |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
282 if os.path.isdir(dst): |
|
69872
051190230254
Backport fix for issue #10684 from 3.x
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
68256
diff
changeset
|
283 if _samefile(src, dst): |
|
051190230254
Backport fix for issue #10684 from 3.x
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
68256
diff
changeset
|
284 # We might be on a case insensitive filesystem, |
|
051190230254
Backport fix for issue #10684 from 3.x
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
68256
diff
changeset
|
285 # perform the rename anyway. |
|
051190230254
Backport fix for issue #10684 from 3.x
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
68256
diff
changeset
|
286 os.rename(src, dst) |
|
051190230254
Backport fix for issue #10684 from 3.x
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
68256
diff
changeset
|
287 return |
|
051190230254
Backport fix for issue #10684 from 3.x
Ronald Oussoren <ronaldoussoren@mac.com>
parents:
68256
diff
changeset
|
288 |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
289 real_dst = os.path.join(dst, _basename(src)) |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
290 if os.path.exists(real_dst): |
|
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
291 raise Error, "Destination path '%s' already exists" % real_dst |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
292 try: |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
293 os.rename(src, real_dst) |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
294 except OSError: |
|
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
295 if os.path.isdir(src): |
|
51446
0ab36796dd79
make destinsrc private
Benjamin Peterson <benjamin@python.org>
parents:
51179
diff
changeset
|
296 if _destinsrc(src, dst): |
|
32386
686e5d38be42
shutil.move() will raise an exception when trying to move a directory into
Brett Cannon <bcannon@gmail.com>
parents:
28025
diff
changeset
|
297 raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst) |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
298 copytree(src, real_dst, symlinks=True) |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
299 rmtree(src) |
|
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
300 else: |
|
45858
923380acd1cd
Issue 1577: shutil.move() where destination is a directory was doing a
Sean Reifscheider <jafo@tummy.com>
parents:
44823
diff
changeset
|
301 copy2(src, real_dst) |
|
25641
13438586daa6
Patch #448038: Add move(). Report errors from copytree as in shutil.Error.
Martin v. Löwis <martin@v.loewis.de>
parents:
25170
diff
changeset
|
302 os.unlink(src) |
|
32386
686e5d38be42
shutil.move() will raise an exception when trying to move a directory into
Brett Cannon <bcannon@gmail.com>
parents:
28025
diff
changeset
|
303 |
|
51446
0ab36796dd79
make destinsrc private
Benjamin Peterson <benjamin@python.org>
parents:
51179
diff
changeset
|
304 def _destinsrc(src, dst): |
|
51179
e2dcad56e40e
Merged revisions 69100 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
48214
diff
changeset
|
305 src = abspath(src) |
|
e2dcad56e40e
Merged revisions 69100 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
48214
diff
changeset
|
306 dst = abspath(dst) |
|
e2dcad56e40e
Merged revisions 69100 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
48214
diff
changeset
|
307 if not src.endswith(os.path.sep): |
|
e2dcad56e40e
Merged revisions 69100 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
48214
diff
changeset
|
308 src += os.path.sep |
|
e2dcad56e40e
Merged revisions 69100 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
48214
diff
changeset
|
309 if not dst.endswith(os.path.sep): |
|
e2dcad56e40e
Merged revisions 69100 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
48214
diff
changeset
|
310 dst += os.path.sep |
|
e2dcad56e40e
Merged revisions 69100 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
48214
diff
changeset
|
311 return dst.startswith(src) |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
312 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
313 def _get_gid(name): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
314 """Returns a gid, given a group name.""" |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
315 if getgrnam is None or name is None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
316 return None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
317 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
318 result = getgrnam(name) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
319 except KeyError: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
320 result = None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
321 if result is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
322 return result[2] |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
323 return None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
324 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
325 def _get_uid(name): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
326 """Returns an uid, given a user name.""" |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
327 if getpwnam is None or name is None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
328 return None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
329 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
330 result = getpwnam(name) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
331 except KeyError: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
332 result = None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
333 if result is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
334 return result[2] |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
335 return None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
336 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
337 def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
338 owner=None, group=None, logger=None): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
339 """Create a (possibly compressed) tar file from all the files under |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
340 'base_dir'. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
341 |
|
60788
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
342 'compress' must be "gzip" (the default), "bzip2", or None. |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
343 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
344 'owner' and 'group' can be used to define an owner and a group for the |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
345 archive that is being built. If not provided, the current owner and group |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
346 will be used. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
347 |
|
66934
5b44059247db
Merged revisions 87277 via svnmerge from
Éric Araujo <merwok@netwok.org>
parents:
61291
diff
changeset
|
348 The output tar file will be named 'base_name' + ".tar", possibly plus |
|
60788
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
349 the appropriate compression extension (".gz", or ".bz2"). |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
350 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
351 Returns the output filename. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
352 """ |
|
60788
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
353 tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: ''} |
|
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
354 compress_ext = {'gzip': '.gz', 'bzip2': '.bz2'} |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
355 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
356 # flags for compression program, each element of list will be an argument |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
357 if compress is not None and compress not in compress_ext.keys(): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
358 raise ValueError, \ |
|
60788
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
359 ("bad value for 'compress': must be None, 'gzip' or 'bzip2'") |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
360 |
|
60788
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
361 archive_name = base_name + '.tar' + compress_ext.get(compress, '') |
|
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
362 archive_dir = os.path.dirname(archive_name) |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
363 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
364 if not os.path.exists(archive_dir): |
|
71956
615a29295d5f
Guard shutil._make_archive against a logger=None argument.
Éric Araujo <merwok@netwok.org>
parents:
69872
diff
changeset
|
365 if logger is not None: |
|
615a29295d5f
Guard shutil._make_archive against a logger=None argument.
Éric Araujo <merwok@netwok.org>
parents:
69872
diff
changeset
|
366 logger.info("creating %s", archive_dir) |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
367 if not dry_run: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
368 os.makedirs(archive_dir) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
369 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
370 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
371 # creating the tarball |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
372 import tarfile # late import so Python build itself doesn't break |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
373 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
374 if logger is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
375 logger.info('Creating tar archive') |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
376 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
377 uid = _get_uid(owner) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
378 gid = _get_gid(group) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
379 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
380 def _set_uid_gid(tarinfo): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
381 if gid is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
382 tarinfo.gid = gid |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
383 tarinfo.gname = group |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
384 if uid is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
385 tarinfo.uid = uid |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
386 tarinfo.uname = owner |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
387 return tarinfo |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
388 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
389 if not dry_run: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
390 tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
391 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
392 tar.add(base_dir, filter=_set_uid_gid) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
393 finally: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
394 tar.close() |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
395 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
396 return archive_name |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
397 |
|
60807
2db06fae8c2e
shutil: removed unused import and fixed attributes names in _call_external_zip
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60788
diff
changeset
|
398 def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
399 # XXX see if we want to keep an external call here |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
400 if verbose: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
401 zipoptions = "-r" |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
402 else: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
403 zipoptions = "-rq" |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
404 from distutils.errors import DistutilsExecError |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
405 from distutils.spawn import spawn |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
406 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
407 spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
408 except DistutilsExecError: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
409 # XXX really should distinguish between "couldn't find |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
410 # external 'zip' command" and "zip failed". |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
411 raise ExecError, \ |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
412 ("unable to create zip file '%s': " |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
413 "could neither import the 'zipfile' module nor " |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
414 "find a standalone zip utility") % zip_filename |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
415 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
416 def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
417 """Create a zip file from all the files under 'base_dir'. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
418 |
|
66934
5b44059247db
Merged revisions 87277 via svnmerge from
Éric Araujo <merwok@netwok.org>
parents:
61291
diff
changeset
|
419 The output zip file will be named 'base_name' + ".zip". Uses either the |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
420 "zipfile" Python module (if available) or the InfoZIP "zip" utility |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
421 (if installed and found on the default search path). If neither tool is |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
422 available, raises ExecError. Returns the name of the output zip |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
423 file. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
424 """ |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
425 zip_filename = base_name + ".zip" |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
426 archive_dir = os.path.dirname(base_name) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
427 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
428 if not os.path.exists(archive_dir): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
429 if logger is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
430 logger.info("creating %s", archive_dir) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
431 if not dry_run: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
432 os.makedirs(archive_dir) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
433 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
434 # If zipfile module is not available, try spawning an external 'zip' |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
435 # command. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
436 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
437 import zipfile |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
438 except ImportError: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
439 zipfile = None |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
440 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
441 if zipfile is None: |
|
60807
2db06fae8c2e
shutil: removed unused import and fixed attributes names in _call_external_zip
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60788
diff
changeset
|
442 _call_external_zip(base_dir, zip_filename, verbose, dry_run) |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
443 else: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
444 if logger is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
445 logger.info("creating '%s' and adding '%s' to it", |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
446 zip_filename, base_dir) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
447 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
448 if not dry_run: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
449 zip = zipfile.ZipFile(zip_filename, "w", |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
450 compression=zipfile.ZIP_DEFLATED) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
451 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
452 for dirpath, dirnames, filenames in os.walk(base_dir): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
453 for name in filenames: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
454 path = os.path.normpath(os.path.join(dirpath, name)) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
455 if os.path.isfile(path): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
456 zip.write(path, path) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
457 if logger is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
458 logger.info("adding '%s'", path) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
459 zip.close() |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
460 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
461 return zip_filename |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
462 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
463 _ARCHIVE_FORMATS = { |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
464 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
465 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
466 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
467 'zip': (_make_zipfile, [],"ZIP file") |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
468 } |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
469 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
470 def get_archive_formats(): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
471 """Returns a list of supported formats for archiving and unarchiving. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
472 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
473 Each element of the returned sequence is a tuple (name, description) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
474 """ |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
475 formats = [(name, registry[2]) for name, registry in |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
476 _ARCHIVE_FORMATS.items()] |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
477 formats.sort() |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
478 return formats |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
479 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
480 def register_archive_format(name, function, extra_args=None, description=''): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
481 """Registers an archive format. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
482 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
483 name is the name of the format. function is the callable that will be |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
484 used to create archives. If provided, extra_args is a sequence of |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
485 (name, value) tuples that will be passed as arguments to the callable. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
486 description can be provided to describe the format, and will be returned |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
487 by the get_archive_formats() function. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
488 """ |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
489 if extra_args is None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
490 extra_args = [] |
|
59431
e2d41079d059
Fix some py3k warnings in the standard library.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
59058
diff
changeset
|
491 if not isinstance(function, collections.Callable): |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
492 raise TypeError('The %s object is not callable' % function) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
493 if not isinstance(extra_args, (tuple, list)): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
494 raise TypeError('extra_args needs to be a sequence') |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
495 for element in extra_args: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
496 if not isinstance(element, (tuple, list)) or len(element) !=2 : |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
497 raise TypeError('extra_args elements are : (arg_name, value)') |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
498 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
499 _ARCHIVE_FORMATS[name] = (function, extra_args, description) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
500 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
501 def unregister_archive_format(name): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
502 del _ARCHIVE_FORMATS[name] |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
503 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
504 def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
505 dry_run=0, owner=None, group=None, logger=None): |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
506 """Create an archive file (eg. zip or tar). |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
507 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
508 'base_name' is the name of the file to create, minus any format-specific |
|
60788
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
509 extension; 'format' is the archive format: one of "zip", "tar", "bztar" |
|
4ddca7fd3639
removed ztar support in shutil.make_archive
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
60728
diff
changeset
|
510 or "gztar". |
|
59053
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
511 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
512 'root_dir' is a directory that will be the root directory of the |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
513 archive; ie. we typically chdir into 'root_dir' before creating the |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
514 archive. 'base_dir' is the directory where we start archiving from; |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
515 ie. 'base_dir' will be the common prefix of all files and |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
516 directories in the archive. 'root_dir' and 'base_dir' both default |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
517 to the current directory. Returns the name of the archive file. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
518 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
519 'owner' and 'group' are used when creating a tar archive. By default, |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
520 uses the current owner and group. |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
521 """ |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
522 save_cwd = os.getcwd() |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
523 if root_dir is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
524 if logger is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
525 logger.debug("changing into '%s'", root_dir) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
526 base_name = os.path.abspath(base_name) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
527 if not dry_run: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
528 os.chdir(root_dir) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
529 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
530 if base_dir is None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
531 base_dir = os.curdir |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
532 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
533 kwargs = {'dry_run': dry_run, 'logger': logger} |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
534 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
535 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
536 format_info = _ARCHIVE_FORMATS[format] |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
537 except KeyError: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
538 raise ValueError, "unknown archive format '%s'" % format |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
539 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
540 func = format_info[0] |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
541 for arg, val in format_info[1]: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
542 kwargs[arg] = val |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
543 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
544 if format != 'zip': |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
545 kwargs['owner'] = owner |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
546 kwargs['group'] = group |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
547 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
548 try: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
549 filename = func(base_name, base_dir, **kwargs) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
550 finally: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
551 if root_dir is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
552 if logger is not None: |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
553 logger.debug("changing back to '%s'", save_cwd) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
554 os.chdir(save_cwd) |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
555 |
|
ac36ec8bae6c
added make_archive (and secondary APIs) to shutil
Tarek Ziadé <ziade.tarek@gmail.com>
parents:
54593
diff
changeset
|
556 return filename |
