cpython: eb02db65e148 (original) (raw)
Mercurial > cpython
changeset 105677:eb02db65e148 2.7
Issue #14061: Misc fixes and cleanups in archiving code in shutil. Improved the documentation and tests for make_archive(). Improved error handling when corresponding compress module is not available. External zip executable is now used if the zlib module is not available. [#14061]
Serhiy Storchaka storchaka@gmail.com | |
---|---|
date | Fri, 16 Dec 2016 19:04:17 +0200 |
parents | eb830f1511ef |
children | 6daa88e02392 287d4290b1b4 |
files | Doc/library/shutil.rst Lib/shutil.py Lib/test/test_shutil.py |
diffstat | 3 files changed, 49 insertions(+), 23 deletions(-)[+] [-] Doc/library/shutil.rst 13 Lib/shutil.py 54 Lib/test/test_shutil.py 5 |
line wrap: on
line diff
--- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -267,7 +267,9 @@ provided. They rely on the :mod:`zipfil base_name is the name of the file to create, including the path, minus any format-specific extension. format is the archive format: one of
- "zip" (if the :mod:
zlib
module or externalzip
executable is - available), "tar", "gztar" (if the :mod:
zlib
module is available), or - "bztar" (if the :mod:
bz2
module is available). root_dir is a directory that will be the root directory of the archive; ie. we typically chdir into root_dir before creating the @@ -295,10 +297,11 @@ provided. They rely on the :mod:zipfil[](#l1.14) [](#l1.15) By default :mod:
shutil` provides these formats:
executable is available).[](#l1.23)
--- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -13,6 +13,20 @@ import collections import errno try:
+ +try: from pwd import getpwnam except ImportError: getpwnam = None @@ -351,15 +365,18 @@ def _make_tarball(base_name, base_dir, c Returns the output filename. """
- tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: ''}
- compress_ext = {'gzip': '.gz', 'bzip2': '.bz2'}
- if compress is None:
tar_compression = ''[](#l2.31)
- elif _ZLIB_SUPPORTED and compress == 'gzip':
tar_compression = 'gz'[](#l2.33)
- elif _BZ2_SUPPORTED and compress == 'bzip2':
tar_compression = 'bz2'[](#l2.35)
- else:
raise ValueError("bad value for 'compress', or compression format not "[](#l2.37)
"supported : {0}".format(compress))[](#l2.38)
flags for compression program, each element of list will be an argument
- if compress is not None and compress not in compress_ext.keys():
raise ValueError, \[](#l2.42)
("bad value for 'compress': must be None, 'gzip' or 'bzip2'")[](#l2.43)
- compress_ext = '.' + tar_compression if compress else ''
- archive_name = base_name + '.tar' + compress_ext archive_dir = os.path.dirname(archive_name) if archive_dir and not os.path.exists(archive_dir): @@ -388,7 +405,7 @@ def _make_tarball(base_name, base_dir, c return tarinfo
tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress])[](#l2.55)
tar = tarfile.open(archive_name, 'w|%s' % tar_compression)[](#l2.56) try:[](#l2.57) tar.add(base_dir, filter=_set_uid_gid)[](#l2.58) finally:[](#l2.59)
@@ -435,6 +452,7 @@ def _make_zipfile(base_name, base_dir, v # If zipfile module is not available, try spawning an external 'zip' # command. try:
@@ -470,11 +488,17 @@ def _make_zipfile(base_name, base_dir, v return zip_filename _ARCHIVE_FORMATS = {
- 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
- 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"),
- 'zip': (_make_zipfile, [],"ZIP file")
- }
def get_archive_formats(): """Returns a list of supported formats for archiving and unarchiving. @@ -515,8 +539,8 @@ def make_archive(base_name, format, root """Create an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific
- extension; 'format' is the archive format: one of "zip", "tar", "gztar",
- or "bztar". Or any other registered format.
'root_dir' is a directory that will be the root directory of the archive; ie. we typically chdir into 'root_dir' before creating the
--- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -35,6 +35,7 @@ except ImportError: try: import zipfile
- import zlib ZIP_SUPPORT = True except ImportError: ZIP_SUPPORT = find_executable('zip') @@ -460,7 +461,6 @@ class TestShutil(unittest.TestCase): self.assertEqual(tarball, base_name + '.tar') self.assertTrue(os.path.isfile(tarball))
- @unittest.skipUnless(zlib, "Requires zlib") @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') def test_make_zipfile(self): # creating something to zip
@@ -485,6 +485,7 @@ class TestShutil(unittest.TestCase): ['dist/', 'dist/file1', 'dist/file2', 'dist/sub/', 'dist/sub/file3', 'dist/sub2/', 'outer'])
support.unlink(res)[](#l3.23)
with support.change_cwd(work_dir): base_name = os.path.abspath(rel_base_name) @@ -498,7 +499,6 @@ class TestShutil(unittest.TestCase): ['dist/', 'dist/file1', 'dist/file2', 'dist/sub/', 'dist/sub/file3', 'dist/sub2/'])
- @unittest.skipUnless(zlib, "Requires zlib") @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') @unittest.skipUnless(find_executable('zip'), 'Need the zip command to run')
@@ -524,7 +524,6 @@ class TestShutil(unittest.TestCase): names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2))