diff --git a/Lib/shutil.py b/Lib/shutil.py --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -21,6 +21,13 @@ except ImportError: _BZ2_SUPPORTED = False try: + import lzma + del lzma + _XZ_SUPPORTED = True +except ImportError: + _XZ_SUPPORTED = False + +try: from pwd import getpwnam except ImportError: getpwnam = None @@ -436,17 +443,24 @@ def _make_tarball(base_name, base_dir, c 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. """ tar_compression = {'gzip': 'gz', None: ''} compress_ext = {'gzip': '.gz'} + # XXX would be nice to stop having three lists of hard-coded values in this + # module and instead pass arguments to tarfile and let it work or complain + if _BZ2_SUPPORTED: tar_compression['bzip2'] = 'bz2' compress_ext['bzip2'] = '.bz2' + if _XZ_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 " @@ -560,6 +574,10 @@ if _BZ2_SUPPORTED: _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file") +if _XZ_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. @@ -770,6 +788,10 @@ if _BZ2_SUPPORTED: _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], "bzip2'ed tar-file") +if _XZ_SUPPORTED: + _UNPACK_FORMATS['xztar'] = (['.xz'], _unpack_tarfile, [], + "xz'ed tar-file") + def _find_unpack_format(filename): for name, info in _UNPACK_FORMATS.items(): for extension in info[0]: diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -30,6 +30,12 @@ try: except ImportError: BZ2_SUPPORTED = False +try: + import lzma + XZ_SUPPORTED = True +except ImportError: + XZ_SUPPORTED = False + TESTFN2 = TESTFN + "2" try: @@ -876,6 +882,8 @@ class TestShutil(unittest.TestCase): formats = ['tar', 'gztar', 'zip'] if BZ2_SUPPORTED: formats.append('bztar') + if XZ_SUPPORTED: + formats.append('xztar') for format in formats: tmpdir = self.mkdtemp()