https://github.com/python/cpython/commit/019ee49d50b6466f2f18035c812fa87d20c24a46
commit: 019ee49d50b6466f2f18035c812fa87d20c24a46
branch: main
author: Michał Górny <mgo...@gentoo.org>
committer: gpshead <g...@krypto.org>
date: 2025-04-27T22:19:59Z
summary:

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.schub...@gmail.com>

files:
A Misc/NEWS.d/next/Library/2025-04-26-14-44-21.gh-issue-133005.y4SRfk.rst
M Doc/library/tarfile.rst
M Lib/tarfile.py

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.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to