diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index c9d69cf5094095..8e9775ddbc6915 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -112,7 +112,7 @@ Some facts and figures: ``'w|bz2'``, :func:`tarfile.open` accepts the keyword argument *compresslevel* (default ``9``) to specify the compression level of the file. - For modes ``'w:xz'`` and ``'x:xz'``, :func:`tarfile.open` accepts the + For modes ``'w:xz'``, ``'x:xz'`` and ``'w|xz'``, :func:`tarfile.open` accepts the keyword argument *preset* to specify the compression level of the file. For special purposes, there is a second format for *mode*: @@ -167,6 +167,9 @@ Some facts and figures: .. versionchanged:: 3.12 The *compresslevel* keyword argument also works for streams. + .. versionchanged:: next + The *preset* keyword argument also works for streams. + .. class:: TarFile :noindex: diff --git a/Lib/tarfile.py b/Lib/tarfile.py index a0fab46b24e249..82c5f6704cbd24 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -339,7 +339,7 @@ class _Stream: """ def __init__(self, name, mode, comptype, fileobj, bufsize, - compresslevel): + compresslevel, preset): """Construct a _Stream object. """ self._extfileobj = True @@ -398,7 +398,7 @@ def __init__(self, name, mode, comptype, fileobj, bufsize, self.cmp = lzma.LZMADecompressor() self.exception = lzma.LZMAError else: - self.cmp = lzma.LZMACompressor() + self.cmp = lzma.LZMACompressor(preset=preset) elif comptype != "tar": raise CompressionError("unknown compression type %r" % comptype) @@ -1885,10 +1885,17 @@ def not_compressed(comptype): if filemode not in ("r", "w"): raise ValueError("mode must be 'r' or 'w'") + if "compresslevel" in kwargs and comptype not in ("gz", "bz2"): + raise ValueError( + "compresslevel is only valid for w|gz and w|bz2 modes" + ) + if "preset" in kwargs and comptype not in ("xz",): + raise ValueError("preset is only valid for w|xz mode") compresslevel = kwargs.pop("compresslevel", 9) + preset = kwargs.pop("preset", None) stream = _Stream(name, filemode, comptype, fileobj, bufsize, - compresslevel) + compresslevel, preset) try: t = cls(name, filemode, stream, **kwargs) except: diff --git a/Misc/NEWS.d/next/Library/2025-04-26-14-44-21.gh-issue-133005.y4SRfk.rst b/Misc/NEWS.d/next/Library/2025-04-26-14-44-21.gh-issue-133005.y4SRfk.rst new file mode 100644 index 00000000000000..cb3ad489706967 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-26-14-44-21.gh-issue-133005.y4SRfk.rst @@ -0,0 +1,2 @@ +Support passing ``preset`` option to :func:`tarfile.open` when using ``'w|xz'`` +mode.