Skip to content

Commit 3ca92e9

Browse files
committed
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.
1 parent 06bb487 commit 3ca92e9

File tree

4 files changed

+23
-16
lines changed

4 files changed

+23
-16
lines changed

Doc/library/tarfile.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ Some facts and figures:
9898
If *fileobj* is specified, it is used as an alternative to a :term:`file object`
9999
opened in binary mode for *name*. It is supposed to be at position 0.
100100

101-
For modes ``'w:gz'``, ``'r:gz'``, ``'w:bz2'``, ``'r:bz2'``, ``'x:gz'``,
102-
``'x:bz2'``, :func:`tarfile.open` accepts the keyword argument
101+
For modes ``'w:gz'``, ``'x:gz'``, ``'w|gz'``, ``'w:bz2'``, ``'x:bz2'``,
102+
``'w|bz2'``, :func:`tarfile.open` accepts the keyword argument
103103
*compresslevel* (default ``9``) to specify the compression level of the file.
104104

105105
For special purposes, there is a second format for *mode*:

Lib/tarfile.py

+19-14
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ class _Stream:
343343
_Stream is intended to be used only internally.
344344
"""
345345

346-
def __init__(self, name, mode, comptype, fileobj, bufsize):
346+
def __init__(self, name, mode, comptype, fileobj, bufsize,
347+
compresslevel=9):
347348
"""Construct a _Stream object.
348349
"""
349350
self._extfileobj = True
@@ -357,14 +358,15 @@ def __init__(self, name, mode, comptype, fileobj, bufsize):
357358
fileobj = _StreamProxy(fileobj)
358359
comptype = fileobj.getcomptype()
359360

360-
self.name = name or ""
361-
self.mode = mode
361+
self.name = name or ""
362+
self.mode = mode
362363
self.comptype = comptype
363-
self.fileobj = fileobj
364-
self.bufsize = bufsize
365-
self.buf = b""
366-
self.pos = 0
367-
self.closed = False
364+
self.fileobj = fileobj
365+
self.bufsize = bufsize
366+
self.compresslevel = compresslevel
367+
self.buf = b""
368+
self.pos = 0
369+
self.closed = False
368370

369371
try:
370372
if comptype == "gz":
@@ -390,7 +392,7 @@ def __init__(self, name, mode, comptype, fileobj, bufsize):
390392
self.cmp = bz2.BZ2Decompressor()
391393
self.exception = OSError
392394
else:
393-
self.cmp = bz2.BZ2Compressor()
395+
self.cmp = bz2.BZ2Compressor(self.compresslevel)
394396

395397
elif comptype == "xz":
396398
try:
@@ -420,10 +422,11 @@ def __del__(self):
420422
def _init_write_gz(self):
421423
"""Initialize for writing with gzip compression.
422424
"""
423-
self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED,
424-
-self.zlib.MAX_WBITS,
425-
self.zlib.DEF_MEM_LEVEL,
426-
0)
425+
self.cmp = self.zlib.compressobj(self.compresslevel,
426+
self.zlib.DEFLATED,
427+
-self.zlib.MAX_WBITS,
428+
self.zlib.DEF_MEM_LEVEL,
429+
0)
427430
timestamp = struct.pack("<L", int(time.time()))
428431
self.__write(b"\037\213\010\010" + timestamp + b"\002\377")
429432
if self.name.endswith(".gz"):
@@ -1597,7 +1600,9 @@ def not_compressed(comptype):
15971600
if filemode not in ("r", "w"):
15981601
raise ValueError("mode must be 'r' or 'w'")
15991602

1600-
stream = _Stream(name, filemode, comptype, fileobj, bufsize)
1603+
compresslevel = kwargs.pop("compresslevel", 9)
1604+
stream = _Stream(name, filemode, comptype, fileobj, bufsize,
1605+
compresslevel)
16011606
try:
16021607
t = cls(name, filemode, stream, **kwargs)
16031608
except:

Misc/ACKS

+1
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,7 @@ Inyeol Lee
871871
James Lee
872872
John J. Lee
873873
Thomas Lee
874+
Yaron de Leeuw
874875
Tennessee Leeuwenburg
875876
Luc Lefebvre
876877
Pierre Paul Lefebvre
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adjustable compression level for tarfile streams.

0 commit comments

Comments
 (0)