Skip to content

Commit 019ee49

Browse files
gh-133005: Support tarfile.open(mode="w|xz", preset=...) (GH-133007)
* gh-133005: Support `tarfile.open(mode="w|xz", preset=...)` Support passing the `preset` option to `tarfile.open` when the file is open with `mode="w|xz"`. This aligns the behavior with `"w:xz"` mode. * Also raise an error for `compresslevel` or `preset` with wrong mode Raise an error if `compresslevel` or `preset` argument is specified for stream mode with incorrect compression. This should reduce the risk of mistakes and align the stream modes with regular modes, that raise an implicit TypeError on unsupported arguments. * Apply suggestions from code review Co-authored-by: Brian Schubert <brianm.schubert@gmail.com>
1 parent 146b981 commit 019ee49

File tree

3 files changed

+16
-4
lines changed

3 files changed

+16
-4
lines changed

Doc/library/tarfile.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Some facts and figures:
112112
``'w|bz2'``, :func:`tarfile.open` accepts the keyword argument
113113
*compresslevel* (default ``9``) to specify the compression level of the file.
114114

115-
For modes ``'w:xz'`` and ``'x:xz'``, :func:`tarfile.open` accepts the
115+
For modes ``'w:xz'``, ``'x:xz'`` and ``'w|xz'``, :func:`tarfile.open` accepts the
116116
keyword argument *preset* to specify the compression level of the file.
117117

118118
For special purposes, there is a second format for *mode*:
@@ -167,6 +167,9 @@ Some facts and figures:
167167
.. versionchanged:: 3.12
168168
The *compresslevel* keyword argument also works for streams.
169169

170+
.. versionchanged:: next
171+
The *preset* keyword argument also works for streams.
172+
170173

171174
.. class:: TarFile
172175
:noindex:

Lib/tarfile.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ class _Stream:
339339
"""
340340

341341
def __init__(self, name, mode, comptype, fileobj, bufsize,
342-
compresslevel):
342+
compresslevel, preset):
343343
"""Construct a _Stream object.
344344
"""
345345
self._extfileobj = True
@@ -398,7 +398,7 @@ def __init__(self, name, mode, comptype, fileobj, bufsize,
398398
self.cmp = lzma.LZMADecompressor()
399399
self.exception = lzma.LZMAError
400400
else:
401-
self.cmp = lzma.LZMACompressor()
401+
self.cmp = lzma.LZMACompressor(preset=preset)
402402

403403
elif comptype != "tar":
404404
raise CompressionError("unknown compression type %r" % comptype)
@@ -1885,10 +1885,17 @@ def not_compressed(comptype):
18851885

18861886
if filemode not in ("r", "w"):
18871887
raise ValueError("mode must be 'r' or 'w'")
1888+
if "compresslevel" in kwargs and comptype not in ("gz", "bz2"):
1889+
raise ValueError(
1890+
"compresslevel is only valid for w|gz and w|bz2 modes"
1891+
)
1892+
if "preset" in kwargs and comptype not in ("xz",):
1893+
raise ValueError("preset is only valid for w|xz mode")
18881894

18891895
compresslevel = kwargs.pop("compresslevel", 9)
1896+
preset = kwargs.pop("preset", None)
18901897
stream = _Stream(name, filemode, comptype, fileobj, bufsize,
1891-
compresslevel)
1898+
compresslevel, preset)
18921899
try:
18931900
t = cls(name, filemode, stream, **kwargs)
18941901
except:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Support passing ``preset`` option to :func:`tarfile.open` when using ``'w|xz'``
2+
mode.

0 commit comments

Comments
 (0)