annotate Lib/shutil.py @ 78069:a8aa77458e12 3.2

Add c_size_t and c_ssize_t to the ctypes summary table.
author Antoine Pitrou <solipsis@pitrou.net>
date Thu, 12 Jul 2012 20:31:50 +0200
parents ae141eebcf96
children a2bf95458eed 4e9680570be8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
59060
df56ba1cb0af Merged revisions 78364 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59056
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
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6
771
2e82dd0f8a9e posix -> os
Guido van Rossum <guido@python.org>
parents: 363
diff changeset
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
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
11 import fnmatch
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
12 import collections
59919
1dc18412a7ee Merged revisions 79301 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 54594
diff changeset
13 import errno
61062
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
14 import tarfile
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
15
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
16 try:
61087
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
17 import bz2
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
18 _BZ2_SUPPORTED = True
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
19 except ImportError:
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
20 _BZ2_SUPPORTED = False
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
21
61087
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
22 try:
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
23 from pwd import getpwnam
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
24 except ImportError:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
25 getpwnam = None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
26
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
27 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
28 from grp import getgrnam
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
29 except ImportError:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
30 getgrnam = None
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
31
59060
df56ba1cb0af Merged revisions 78364 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59056
diff changeset
32 __all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2",
df56ba1cb0af Merged revisions 78364 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59056
diff changeset
33 "copytree", "move", "rmtree", "Error", "SpecialFileError",
df56ba1cb0af Merged revisions 78364 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59056
diff changeset
34 "ExecError", "make_archive", "get_archive_formats",
61062
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
35 "register_archive_format", "unregister_archive_format",
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
36 "get_unpack_formats", "register_unpack_format",
72235
2f549ddd5bdc Add missing name in shutil
Éric Araujo <merwok@netwok.org>
parents: 69870
diff changeset
37 "unregister_unpack_format", "unpack_archive", "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
38
35505
26ba3d4f4fc4 No need to import exceptions, they are builtins
Neal Norwitz <nnorwitz@gmail.com>
parents: 35501
diff changeset
39 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
40 pass
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
41
53653
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
42 class SpecialFileError(EnvironmentError):
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
43 """Raised when trying to do a kind of operation (e.g. copying) which is
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
44 not supported on a special file (e.g. a named pipe)"""
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
45
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
46 class ExecError(EnvironmentError):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
47 """Raised when a command could not be executed"""
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
48
61062
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
49 class ReadError(EnvironmentError):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
50 """Raised when an archive cannot be read"""
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
51
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
52 class RegistryError(Exception):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
53 """Raised when a registery operation with the archiving
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
54 and unpacking registeries fails"""
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
55
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
56
48680
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
57 try:
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
58 WindowsError
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
59 except NameError:
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
60 WindowsError = None
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
61
13571
3a8c670309a2 apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents: 12285
diff changeset
62 def copyfileobj(fsrc, fdst, length=16*1024):
3a8c670309a2 apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents: 12285
diff changeset
63 """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
64 while 1:
3a8c670309a2 apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents: 12285
diff changeset
65 buf = fsrc.read(length)
3a8c670309a2 apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents: 12285
diff changeset
66 if not buf:
3a8c670309a2 apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents: 12285
diff changeset
67 break
3a8c670309a2 apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents: 12285
diff changeset
68 fdst.write(buf)
3a8c670309a2 apply patch #100868 from Moshe Zadka:
Greg Stein <gstein@lyra.org>
parents: 12285
diff changeset
69
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 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
71 # Macintosh, Unix.
60726
71860cdb4886 Merged revisions 80218 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59918
diff changeset
72 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
73 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
74 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
75 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
76 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
77
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
78 # 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
79 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
80 os.path.normcase(os.path.abspath(dst)))
15872
3685ef2a55a4 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 13571
diff changeset
81
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 def copyfile(src, dst):
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
83 """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
84 if _samefile(src, dst):
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 40893
diff changeset
85 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
86
53653
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
87 for fn in [src, dst]:
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
88 try:
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
89 st = os.stat(fn)
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
90 except OSError:
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
91 # File most likely does not exist
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
92 pass
54594
da33bed5d8c4 Merged revisions 73250 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53653
diff changeset
93 else:
da33bed5d8c4 Merged revisions 73250 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53653
diff changeset
94 # XXX What about other special files? (sockets, devices...)
da33bed5d8c4 Merged revisions 73250 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53653
diff changeset
95 if stat.S_ISFIFO(st.st_mode):
da33bed5d8c4 Merged revisions 73250 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53653
diff changeset
96 raise SpecialFileError("`%s` is a named pipe" % fn)
61289
78e7fc01c51a Merged revisions 80833 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59919
diff changeset
97
78e7fc01c51a Merged revisions 80833 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59919
diff changeset
98 with open(src, 'rb') as fsrc:
78e7fc01c51a Merged revisions 80833 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59919
diff changeset
99 with open(dst, 'wb') as fdst:
78e7fc01c51a Merged revisions 80833 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 59919
diff changeset
100 copyfileobj(fsrc, fdst)
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
101
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 def copymode(src, dst):
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
103 """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
104 if hasattr(os, 'chmod'):
4c307a12dcb9 Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents: 15872
diff changeset
105 st = os.stat(src)
23697
c0e8c07ae1d6 Replace obsolete stat module constants with
Walter Dörwald <walter@livinglogic.de>
parents: 23627
diff changeset
106 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
107 os.chmod(dst, mode)
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
108
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 def copystat(src, dst):
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40587
diff changeset
110 """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
111 st = os.stat(src)
23697
c0e8c07ae1d6 Replace obsolete stat module constants with
Walter Dörwald <walter@livinglogic.de>
parents: 23627
diff changeset
112 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
113 if hasattr(os, 'utime'):
23697
c0e8c07ae1d6 Replace obsolete stat module constants with
Walter Dörwald <walter@livinglogic.de>
parents: 23627
diff changeset
114 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
115 if hasattr(os, 'chmod'):
4c307a12dcb9 Patch #103342: Make shutil.copytree more useful under Jython.
Tim Peters <tim.peters@gmail.com>
parents: 15872
diff changeset
116 os.chmod(dst, mode)
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40587
diff changeset
117 if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
59919
1dc18412a7ee Merged revisions 79301 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 54594
diff changeset
118 try:
1dc18412a7ee Merged revisions 79301 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 54594
diff changeset
119 os.chflags(dst, st.st_flags)
1dc18412a7ee Merged revisions 79301 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 54594
diff changeset
120 except OSError as why:
76870
ae141eebcf96 Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents: 74791
diff changeset
121 for err in 'EOPNOTSUPP', 'ENOTSUP':
ae141eebcf96 Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents: 74791
diff changeset
122 if hasattr(errno, err) and why.errno == getattr(errno, err):
ae141eebcf96 Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents: 74791
diff changeset
123 break
ae141eebcf96 Issue #14662: Prevent shutil failures on OS X when destination does not
Ned Deily <nad@acm.org>
parents: 74791
diff changeset
124 else:
59919
1dc18412a7ee Merged revisions 79301 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 54594
diff changeset
125 raise
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
126
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
127 def copy(src, dst):
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
128 """Copy data and mode bits ("cp src dst").
15872
3685ef2a55a4 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 13571
diff changeset
129
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
130 The destination may be a directory.
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
131
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
132 """
5348
ae02ed2aac3f Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents: 5347
diff changeset
133 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
134 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
135 copyfile(src, dst)
ae02ed2aac3f Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents: 5347
diff changeset
136 copymode(src, dst)
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
137
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
138 def copy2(src, dst):
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
139 """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
140
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
141 The destination may be a directory.
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
142
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
143 """
5348
ae02ed2aac3f Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents: 5347
diff changeset
144 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
145 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
146 copyfile(src, dst)
ae02ed2aac3f Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents: 5347
diff changeset
147 copystat(src, dst)
5
5570dbb1ce55 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
148
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
149 def ignore_patterns(*patterns):
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
150 """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
151
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
152 Patterns is a sequence of glob-style patterns
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
153 that are used to exclude files"""
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
154 def _ignore_patterns(path, names):
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
155 ignored_names = []
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
156 for pattern in patterns:
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
157 ignored_names.extend(fnmatch.filter(names, pattern))
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
158 return set(ignored_names)
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
159 return _ignore_patterns
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
160
60751
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
161 def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
162 ignore_dangling_symlinks=False):
60737
be17bda5a658 Fixed #1540112: now shutil.copytree will let you provide your own copy() function
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60731
diff changeset
163 """Recursively copy a directory tree.
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
164
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
165 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
166 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
167
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
168 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
169 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
170 it is false, the contents of the files pointed to by symbolic
60751
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
171 links are copied. If the file pointed by the symlink doesn't
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
172 exist, an exception will be added in the list of errors raised in
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
173 an Error exception at the end of the copy process.
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
174
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
175 You can set the optional ignore_dangling_symlinks flag to true if you
60892
d426bbfd5bd7 added a note about the ignore_dangling_symlinks option
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60810
diff changeset
176 want to silence this exception. Notice that this has no effect on
d426bbfd5bd7 added a note about the ignore_dangling_symlinks option
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60810
diff changeset
177 platforms that don't support os.symlink.
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
178
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
179 The optional ignore argument is a callable. If given, it
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
180 is called with the `src` parameter, which is the directory
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
181 being visited by copytree(), and `names` which is the list of
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
182 `src` contents, as returned by os.listdir():
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
183
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
184 callable(src, names) -> ignored_names
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
185
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
186 Since copytree() is called recursively, the callable will be
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
187 called once for each directory that is copied. It returns a
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
188 list of names relative to the `src` directory that should
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
189 not be copied.
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
190
60737
be17bda5a658 Fixed #1540112: now shutil.copytree will let you provide your own copy() function
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60731
diff changeset
191 The optional copy_function argument is a callable that will be used
be17bda5a658 Fixed #1540112: now shutil.copytree will let you provide your own copy() function
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60731
diff changeset
192 to copy each file. It will be called with the source path and the
be17bda5a658 Fixed #1540112: now shutil.copytree will let you provide your own copy() function
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60731
diff changeset
193 destination path as arguments. By default, copy2() is used, but any
be17bda5a658 Fixed #1540112: now shutil.copytree will let you provide your own copy() function
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60731
diff changeset
194 function that supports the same signature (like copy()) can be used.
5349
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
195
6ab392d7a52f Transformed comments to doc strings.
Guido van Rossum <guido@python.org>
parents: 5348
diff changeset
196 """
5348
ae02ed2aac3f Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents: 5347
diff changeset
197 names = os.listdir(src)
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
198 if ignore is not None:
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
199 ignored_names = ignore(src, names)
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
200 else:
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
201 ignored_names = set()
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
202
34364
19e61a2a5632 Patch #1094015:
Johannes Gijsbers <jlg@dds.nl>
parents: 33865
diff changeset
203 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
204 errors = []
5348
ae02ed2aac3f Reindented at 4 spaces.
Guido van Rossum <guido@python.org>
parents: 5347
diff changeset
205 for name in names:
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
206 if name in ignored_names:
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 45865
diff changeset
207 continue
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 7203
diff changeset
208 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
209 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
210 try:
60751
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
211 if os.path.islink(srcname):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 7203
diff changeset
212 linkto = os.readlink(srcname)
60751
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
213 if symlinks:
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
214 os.symlink(linkto, dstname)
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
215 else:
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
216 # ignore dangling symlink if the flag is on
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
217 if not os.path.exists(linkto) and ignore_dangling_symlinks:
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
218 continue
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
219 # otherwise let the copy occurs. copy2 will raise an error
82de0b488f2d Fixed #6547: Added the ignore_dangling_symlinks option to shutil.copytree
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60737
diff changeset
220 copy_function(srcname, dstname)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 7203
diff changeset
221 elif os.path.isdir(srcname):
60737
be17bda5a658 Fixed #1540112: now shutil.copytree will let you provide your own copy() function
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60731
diff changeset
222 copytree(srcname, dstname, symlinks, ignore, copy_function)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 7203
diff changeset
223 else:
53653
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
224 # Will raise a SpecialFileError for unsupported file types
60737
be17bda5a658 Fixed #1540112: now shutil.copytree will let you provide your own copy() function
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60731
diff changeset
225 copy_function(srcname, dstname)
35501
ed65e0ad2215 patch [ 1242454 ] shutil.copytree() quits too soon after an error.
Georg Brandl <georg@python.org>
parents: 34485
diff changeset
226 # 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
227 # continue with other files
40587
6b18a095c2e7 SF patch 1631942 by Collin Winter:
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
228 except Error as err:
35501
ed65e0ad2215 patch [ 1242454 ] shutil.copytree() quits too soon after an error.
Georg Brandl <georg@python.org>
parents: 34485
diff changeset
229 errors.extend(err.args[0])
53653
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
230 except EnvironmentError as why:
960ef00d5214 Merged revisions 72178 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 51750
diff changeset
231 errors.append((srcname, dstname, str(why)))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 38453
diff changeset
232 try:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 38453
diff changeset
233 copystat(src, dst)
40587
6b18a095c2e7 SF patch 1631942 by Collin Winter:
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
234 except OSError as why:
48680
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
235 if WindowsError is not None and isinstance(why, WindowsError):
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
236 # Copying file access times may fail on Windows
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
237 pass
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
238 else:
7779af388aec Merged revisions 65459,65472,65481,65518,65536,65581,65609,65637,65641,65644-65645 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48499
diff changeset
239 errors.extend((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
240 if errors:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 40893
diff changeset
241 raise Error(errors)
7203
8c129a567867 Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents: 5349
diff changeset
242
27361
891ec4d266d1 rmtree(): Make implementation agree with documentation (both latex and
Barry Warsaw <barry@python.org>
parents: 27096
diff changeset
243 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
244 """Recursively delete a directory tree.
8c129a567867 Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents: 5349
diff changeset
245
33865
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
246 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
247 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
248 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
249 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
250 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
251 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
252
7203
8c129a567867 Added rmtree(), to recursively remove a directory tree.
Guido van Rossum <guido@python.org>
parents: 5349
diff changeset
253 """
33865
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
254 if ignore_errors:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
255 def onerror(*args):
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
256 pass
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
257 elif onerror is None:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
258 def onerror(*args):
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
259 raise
44828
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
260 try:
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
261 if os.path.islink(path):
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
262 # symlinks to directories are forbidden, see bug #1669
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
263 raise OSError("Cannot call rmtree on a symbolic link")
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
264 except OSError:
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
265 onerror(os.path.islink, path, sys.exc_info())
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
266 # can't continue even if onerror hook returns
ef7d72d98485 Merged revisions 60124-60142 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43020
diff changeset
267 return
33865
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
268 names = []
27361
891ec4d266d1 rmtree(): Make implementation agree with documentation (both latex and
Barry Warsaw <barry@python.org>
parents: 27096
diff changeset
269 try:
33865
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
270 names = os.listdir(path)
40587
6b18a095c2e7 SF patch 1631942 by Collin Winter:
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
271 except os.error as err:
33865
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
272 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
273 for name in names:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
274 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
275 try:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
276 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
277 except os.error:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
278 mode = 0
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
279 if stat.S_ISDIR(mode):
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
280 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
281 else:
33865
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
282 try:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
283 os.remove(fullname)
40587
6b18a095c2e7 SF patch 1631942 by Collin Winter:
Guido van Rossum <guido@python.org>
parents: 39442
diff changeset
284 except os.error as err:
33865
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
285 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
286 try:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
287 os.rmdir(path)
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
288 except os.error:
f196716ea0db Bug #1048941: shutil.rmtree error handling was always broken
Johannes Gijsbers <jlg@dds.nl>
parents: 33687
diff changeset
289 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
290
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
291
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
292 def _basename(path):
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
293 # A basename() variant which first strips the trailing slash, if present.
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
294 # Thus we always get the last component of the path, even for directories.
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
295 return os.path.basename(path.rstrip(os.path.sep))
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
296
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
297 def move(src, dst):
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
298 """Recursively move a file or directory to another location. This is
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
299 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
300
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
301 If the destination is a directory or a symlink to a directory, the source
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
302 is moved inside the directory. The destination path must not already
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
303 exist.
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
304
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
305 If the destination already exists but is not a directory, it may be
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
306 overwritten depending on os.rename() semantics.
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
307
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
308 If the destination is on our current filesystem, then rename() is used.
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
309 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
310 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
311 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
312
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
313 """
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
314 real_dst = dst
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
315 if os.path.isdir(dst):
69869
26da299ca88e Fix for issue 10684: Folders get deleted when trying to change case with shutil.move (case insensitive file systems only)
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61295
diff changeset
316 if _samefile(src, dst):
26da299ca88e Fix for issue 10684: Folders get deleted when trying to change case with shutil.move (case insensitive file systems only)
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61295
diff changeset
317 # We might be on a case insensitive filesystem,
26da299ca88e Fix for issue 10684: Folders get deleted when trying to change case with shutil.move (case insensitive file systems only)
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61295
diff changeset
318 # perform the rename anyway.
26da299ca88e Fix for issue 10684: Folders get deleted when trying to change case with shutil.move (case insensitive file systems only)
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61295
diff changeset
319 os.rename(src, dst)
26da299ca88e Fix for issue 10684: Folders get deleted when trying to change case with shutil.move (case insensitive file systems only)
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61295
diff changeset
320 return
26da299ca88e Fix for issue 10684: Folders get deleted when trying to change case with shutil.move (case insensitive file systems only)
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61295
diff changeset
321
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
322 real_dst = os.path.join(dst, _basename(src))
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
323 if os.path.exists(real_dst):
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
324 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
325 try:
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
326 os.rename(src, real_dst)
69869
26da299ca88e Fix for issue 10684: Folders get deleted when trying to change case with shutil.move (case insensitive file systems only)
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 61295
diff changeset
327 except OSError as exc:
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
328 if os.path.isdir(src):
51750
db8db31fdb4c Merged revisions 69415,69591,69593 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 51180
diff changeset
329 if _destinsrc(src, dst):
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 40893
diff changeset
330 raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst))
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
331 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
332 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
333 else:
45865
e0e8bef0d5ec Merged revisions 61520,61523-61528,61532 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44828
diff changeset
334 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
335 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
336
51750
db8db31fdb4c Merged revisions 69415,69591,69593 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 51180
diff changeset
337 def _destinsrc(src, dst):
51180
5d0eaeb4134d Merged revisions 69101 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48680
diff changeset
338 src = abspath(src)
5d0eaeb4134d Merged revisions 69101 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48680
diff changeset
339 dst = abspath(dst)
5d0eaeb4134d Merged revisions 69101 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48680
diff changeset
340 if not src.endswith(os.path.sep):
5d0eaeb4134d Merged revisions 69101 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48680
diff changeset
341 src += os.path.sep
5d0eaeb4134d Merged revisions 69101 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48680
diff changeset
342 if not dst.endswith(os.path.sep):
5d0eaeb4134d Merged revisions 69101 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48680
diff changeset
343 dst += os.path.sep
5d0eaeb4134d Merged revisions 69101 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48680
diff changeset
344 return dst.startswith(src)
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
345
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
346 def _get_gid(name):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
347 """Returns a gid, given a group name."""
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
348 if getgrnam is None or name is None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
349 return None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
350 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
351 result = getgrnam(name)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
352 except KeyError:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
353 result = None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
354 if result is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
355 return result[2]
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
356 return None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
357
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
358 def _get_uid(name):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
359 """Returns an uid, given a user name."""
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
360 if getpwnam is None or name is None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
361 return None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
362 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
363 result = getpwnam(name)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
364 except KeyError:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
365 result = None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
366 if result is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
367 return result[2]
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
368 return None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
369
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
370 def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
371 owner=None, group=None, logger=None):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
372 """Create a (possibly compressed) tar file from all the files under
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
373 'base_dir'.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
374
60789
bd45e0110990 Merged revisions 80282 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60770
diff changeset
375 'compress' must be "gzip" (the default), "bzip2", or None.
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
376
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
377 'owner' and 'group' can be used to define an owner and a group for the
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
378 archive that is being built. If not provided, the current owner and group
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
379 will be used.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
380
66932
2d2997f19e90 Fix wrong name in docstring and doc (#10693). Original patch by Eli Bendersky.
Éric Araujo <merwok@netwok.org>
parents: 61294
diff changeset
381 The output tar file will be named 'base_name' + ".tar", possibly plus
60789
bd45e0110990 Merged revisions 80282 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60770
diff changeset
382 the appropriate compression extension (".gz", or ".bz2").
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
383
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
384 Returns the output filename.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
385 """
61087
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
386 tar_compression = {'gzip': 'gz', None: ''}
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
387 compress_ext = {'gzip': '.gz'}
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
388
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
389 if _BZ2_SUPPORTED:
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
390 tar_compression['bzip2'] = 'bz2'
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
391 compress_ext['bzip2'] = '.bz2'
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
392
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
393 # flags for compression program, each element of list will be an argument
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
394 if compress is not None and compress not in compress_ext.keys():
61087
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
395 raise ValueError("bad value for 'compress', or compression format not "
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
396 "supported : {0}".format(compress))
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
397
60789
bd45e0110990 Merged revisions 80282 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60770
diff changeset
398 archive_name = base_name + '.tar' + compress_ext.get(compress, '')
bd45e0110990 Merged revisions 80282 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60770
diff changeset
399 archive_dir = os.path.dirname(archive_name)
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
400
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
401 if not os.path.exists(archive_dir):
67804
5f1ad65a1b84 Protect logging call against None argument (fixes #11045).
Éric Araujo <merwok@netwok.org>
parents: 66932
diff changeset
402 if logger is not None:
71934
fe3b346fb09c Make logging call lazy
Éric Araujo <merwok@netwok.org>
parents: 69870
diff changeset
403 logger.info("creating %s", archive_dir)
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
404 if not dry_run:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
405 os.makedirs(archive_dir)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
406
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
407 # creating the tarball
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
408 if logger is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
409 logger.info('Creating tar archive')
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
410
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
411 uid = _get_uid(owner)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
412 gid = _get_gid(group)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
413
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
414 def _set_uid_gid(tarinfo):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
415 if gid is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
416 tarinfo.gid = gid
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
417 tarinfo.gname = group
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
418 if uid is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
419 tarinfo.uid = uid
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
420 tarinfo.uname = owner
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
421 return tarinfo
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
422
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
423 if not dry_run:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
424 tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress])
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
425 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
426 tar.add(base_dir, filter=_set_uid_gid)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
427 finally:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
428 tar.close()
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
429
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
430 return archive_name
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
431
60810
c2905b0ef1d2 Merged revisions 80306 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60789
diff changeset
432 def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False):
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
433 # XXX see if we want to keep an external call here
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
434 if verbose:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
435 zipoptions = "-r"
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
436 else:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
437 zipoptions = "-rq"
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
438 from distutils.errors import DistutilsExecError
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
439 from distutils.spawn import spawn
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
440 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
441 spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
442 except DistutilsExecError:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
443 # XXX really should distinguish between "couldn't find
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
444 # external 'zip' command" and "zip failed".
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
445 raise ExecError("unable to create zip file '%s': "
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
446 "could neither import the 'zipfile' module nor "
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
447 "find a standalone zip utility") % zip_filename
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
448
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
449 def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
450 """Create a zip file from all the files under 'base_dir'.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
451
66932
2d2997f19e90 Fix wrong name in docstring and doc (#10693). Original patch by Eli Bendersky.
Éric Araujo <merwok@netwok.org>
parents: 61294
diff changeset
452 The output zip file will be named 'base_name' + ".zip". Uses either the
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
453 "zipfile" Python module (if available) or the InfoZIP "zip" utility
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
454 (if installed and found on the default search path). If neither tool is
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
455 available, raises ExecError. Returns the name of the output zip
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
456 file.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
457 """
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
458 zip_filename = base_name + ".zip"
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
459 archive_dir = os.path.dirname(base_name)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
460
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
461 if not os.path.exists(archive_dir):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
462 if logger is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
463 logger.info("creating %s", archive_dir)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
464 if not dry_run:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
465 os.makedirs(archive_dir)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
466
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
467 # If zipfile module is not available, try spawning an external 'zip'
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
468 # command.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
469 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
470 import zipfile
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
471 except ImportError:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
472 zipfile = None
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
473
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
474 if zipfile is None:
60810
c2905b0ef1d2 Merged revisions 80306 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60789
diff changeset
475 _call_external_zip(base_dir, zip_filename, verbose, dry_run)
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
476 else:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
477 if logger is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
478 logger.info("creating '%s' and adding '%s' to it",
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
479 zip_filename, base_dir)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
480
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
481 if not dry_run:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
482 zip = zipfile.ZipFile(zip_filename, "w",
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
483 compression=zipfile.ZIP_DEFLATED)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
484
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
485 for dirpath, dirnames, filenames in os.walk(base_dir):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
486 for name in filenames:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
487 path = os.path.normpath(os.path.join(dirpath, name))
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
488 if os.path.isfile(path):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
489 zip.write(path, path)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
490 if logger is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
491 logger.info("adding '%s'", path)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
492 zip.close()
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
493
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
494 return zip_filename
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
495
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
496 _ARCHIVE_FORMATS = {
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
497 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
498 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"),
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
499 'zip': (_make_zipfile, [],"ZIP file")
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
500 }
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
501
61087
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
502 if _BZ2_SUPPORTED:
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
503 _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')],
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
504 "bzip2'ed tar-file")
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
505
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
506 def get_archive_formats():
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
507 """Returns a list of supported formats for archiving and unarchiving.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
508
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
509 Each element of the returned sequence is a tuple (name, description)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
510 """
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
511 formats = [(name, registry[2]) for name, registry in
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
512 _ARCHIVE_FORMATS.items()]
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
513 formats.sort()
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
514 return formats
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
515
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
516 def register_archive_format(name, function, extra_args=None, description=''):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
517 """Registers an archive format.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
518
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
519 name is the name of the format. function is the callable that will be
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
520 used to create archives. If provided, extra_args is a sequence of
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
521 (name, value) tuples that will be passed as arguments to the callable.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
522 description can be provided to describe the format, and will be returned
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
523 by the get_archive_formats() function.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
524 """
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
525 if extra_args is None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
526 extra_args = []
73165
8e57b5d8f58f Closes #13258: Use callable() built-in in the standard library.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 72265
diff changeset
527 if not callable(function):
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
528 raise TypeError('The %s object is not callable' % function)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
529 if not isinstance(extra_args, (tuple, list)):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
530 raise TypeError('extra_args needs to be a sequence')
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
531 for element in extra_args:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
532 if not isinstance(element, (tuple, list)) or len(element) !=2 :
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
533 raise TypeError('extra_args elements are : (arg_name, value)')
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
534
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
535 _ARCHIVE_FORMATS[name] = (function, extra_args, description)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
536
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
537 def unregister_archive_format(name):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
538 del _ARCHIVE_FORMATS[name]
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
539
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
540 def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
541 dry_run=0, owner=None, group=None, logger=None):
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
542 """Create an archive file (eg. zip or tar).
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
543
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
544 'base_name' is the name of the file to create, minus any format-specific
60789
bd45e0110990 Merged revisions 80282 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60770
diff changeset
545 extension; 'format' is the archive format: one of "zip", "tar", "bztar"
bd45e0110990 Merged revisions 80282 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60770
diff changeset
546 or "gztar".
59056
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
547
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
548 'root_dir' is a directory that will be the root directory of the
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
549 archive; ie. we typically chdir into 'root_dir' before creating the
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
550 archive. 'base_dir' is the directory where we start archiving from;
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
551 ie. 'base_dir' will be the common prefix of all files and
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
552 directories in the archive. 'root_dir' and 'base_dir' both default
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
553 to the current directory. Returns the name of the archive file.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
554
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
555 'owner' and 'group' are used when creating a tar archive. By default,
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
556 uses the current owner and group.
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
557 """
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
558 save_cwd = os.getcwd()
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
559 if root_dir is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
560 if logger is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
561 logger.debug("changing into '%s'", root_dir)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
562 base_name = os.path.abspath(base_name)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
563 if not dry_run:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
564 os.chdir(root_dir)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
565
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
566 if base_dir is None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
567 base_dir = os.curdir
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
568
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
569 kwargs = {'dry_run': dry_run, 'logger': logger}
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
570
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
571 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
572 format_info = _ARCHIVE_FORMATS[format]
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
573 except KeyError:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
574 raise ValueError("unknown archive format '%s'" % format)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
575
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
576 func = format_info[0]
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
577 for arg, val in format_info[1]:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
578 kwargs[arg] = val
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
579
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
580 if format != 'zip':
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
581 kwargs['owner'] = owner
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
582 kwargs['group'] = group
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
583
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
584 try:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
585 filename = func(base_name, base_dir, **kwargs)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
586 finally:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
587 if root_dir is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
588 if logger is not None:
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
589 logger.debug("changing back to '%s'", save_cwd)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
590 os.chdir(save_cwd)
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
591
a1d078b88247 Merged revisions 78359-78360 via svnmerge from
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 54594
diff changeset
592 return filename
61062
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
593
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
594
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
595 def get_unpack_formats():
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
596 """Returns a list of supported formats for unpacking.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
597
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
598 Each element of the returned sequence is a tuple
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
599 (name, extensions, description)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
600 """
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
601 formats = [(name, info[0], info[3]) for name, info in
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
602 _UNPACK_FORMATS.items()]
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
603 formats.sort()
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
604 return formats
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
605
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
606 def _check_unpack_options(extensions, function, extra_args):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
607 """Checks what gets registered as an unpacker."""
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
608 # first make sure no other unpacker is registered for this extension
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
609 existing_extensions = {}
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
610 for name, info in _UNPACK_FORMATS.items():
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
611 for ext in info[0]:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
612 existing_extensions[ext] = name
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
613
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
614 for extension in extensions:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
615 if extension in existing_extensions:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
616 msg = '%s is already registered for "%s"'
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
617 raise RegistryError(msg % (extension,
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
618 existing_extensions[extension]))
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
619
73165
8e57b5d8f58f Closes #13258: Use callable() built-in in the standard library.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 72265
diff changeset
620 if not callable(function):
61062
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
621 raise TypeError('The registered function must be a callable')
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
622
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
623
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
624 def register_unpack_format(name, extensions, function, extra_args=None,
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
625 description=''):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
626 """Registers an unpack format.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
627
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
628 `name` is the name of the format. `extensions` is a list of extensions
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
629 corresponding to the format.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
630
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
631 `function` is the callable that will be
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
632 used to unpack archives. The callable will receive archives to unpack.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
633 If it's unable to handle an archive, it needs to raise a ReadError
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
634 exception.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
635
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
636 If provided, `extra_args` is a sequence of
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
637 (name, value) tuples that will be passed as arguments to the callable.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
638 description can be provided to describe the format, and will be returned
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
639 by the get_unpack_formats() function.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
640 """
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
641 if extra_args is None:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
642 extra_args = []
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
643 _check_unpack_options(extensions, function, extra_args)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
644 _UNPACK_FORMATS[name] = extensions, function, extra_args, description
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
645
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
646 def unregister_unpack_format(name):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
647 """Removes the pack format from the registery."""
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
648 del _UNPACK_FORMATS[name]
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
649
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
650 def _ensure_directory(path):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
651 """Ensure that the parent directory of `path` exists"""
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
652 dirname = os.path.dirname(path)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
653 if not os.path.isdir(dirname):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
654 os.makedirs(dirname)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
655
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
656 def _unpack_zipfile(filename, extract_dir):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
657 """Unpack zip `filename` to `extract_dir`
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
658 """
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
659 try:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
660 import zipfile
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
661 except ImportError:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
662 raise ReadError('zlib not supported, cannot unpack this archive.')
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
663
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
664 if not zipfile.is_zipfile(filename):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
665 raise ReadError("%s is not a zip file" % filename)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
666
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
667 zip = zipfile.ZipFile(filename)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
668 try:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
669 for info in zip.infolist():
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
670 name = info.filename
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
671
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
672 # don't extract absolute paths or ones with .. in them
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
673 if name.startswith('/') or '..' in name:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
674 continue
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
675
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
676 target = os.path.join(extract_dir, *name.split('/'))
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
677 if not target:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
678 continue
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
679
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
680 _ensure_directory(target)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
681 if not name.endswith('/'):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
682 # file
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
683 data = zip.read(info.filename)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
684 f = open(target,'wb')
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
685 try:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
686 f.write(data)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
687 finally:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
688 f.close()
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
689 del data
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
690 finally:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
691 zip.close()
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
692
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
693 def _unpack_tarfile(filename, extract_dir):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
694 """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir`
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
695 """
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
696 try:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
697 tarobj = tarfile.open(filename)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
698 except tarfile.TarError:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
699 raise ReadError(
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
700 "%s is not a compressed or uncompressed tar file" % filename)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
701 try:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
702 tarobj.extractall(extract_dir)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
703 finally:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
704 tarobj.close()
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
705
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
706 _UNPACK_FORMATS = {
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
707 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"),
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
708 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"),
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
709 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file")
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
710 }
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
711
61087
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
712 if _BZ2_SUPPORTED:
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
713 _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [],
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
714 "bzip2'ed tar-file")
4b57019150a8 make sure shutil checks for bz2 availability before it uses it.
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 61062
diff changeset
715
61062
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
716 def _find_unpack_format(filename):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
717 for name, info in _UNPACK_FORMATS.items():
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
718 for extension in info[0]:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
719 if filename.endswith(extension):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
720 return name
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
721 return None
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
722
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
723 def unpack_archive(filename, extract_dir=None, format=None):
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
724 """Unpack an archive.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
725
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
726 `filename` is the name of the archive.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
727
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
728 `extract_dir` is the name of the target directory, where the archive
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
729 is unpacked. If not provided, the current working directory is used.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
730
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
731 `format` is the archive format: one of "zip", "tar", or "gztar". Or any
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
732 other registered format. If not provided, unpack_archive will use the
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
733 filename extension and see if an unpacker was registered for that
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
734 extension.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
735
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
736 In case none is found, a ValueError is raised.
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
737 """
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
738 if extract_dir is None:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
739 extract_dir = os.getcwd()
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
740
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
741 if format is not None:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
742 try:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
743 format_info = _UNPACK_FORMATS[format]
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
744 except KeyError:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
745 raise ValueError("Unknown unpack format '{0}'".format(format))
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
746
68601
d1619747c17d Close #11548: Correctly handle format argument in shutil.unpack_archive
Nick Coghlan <ncoghlan@gmail.com>
parents: 68257
diff changeset
747 func = format_info[1]
d1619747c17d Close #11548: Correctly handle format argument in shutil.unpack_archive
Nick Coghlan <ncoghlan@gmail.com>
parents: 68257
diff changeset
748 func(filename, extract_dir, **dict(format_info[2]))
61062
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
749 else:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
750 # we need to look at the registered unpackers supported extensions
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
751 format = _find_unpack_format(filename)
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
752 if format is None:
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
753 raise ReadError("Unknown archive format '{0}'".format(filename))
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
754
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
755 func = _UNPACK_FORMATS[format][1]
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
756 kwargs = dict(_UNPACK_FORMATS[format][2])
a43776553ab5 #8295 : Added shutil.unpack_archive and related APIs
Tarek Ziadé <ziade.tarek@gmail.com>
parents: 60892
diff changeset
757 func(filename, extract_dir, **kwargs)