[Python-checkins] cpython: Issue #16314: Added support for the LZMA compression in distutils.

serhiy.storchaka python-checkins at python.org
Sat May 16 21:13:47 CEST 2015


https://hg.python.org/cpython/rev/09bd552999bf
changeset:   96102:09bd552999bf
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sat May 16 22:13:27 2015 +0300
summary:
  Issue #16314: Added support for the LZMA compression in distutils.

files:
  Doc/distutils/apiref.rst                 |   32 +-
  Doc/distutils/builtdist.rst              |   45 +-
  Doc/distutils/sourcedist.rst             |    8 +-
  Doc/whatsnew/3.5.rst                     |    3 +
  Lib/distutils/archive_util.py            |   21 +-
  Lib/distutils/command/bdist.py           |    3 +-
  Lib/distutils/command/bdist_dumb.py      |    3 +-
  Lib/distutils/tests/test_archive_util.py |  154 +++++++---
  Lib/distutils/tests/test_bdist.py        |    2 +-
  Misc/NEWS                                |    2 +
  10 files changed, 180 insertions(+), 93 deletions(-)


diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -868,23 +868,31 @@
 
    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``,  ``ztar``, or ``gztar``. *root_dir* is
-   a directory that will be the root directory of the archive; ie. we typically
-   ``chdir`` into *root_dir* before  creating the archive.  *base_dir* is the
-   directory where we start  archiving from; ie. *base_dir* will be the common
-   prefix of all files and directories in the archive.  *root_dir* and *base_dir*
-   both default to the current directory.  Returns the name of the archive file.
+   archive format: one of ``zip``, ``tar``, ``gztar``, ``bztar``, ``xztar``, or
+   ``ztar``. *root_dir* is a directory that will be the root directory of the
+   archive; ie. we typically ``chdir`` into *root_dir* before  creating the
+   archive.  *base_dir* is the directory where we start  archiving from; ie.
+   *base_dir* will be the common prefix of all files and directories in the
+   archive.  *root_dir* and *base_dir* both default to the current directory.
+   Returns the name of the archive file.
+
+   .. versionchanged: 3.5
+      Added support for the ``xztar`` format.
 
 
 .. function:: make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0])
 
    'Create an (optional compressed) archive as a tar file from all files in and
-   under *base_dir*. *compress* must be ``'gzip'`` (the default),  ``'compress'``,
-   ``'bzip2'``, or ``None``.  Both :program:`tar` and the compression utility named
-   by *compress* must be on the  default program search path, so this is probably
-   Unix-specific.  The  output tar file will be named :file:`base_dir.tar`,
-   possibly plus the appropriate compression extension (:file:`.gz`, :file:`.bz2`
-   or :file:`.Z`).  Return the output filename.
+   under *base_dir*. *compress* must be ``'gzip'`` (the default),
+   ``'bzip2'``, ``'xz'``, ``'compress'``, or ``None``.  For the ``'compress'``
+   method the compression utility named by :program:`compress` must be on the
+   default program search path, so this is probably Unix-specific.  The output
+   tar file will be named :file:`base_dir.tar`, possibly plus the appropriate
+   compression extension (``.gz``, ``.bz2``, ``.xz`` or ``.Z``).  Return the
+   output filename.
+
+   .. versionchanged: 3.5
+      Added support for the ``xz`` compression.
 
 
 .. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0])
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
--- a/Doc/distutils/builtdist.rst
+++ b/Doc/distutils/builtdist.rst
@@ -72,13 +72,19 @@
 +-------------+------------------------------+---------+
 | Format      | Description                  | Notes   |
 +=============+==============================+=========+
-| ``gztar``   | gzipped tar file             | (1),(3) |
+| ``gztar``   | gzipped tar file             | \(1)    |
 |             | (:file:`.tar.gz`)            |         |
 +-------------+------------------------------+---------+
+| ``bztar``   | bzipped tar file             |         |
+|             | (:file:`.tar.bz2`)           |         |
++-------------+------------------------------+---------+
+| ``xztar``   | xzipped tar file             |         |
+|             | (:file:`.tar.xz`)            |         |
++-------------+------------------------------+---------+
 | ``ztar``    | compressed tar file          | \(3)    |
 |             | (:file:`.tar.Z`)             |         |
 +-------------+------------------------------+---------+
-| ``tar``     | tar file (:file:`.tar`)      | \(3)    |
+| ``tar``     | tar file (:file:`.tar`)      |         |
 +-------------+------------------------------+---------+
 | ``zip``     | zip file (:file:`.zip`)      | (2),(4) |
 +-------------+------------------------------+---------+
@@ -94,6 +100,9 @@
 | ``msi``     | Microsoft Installer.         |         |
 +-------------+------------------------------+---------+
 
+.. versionchanged: 3.5
+   Added support for the ``xztar`` format.
+
 
 Notes:
 
@@ -104,8 +113,7 @@
    default on Windows
 
 (3)
-   requires external utilities: :program:`tar` and possibly one of :program:`gzip`,
-   :program:`bzip2`, or :program:`compress`
+   requires external :program:`compress` utility.
 
 (4)
    requires either external :program:`zip` utility or :mod:`zipfile` module (part
@@ -119,21 +127,22 @@
 option; you can also use the command that directly implements the format you're
 interested in.  Some of these :command:`bdist` "sub-commands" actually generate
 several similar formats; for instance, the :command:`bdist_dumb` command
-generates all the "dumb" archive formats (``tar``, ``ztar``, ``gztar``, and
-``zip``), and :command:`bdist_rpm` generates both binary and source RPMs.  The
-:command:`bdist` sub-commands, and the formats generated by each, are:
+generates all the "dumb" archive formats (``tar``, ``gztar``, ``bztar``,
+``xztar``, ``ztar``, and ``zip``), and :command:`bdist_rpm` generates both
+binary and source RPMs.  The :command:`bdist` sub-commands, and the formats
+generated by each, are:
 
-+--------------------------+-----------------------+
-| Command                  | Formats               |
-+==========================+=======================+
-| :command:`bdist_dumb`    | tar, ztar, gztar, zip |
-+--------------------------+-----------------------+
-| :command:`bdist_rpm`     | rpm, srpm             |
-+--------------------------+-----------------------+
-| :command:`bdist_wininst` | wininst               |
-+--------------------------+-----------------------+
-| :command:`bdist_msi`     | msi                   |
-+--------------------------+-----------------------+
++--------------------------+-------------------------------------+
+| Command                  | Formats                             |
++==========================+=====================================+
+| :command:`bdist_dumb`    | tar, gztar, bztar, xztar, ztar, zip |
++--------------------------+-------------------------------------+
+| :command:`bdist_rpm`     | rpm, srpm                           |
++--------------------------+-------------------------------------+
+| :command:`bdist_wininst` | wininst                             |
++--------------------------+-------------------------------------+
+| :command:`bdist_msi`     | msi                                 |
++--------------------------+-------------------------------------+
 
 The following sections give details on the individual :command:`bdist_\*`
 commands.
diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst
--- a/Doc/distutils/sourcedist.rst
+++ b/Doc/distutils/sourcedist.rst
@@ -32,12 +32,18 @@
 | ``bztar`` | bzip2'ed tar file       |         |
 |           | (:file:`.tar.bz2`)      |         |
 +-----------+-------------------------+---------+
+| ``xztar`` | xz'ed tar file          |         |
+|           | (:file:`.tar.xz`)       |         |
++-----------+-------------------------+---------+
 | ``ztar``  | compressed tar file     | \(4)    |
 |           | (:file:`.tar.Z`)        |         |
 +-----------+-------------------------+---------+
 | ``tar``   | tar file (:file:`.tar`) |         |
 +-----------+-------------------------+---------+
 
+.. versionchanged: 3.5
+   Added support for the ``xztar`` format.
+
 Notes:
 
 (1)
@@ -54,7 +60,7 @@
    requires the :program:`compress` program. Notice that this format is now
    pending for deprecation and will be removed in the future versions of Python.
 
-When using any ``tar`` format (``gztar``, ``bztar``, ``ztar`` or
+When using any ``tar`` format (``gztar``, ``bztar``, ``xztar``, ``ztar`` or
 ``tar``), under Unix you can specify the ``owner`` and ``group`` names
 that will be set for each member of the archive.
 
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -338,6 +338,9 @@
   option to enable parallel building of extension modules.
   (Contributed by Antoine Pitrou in :issue:`5309`.)
 
+* Added support for the LZMA compression.
+  (Contributed by Serhiy Storchaka in :issue:`16314`.)
+
 doctest
 -------
 
diff --git a/Lib/distutils/archive_util.py b/Lib/distutils/archive_util.py
--- a/Lib/distutils/archive_util.py
+++ b/Lib/distutils/archive_util.py
@@ -57,26 +57,28 @@
     """Create a (possibly compressed) tar file from all the files under
     'base_dir'.
 
-    'compress' must be "gzip" (the default), "compress", "bzip2", or None.
-    (compress will be deprecated in Python 3.2)
+    'compress' must be "gzip" (the default), "bzip2", "xz", "compress", or
+    None.  ("compress" will be deprecated in Python 3.2)
 
     '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_dir' +  ".tar", possibly plus
-    the appropriate compression extension (".gz", ".bz2" or ".Z").
+    the appropriate compression extension (".gz", ".bz2", ".xz" or ".Z").
 
     Returns the output filename.
     """
-    tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: '', 'compress': ''}
-    compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'compress': '.Z'}
+    tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', 'xz': 'xz', None: '',
+                       'compress': ''}
+    compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'xz': '.xz',
+                    'compress': '.Z'}
 
     # 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(
-              "bad value for 'compress': must be None, 'gzip', 'bzip2' "
-              "or 'compress'")
+              "bad value for 'compress': must be None, 'gzip', 'bzip2', "
+              "'xz' or 'compress'")
 
     archive_name = base_name + '.tar'
     if compress != 'compress':
@@ -177,6 +179,7 @@
 ARCHIVE_FORMATS = {
     'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
     'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"),
+    'xztar': (make_tarball, [('compress', 'xz')], "xz'ed tar-file"),
     'ztar':  (make_tarball, [('compress', 'compress')], "compressed tar file"),
     'tar':   (make_tarball, [('compress', None)], "uncompressed tar file"),
     'zip':   (make_zipfile, [],"ZIP file")
@@ -197,8 +200,8 @@
     """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", "ztar",
-    or "gztar".
+    extension; 'format' is the archive format: one of "zip", "tar", "gztar",
+    "bztar", "xztar", or "ztar".
 
     'root_dir' is a directory that will be the root directory of the
     archive; ie. we typically chdir into 'root_dir' before creating the
diff --git a/Lib/distutils/command/bdist.py b/Lib/distutils/command/bdist.py
--- a/Lib/distutils/command/bdist.py
+++ b/Lib/distutils/command/bdist.py
@@ -61,13 +61,14 @@
                       'nt': 'zip'}
 
     # Establish the preferred order (for the --help-formats option).
-    format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar',
+    format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar',
                        'wininst', 'zip', 'msi']
 
     # And the real information.
     format_command = {'rpm':   ('bdist_rpm',  "RPM distribution"),
                       'gztar': ('bdist_dumb', "gzip'ed tar file"),
                       'bztar': ('bdist_dumb', "bzip2'ed tar file"),
+                      'xztar': ('bdist_dumb', "xz'ed tar file"),
                       'ztar':  ('bdist_dumb', "compressed tar file"),
                       'tar':   ('bdist_dumb', "tar file"),
                       'wininst': ('bdist_wininst',
diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py
--- a/Lib/distutils/command/bdist_dumb.py
+++ b/Lib/distutils/command/bdist_dumb.py
@@ -22,7 +22,8 @@
                      "platform name to embed in generated filenames "
                      "(default: %s)" % get_platform()),
                     ('format=', 'f',
-                     "archive format to create (tar, ztar, gztar, zip)"),
+                     "archive format to create (tar, gztar, bztar, xztar, "
+                     "ztar, zip)"),
                     ('keep-temp', 'k',
                      "keep the pseudo-installation tree around after " +
                      "creating the distribution archive"),
diff --git a/Lib/distutils/tests/test_archive_util.py b/Lib/distutils/tests/test_archive_util.py
--- a/Lib/distutils/tests/test_archive_util.py
+++ b/Lib/distutils/tests/test_archive_util.py
@@ -13,7 +13,7 @@
                                     ARCHIVE_FORMATS)
 from distutils.spawn import find_executable, spawn
 from distutils.tests import support
-from test.support import check_warnings, run_unittest, patch
+from test.support import check_warnings, run_unittest, patch, change_cwd
 
 try:
     import grp
@@ -34,6 +34,16 @@
 except ImportError:
     ZLIB_SUPPORT = False
 
+try:
+    import bz2
+except ImportError:
+    bz2 = None
+
+try:
+    import lzma
+except ImportError:
+    lzma = None
+
 def can_fs_encode(filename):
     """
     Return True if the filename can be saved in the file system.
@@ -52,19 +62,36 @@
                           unittest.TestCase):
 
     @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
-    def test_make_tarball(self):
-        self._make_tarball('archive')
+    def test_make_tarball(self, name='archive'):
+        # creating something to tar
+        tmpdir = self._create_files()
+        self._make_tarball(tmpdir, name, '.tar.gz')
+        # trying an uncompressed one
+        self._make_tarball(tmpdir, name, '.tar', compress=None)
 
     @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
+    def test_make_tarball_gzip(self):
+        tmpdir = self._create_files()
+        self._make_tarball(tmpdir, 'archive', '.tar.gz', compress='gzip')
+
+    @unittest.skipUnless(bz2, 'Need bz2 support to run')
+    def test_make_tarball_bzip2(self):
+        tmpdir = self._create_files()
+        self._make_tarball(tmpdir, 'archive', '.tar.bz2', compress='bzip2')
+
+    @unittest.skipUnless(lzma, 'Need lzma support to run')
+    def test_make_tarball_xz(self):
+        tmpdir = self._create_files()
+        self._make_tarball(tmpdir, 'archive', '.tar.xz', compress='xz')
+
     @unittest.skipUnless(can_fs_encode('årchiv'),
         'File system cannot handle this filename')
     def test_make_tarball_latin1(self):
         """
         Mirror test_make_tarball, except filename contains latin characters.
         """
-        self._make_tarball('årchiv') # note this isn't a real word
+        self.test_make_tarball('årchiv') # note this isn't a real word
 
-    @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
     @unittest.skipUnless(can_fs_encode('のアーカイブ'),
         'File system cannot handle this filename')
     def test_make_tarball_extended(self):
@@ -72,16 +99,9 @@
         Mirror test_make_tarball, except filename contains extended
         characters outside the latin charset.
         """
-        self._make_tarball('のアーカイブ') # japanese for archive
+        self.test_make_tarball('のアーカイブ') # japanese for archive
 
-    def _make_tarball(self, target_name):
-        # creating something to tar
-        tmpdir = self.mkdtemp()
-        self.write_file([tmpdir, 'file1'], 'xxx')
-        self.write_file([tmpdir, 'file2'], 'xxx')
-        os.mkdir(os.path.join(tmpdir, 'sub'))
-        self.write_file([tmpdir, 'sub', 'file3'], 'xxx')
-
+    def _make_tarball(self, tmpdir, target_name, suffix, **kwargs):
         tmpdir2 = self.mkdtemp()
         unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0],
                             "source and target should be on same drive")
@@ -89,27 +109,13 @@
         base_name = os.path.join(tmpdir2, target_name)
 
         # working with relative paths to avoid tar warnings
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            make_tarball(splitdrive(base_name)[1], '.')
-        finally:
-            os.chdir(old_dir)
+        with change_cwd(tmpdir):
+            make_tarball(splitdrive(base_name)[1], 'dist', **kwargs)
 
         # check if the compressed tarball was created
-        tarball = base_name + '.tar.gz'
+        tarball = base_name + suffix
         self.assertTrue(os.path.exists(tarball))
-
-        # trying an uncompressed one
-        base_name = os.path.join(tmpdir2, target_name)
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            make_tarball(splitdrive(base_name)[1], '.', compress=None)
-        finally:
-            os.chdir(old_dir)
-        tarball = base_name + '.tar'
-        self.assertTrue(os.path.exists(tarball))
+        self.assertEqual(self._tarinfo(tarball), self._created_files)
 
     def _tarinfo(self, path):
         tar = tarfile.open(path)
@@ -120,6 +126,9 @@
         finally:
             tar.close()
 
+    _created_files = ('dist', 'dist/file1', 'dist/file2',
+                      'dist/sub', 'dist/sub/file3', 'dist/sub2')
+
     def _create_files(self):
         # creating something to tar
         tmpdir = self.mkdtemp()
@@ -130,15 +139,15 @@
         os.mkdir(os.path.join(dist, 'sub'))
         self.write_file([dist, 'sub', 'file3'], 'xxx')
         os.mkdir(os.path.join(dist, 'sub2'))
-        tmpdir2 = self.mkdtemp()
-        base_name = os.path.join(tmpdir2, 'archive')
-        return tmpdir, tmpdir2, base_name
+        return tmpdir
 
     @unittest.skipUnless(find_executable('tar') and find_executable('gzip')
                          and ZLIB_SUPPORT,
                          'Need the tar, gzip and zlib command to run')
     def test_tarfile_vs_tar(self):
-        tmpdir, tmpdir2, base_name =  self._create_files()
+        tmpdir =  self._create_files()
+        tmpdir2 = self.mkdtemp()
+        base_name = os.path.join(tmpdir2, 'archive')
         old_dir = os.getcwd()
         os.chdir(tmpdir)
         try:
@@ -164,7 +173,8 @@
 
         self.assertTrue(os.path.exists(tarball2))
         # let's compare both tarballs
-        self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2))
+        self.assertEqual(self._tarinfo(tarball), self._created_files)
+        self.assertEqual(self._tarinfo(tarball2), self._created_files)
 
         # trying an uncompressed one
         base_name = os.path.join(tmpdir2, 'archive')
@@ -191,7 +201,8 @@
     @unittest.skipUnless(find_executable('compress'),
                          'The compress program is required')
     def test_compress_deprecated(self):
-        tmpdir, tmpdir2, base_name =  self._create_files()
+        tmpdir =  self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
 
         # using compress and testing the PendingDeprecationWarning
         old_dir = os.getcwd()
@@ -224,17 +235,17 @@
                          'Need zip and zlib support to run')
     def test_make_zipfile(self):
         # creating something to tar
-        tmpdir = self.mkdtemp()
-        self.write_file([tmpdir, 'file1'], 'xxx')
-        self.write_file([tmpdir, 'file2'], 'xxx')
-
-        tmpdir2 = self.mkdtemp()
-        base_name = os.path.join(tmpdir2, 'archive')
-        make_zipfile(base_name, tmpdir)
+        tmpdir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
+        with change_cwd(tmpdir):
+            make_zipfile(base_name, 'dist')
 
         # check if the compressed tarball was created
         tarball = base_name + '.zip'
         self.assertTrue(os.path.exists(tarball))
+        with zipfile.ZipFile(tarball) as zf:
+            self.assertEqual(sorted(zf.namelist()),
+                             ['dist/file1', 'dist/file2', 'dist/sub/file3'])
 
     @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
     def test_make_zipfile_no_zlib(self):
@@ -250,18 +261,24 @@
         patch(self, archive_util.zipfile, 'ZipFile', fake_zipfile)
 
         # create something to tar and compress
-        tmpdir, tmpdir2, base_name = self._create_files()
-        make_zipfile(base_name, tmpdir)
+        tmpdir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
+        with change_cwd(tmpdir):
+            make_zipfile(base_name, 'dist')
 
         tarball = base_name + '.zip'
         self.assertEqual(called,
                          [((tarball, "w"), {'compression': zipfile.ZIP_STORED})])
         self.assertTrue(os.path.exists(tarball))
+        with zipfile.ZipFile(tarball) as zf:
+            self.assertEqual(sorted(zf.namelist()),
+                             ['dist/file1', 'dist/file2', 'dist/sub/file3'])
 
     def test_check_archive_formats(self):
         self.assertEqual(check_archive_formats(['gztar', 'xxx', 'zip']),
                          'xxx')
-        self.assertEqual(check_archive_formats(['gztar', 'zip']), None)
+        self.assertIsNone(check_archive_formats(['gztar', 'bztar', 'xztar',
+                                                 'ztar', 'tar', 'zip']))
 
     def test_make_archive(self):
         tmpdir = self.mkdtemp()
@@ -282,6 +299,41 @@
         finally:
             del ARCHIVE_FORMATS['xxx']
 
+    def test_make_archive_tar(self):
+        base_dir =  self._create_files()
+        base_name = os.path.join(self.mkdtemp() , 'archive')
+        res = make_archive(base_name, 'tar', base_dir, 'dist')
+        self.assertTrue(os.path.exists(res))
+        self.assertEqual(os.path.basename(res), 'archive.tar')
+        self.assertEqual(self._tarinfo(res), self._created_files)
+
+    @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
+    def test_make_archive_gztar(self):
+        base_dir =  self._create_files()
+        base_name = os.path.join(self.mkdtemp() , 'archive')
+        res = make_archive(base_name, 'gztar', base_dir, 'dist')
+        self.assertTrue(os.path.exists(res))
+        self.assertEqual(os.path.basename(res), 'archive.tar.gz')
+        self.assertEqual(self._tarinfo(res), self._created_files)
+
+    @unittest.skipUnless(bz2, 'Need bz2 support to run')
+    def test_make_archive_bztar(self):
+        base_dir =  self._create_files()
+        base_name = os.path.join(self.mkdtemp() , 'archive')
+        res = make_archive(base_name, 'bztar', base_dir, 'dist')
+        self.assertTrue(os.path.exists(res))
+        self.assertEqual(os.path.basename(res), 'archive.tar.bz2')
+        self.assertEqual(self._tarinfo(res), self._created_files)
+
+    @unittest.skipUnless(bz2, 'Need xz support to run')
+    def test_make_archive_xztar(self):
+        base_dir =  self._create_files()
+        base_name = os.path.join(self.mkdtemp() , 'archive')
+        res = make_archive(base_name, 'xztar', base_dir, 'dist')
+        self.assertTrue(os.path.exists(res))
+        self.assertEqual(os.path.basename(res), 'archive.tar.xz')
+        self.assertEqual(self._tarinfo(res), self._created_files)
+
     def test_make_archive_owner_group(self):
         # testing make_archive with owner and group, with various combinations
         # this works even if there's not gid/uid support
@@ -291,7 +343,8 @@
         else:
             group = owner = 'root'
 
-        base_dir, root_dir, base_name =  self._create_files()
+        base_dir =  self._create_files()
+        root_dir = self.mkdtemp()
         base_name = os.path.join(self.mkdtemp() , 'archive')
         res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner,
                            group=group)
@@ -311,7 +364,8 @@
     @unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib")
     @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
     def test_tarfile_root_owner(self):
-        tmpdir, tmpdir2, base_name =  self._create_files()
+        tmpdir =  self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
         old_dir = os.getcwd()
         os.chdir(tmpdir)
         group = grp.getgrgid(0)[0]
diff --git a/Lib/distutils/tests/test_bdist.py b/Lib/distutils/tests/test_bdist.py
--- a/Lib/distutils/tests/test_bdist.py
+++ b/Lib/distutils/tests/test_bdist.py
@@ -21,7 +21,7 @@
 
         # what formats does bdist offer?
         formats = ['bztar', 'gztar', 'msi', 'rpm', 'tar',
-                   'wininst', 'zip', 'ztar']
+                   'wininst', 'xztar', 'zip', 'ztar']
         found = sorted(cmd.format_command)
         self.assertEqual(found, formats)
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -47,6 +47,8 @@
 Library
 -------
 
+- Issue #16314: Added support for the LZMA compression in distutils.
+
 - Issue #21804: poplib now supports RFC 6856 (UTF8).
 
 - Issue #18682: Optimized pprint functions for builtin scalar types.

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list