Skip to content

Commit

Permalink
bpo-26253: Add compressionlevel to tarfile stream
Browse files Browse the repository at this point in the history
`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.
  • Loading branch information
jarondl committed Jul 31, 2017
1 parent 06bb487 commit 3ca92e9
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 16 deletions.
4 changes: 2 additions & 2 deletions Doc/library/tarfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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*:
Expand Down
33 changes: 19 additions & 14 deletions Lib/tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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":
Expand All @@ -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:
Expand Down Expand Up @@ -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("<L", int(time.time()))
self.__write(b"\037\213\010\010" + timestamp + b"\002\377")
if self.name.endswith(".gz"):
Expand Down Expand Up @@ -1597,7 +1600,9 @@ def not_compressed(comptype):
if filemode not in ("r", "w"):
raise ValueError("mode must be 'r' or 'w'")

stream = _Stream(name, filemode, comptype, fileobj, bufsize)
compresslevel = kwargs.pop("compresslevel", 9)
stream = _Stream(name, filemode, comptype, fileobj, bufsize,
compresslevel)
try:
t = cls(name, filemode, stream, **kwargs)
except:
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,7 @@ Inyeol Lee
James Lee
John J. Lee
Thomas Lee
Yaron de Leeuw
Tennessee Leeuwenburg
Luc Lefebvre
Pierre Paul Lefebvre
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Adjustable compression level for tarfile streams.

0 comments on commit 3ca92e9

Please sign in to comment.