Issue #5411: Added support for the "xztar" format in the shutil module.

This commit is contained in:
Serhiy Storchaka 2014-08-06 18:50:19 +03:00
parent af78ef1824
commit 1121377cdb
4 changed files with 40 additions and 5 deletions

View File

@ -469,7 +469,8 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
*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", "tar", "bztar" (if the :mod:`bz2` module is available) or "gztar".
"zip", "tar", "bztar" (if the :mod:`bz2` module is available), "xztar"
(if the :mod:`lzma` module is available) or "gztar".
*root_dir* is a directory that will be the root directory of the
archive; for example, we typically chdir into *root_dir* before creating the
@ -487,6 +488,9 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
*logger* must be an object compatible with :pep:`282`, usually an instance of
:class:`logging.Logger`.
.. versionchanged:: 3.4
Added support for the *xztar* format.
.. function:: get_archive_formats()
@ -497,6 +501,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
- *gztar*: gzip'ed tar-file
- *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.)
- *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available.)
- *tar*: uncompressed tar file
- *zip*: ZIP file
@ -567,6 +572,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
- *gztar*: gzip'ed tar-file
- *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.)
- *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available.)
- *tar*: uncompressed tar file
- *zip*: ZIP file

View File

@ -20,6 +20,13 @@ try:
except ImportError:
_BZ2_SUPPORTED = False
try:
import lzma
del lzma
_LZMA_SUPPORTED = True
except ImportError:
_LZMA_SUPPORTED = False
try:
from pwd import getpwnam
except ImportError:
@ -580,14 +587,14 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
"""Create a (possibly compressed) tar file from all the files under
'base_dir'.
'compress' must be "gzip" (the default), "bzip2", or None.
'compress' must be "gzip" (the default), "bzip2", "xz", or None.
'owner' and 'group' can be used to define an owner and a group for the
archive that is being built. If not provided, the current owner and group
will be used.
The output tar file will be named 'base_name' + ".tar", possibly plus
the appropriate compression extension (".gz", or ".bz2").
the appropriate compression extension (".gz", ".bz2", or ".xz").
Returns the output filename.
"""
@ -598,6 +605,10 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
tar_compression['bzip2'] = 'bz2'
compress_ext['bzip2'] = '.bz2'
if _LZMA_SUPPORTED:
tar_compression['xz'] = 'xz'
compress_ext['xz'] = '.xz'
# flags for compression program, each element of list will be an argument
if compress is not None and compress not in compress_ext:
raise ValueError("bad value for 'compress', or compression format not "
@ -684,6 +695,10 @@ if _BZ2_SUPPORTED:
_ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')],
"bzip2'ed tar-file")
if _LZMA_SUPPORTED:
_ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')],
"xz'ed tar-file")
def get_archive_formats():
"""Returns a list of supported formats for archiving and unarchiving.
@ -872,7 +887,7 @@ def _unpack_zipfile(filename, extract_dir):
zip.close()
def _unpack_tarfile(filename, extract_dir):
"""Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir`
"""Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir`
"""
try:
tarobj = tarfile.open(filename)
@ -891,9 +906,13 @@ _UNPACK_FORMATS = {
}
if _BZ2_SUPPORTED:
_UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [],
_UNPACK_FORMATS['bztar'] = (['.tar.bz2', '.tbz2'], _unpack_tarfile, [],
"bzip2'ed tar-file")
if _LZMA_SUPPORTED:
_UNPACK_FORMATS['xztar'] = (['.tar.xz', '.txz'], _unpack_tarfile, [],
"xz'ed tar-file")
def _find_unpack_format(filename):
for name, info in _UNPACK_FORMATS.items():
for extension in info[0]:

View File

@ -32,6 +32,12 @@ try:
except ImportError:
BZ2_SUPPORTED = False
try:
import lzma
LZMA_SUPPORTED = True
except ImportError:
LZMA_SUPPORTED = False
TESTFN2 = TESTFN + "2"
try:
@ -1156,6 +1162,8 @@ class TestShutil(unittest.TestCase):
formats = ['tar', 'gztar', 'zip']
if BZ2_SUPPORTED:
formats.append('bztar')
if LZMA_SUPPORTED:
formats.append('xztar')
for format in formats:
tmpdir = self.mkdtemp()

View File

@ -112,6 +112,8 @@ Core and Builtins
Library
-------
- Issue #5411: Added support for the "xztar" format in the shutil module.
- Issue #21975: Fixed crash when using uninitialized sqlite3.Row (in particular
when unpickling pickled sqlite3.Row). sqlite3.Row is now initialized in the
__new__() method.