Kaydet (Commit) 1121377c authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

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

üst af78ef18
...@@ -469,7 +469,8 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. ...@@ -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 *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 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 *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 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. ...@@ -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 *logger* must be an object compatible with :pep:`282`, usually an instance of
:class:`logging.Logger`. :class:`logging.Logger`.
.. versionchanged:: 3.4
Added support for the *xztar* format.
.. function:: get_archive_formats() .. function:: get_archive_formats()
...@@ -497,6 +501,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. ...@@ -497,6 +501,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
- *gztar*: gzip'ed tar-file - *gztar*: gzip'ed tar-file
- *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.) - *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 - *tar*: uncompressed tar file
- *zip*: ZIP file - *zip*: ZIP file
...@@ -567,6 +572,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. ...@@ -567,6 +572,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
- *gztar*: gzip'ed tar-file - *gztar*: gzip'ed tar-file
- *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.) - *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 - *tar*: uncompressed tar file
- *zip*: ZIP file - *zip*: ZIP file
......
...@@ -20,6 +20,13 @@ try: ...@@ -20,6 +20,13 @@ try:
except ImportError: except ImportError:
_BZ2_SUPPORTED = False _BZ2_SUPPORTED = False
try:
import lzma
del lzma
_LZMA_SUPPORTED = True
except ImportError:
_LZMA_SUPPORTED = False
try: try:
from pwd import getpwnam from pwd import getpwnam
except ImportError: except ImportError:
...@@ -580,14 +587,14 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, ...@@ -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 """Create a (possibly compressed) tar file from all the files under
'base_dir'. '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 '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 archive that is being built. If not provided, the current owner and group
will be used. will be used.
The output tar file will be named 'base_name' + ".tar", possibly plus 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. Returns the output filename.
""" """
...@@ -598,6 +605,10 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, ...@@ -598,6 +605,10 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
tar_compression['bzip2'] = 'bz2' tar_compression['bzip2'] = 'bz2'
compress_ext['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 # flags for compression program, each element of list will be an argument
if compress is not None and compress not in compress_ext: if compress is not None and compress not in compress_ext:
raise ValueError("bad value for 'compress', or compression format not " raise ValueError("bad value for 'compress', or compression format not "
...@@ -684,6 +695,10 @@ if _BZ2_SUPPORTED: ...@@ -684,6 +695,10 @@ if _BZ2_SUPPORTED:
_ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')],
"bzip2'ed tar-file") "bzip2'ed tar-file")
if _LZMA_SUPPORTED:
_ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')],
"xz'ed tar-file")
def get_archive_formats(): def get_archive_formats():
"""Returns a list of supported formats for archiving and unarchiving. """Returns a list of supported formats for archiving and unarchiving.
...@@ -872,7 +887,7 @@ def _unpack_zipfile(filename, extract_dir): ...@@ -872,7 +887,7 @@ def _unpack_zipfile(filename, extract_dir):
zip.close() zip.close()
def _unpack_tarfile(filename, extract_dir): 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: try:
tarobj = tarfile.open(filename) tarobj = tarfile.open(filename)
...@@ -891,9 +906,13 @@ _UNPACK_FORMATS = { ...@@ -891,9 +906,13 @@ _UNPACK_FORMATS = {
} }
if _BZ2_SUPPORTED: if _BZ2_SUPPORTED:
_UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], _UNPACK_FORMATS['bztar'] = (['.tar.bz2', '.tbz2'], _unpack_tarfile, [],
"bzip2'ed tar-file") "bzip2'ed tar-file")
if _LZMA_SUPPORTED:
_UNPACK_FORMATS['xztar'] = (['.tar.xz', '.txz'], _unpack_tarfile, [],
"xz'ed tar-file")
def _find_unpack_format(filename): def _find_unpack_format(filename):
for name, info in _UNPACK_FORMATS.items(): for name, info in _UNPACK_FORMATS.items():
for extension in info[0]: for extension in info[0]:
......
...@@ -32,6 +32,12 @@ try: ...@@ -32,6 +32,12 @@ try:
except ImportError: except ImportError:
BZ2_SUPPORTED = False BZ2_SUPPORTED = False
try:
import lzma
LZMA_SUPPORTED = True
except ImportError:
LZMA_SUPPORTED = False
TESTFN2 = TESTFN + "2" TESTFN2 = TESTFN + "2"
try: try:
...@@ -1156,6 +1162,8 @@ class TestShutil(unittest.TestCase): ...@@ -1156,6 +1162,8 @@ class TestShutil(unittest.TestCase):
formats = ['tar', 'gztar', 'zip'] formats = ['tar', 'gztar', 'zip']
if BZ2_SUPPORTED: if BZ2_SUPPORTED:
formats.append('bztar') formats.append('bztar')
if LZMA_SUPPORTED:
formats.append('xztar')
for format in formats: for format in formats:
tmpdir = self.mkdtemp() tmpdir = self.mkdtemp()
......
...@@ -112,6 +112,8 @@ Core and Builtins ...@@ -112,6 +112,8 @@ Core and Builtins
Library Library
------- -------
- Issue #5411: Added support for the "xztar" format in the shutil module.
- Issue #21975: Fixed crash when using uninitialized sqlite3.Row (in particular - Issue #21975: Fixed crash when using uninitialized sqlite3.Row (in particular
when unpickling pickled sqlite3.Row). sqlite3.Row is now initialized in the when unpickling pickled sqlite3.Row). sqlite3.Row is now initialized in the
__new__() method. __new__() method.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment