From 3ca92e9c12768b40e947046d6614f4c948da2558 Mon Sep 17 00:00:00 2001 From: Yaron de Leeuw Date: Mon, 31 Jul 2017 13:16:19 -0400 Subject: [PATCH] bpo-26253: Add compressionlevel to tarfile stream `tarfile` already accepts a compressionlevel argument for creating files. This patch adds the same for stream-based tarfile usage. The default is 9, the value that was previously hard-coded. --- Doc/library/tarfile.rst | 4 +-- Lib/tarfile.py | 33 +++++++++++-------- Misc/ACKS | 1 + .../2017-07-31-13-35-28.bpo-26253.8v_sCs.rst | 1 + 4 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-07-31-13-35-28.bpo-26253.8v_sCs.rst diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 2450716a1d9120..65d0c39015561e 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -98,8 +98,8 @@ Some facts and figures: If *fileobj* is specified, it is used as an alternative to a :term:`file object` opened in binary mode for *name*. It is supposed to be at position 0. - For modes ``'w:gz'``, ``'r:gz'``, ``'w:bz2'``, ``'r:bz2'``, ``'x:gz'``, - ``'x:bz2'``, :func:`tarfile.open` accepts the keyword argument + For modes ``'w:gz'``, ``'x:gz'``, ``'w|gz'``, ``'w:bz2'``, ``'x:bz2'``, + ``'w|bz2'``, :func:`tarfile.open` accepts the keyword argument *compresslevel* (default ``9``) to specify the compression level of the file. For special purposes, there is a second format for *mode*: diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 2d702dd2ec6af9..25ba273cac6439 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -343,7 +343,8 @@ class _Stream: _Stream is intended to be used only internally. """ - def __init__(self, name, mode, comptype, fileobj, bufsize): + def __init__(self, name, mode, comptype, fileobj, bufsize, + compresslevel=9): """Construct a _Stream object. """ self._extfileobj = True @@ -357,14 +358,15 @@ def __init__(self, name, mode, comptype, fileobj, bufsize): fileobj = _StreamProxy(fileobj) comptype = fileobj.getcomptype() - self.name = name or "" - self.mode = mode + self.name = name or "" + self.mode = mode self.comptype = comptype - self.fileobj = fileobj - self.bufsize = bufsize - self.buf = b"" - self.pos = 0 - self.closed = False + self.fileobj = fileobj + self.bufsize = bufsize + self.compresslevel = compresslevel + self.buf = b"" + self.pos = 0 + self.closed = False try: if comptype == "gz": @@ -390,7 +392,7 @@ def __init__(self, name, mode, comptype, fileobj, bufsize): self.cmp = bz2.BZ2Decompressor() self.exception = OSError else: - self.cmp = bz2.BZ2Compressor() + self.cmp = bz2.BZ2Compressor(self.compresslevel) elif comptype == "xz": try: @@ -420,10 +422,11 @@ def __del__(self): def _init_write_gz(self): """Initialize for writing with gzip compression. """ - self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, - -self.zlib.MAX_WBITS, - self.zlib.DEF_MEM_LEVEL, - 0) + self.cmp = self.zlib.compressobj(self.compresslevel, + self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) timestamp = struct.pack("