Issue #19201: Add support for the 'x' mode to the lzma module.
Patch by Tim Heaney and Vajrasky Kok.
This commit is contained in:
parent
c516815353
commit
42ca98217c
|
@ -39,8 +39,8 @@ Reading and writing compressed files
|
||||||
opened, or it can be an existing file object to read from or write to.
|
opened, or it can be an existing file object to read from or write to.
|
||||||
|
|
||||||
The *mode* argument can be any of ``"r"``, ``"rb"``, ``"w"``, ``"wb"``,
|
The *mode* argument can be any of ``"r"``, ``"rb"``, ``"w"``, ``"wb"``,
|
||||||
``"a"`` or ``"ab"`` for binary mode, or ``"rt"``, ``"wt"``, or ``"at"`` for
|
``"x"``, ``"xb"``, ``"a"`` or ``"ab"`` for binary mode, or ``"rt"``,
|
||||||
text mode. The default is ``"rb"``.
|
``"wt"``, ``"xt"``, or ``"at"`` for text mode. The default is ``"rb"``.
|
||||||
|
|
||||||
When opening a file for reading, the *format* and *filters* arguments have
|
When opening a file for reading, the *format* and *filters* arguments have
|
||||||
the same meanings as for :class:`LZMADecompressor`. In this case, the *check*
|
the same meanings as for :class:`LZMADecompressor`. In this case, the *check*
|
||||||
|
@ -57,6 +57,9 @@ Reading and writing compressed files
|
||||||
:class:`io.TextIOWrapper` instance with the specified encoding, error
|
:class:`io.TextIOWrapper` instance with the specified encoding, error
|
||||||
handling behavior, and line ending(s).
|
handling behavior, and line ending(s).
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4
|
||||||
|
Added support for the ``"x"``, ``"xb"`` and ``"xt"`` modes.
|
||||||
|
|
||||||
|
|
||||||
.. class:: LZMAFile(filename=None, mode="r", \*, format=None, check=-1, preset=None, filters=None)
|
.. class:: LZMAFile(filename=None, mode="r", \*, format=None, check=-1, preset=None, filters=None)
|
||||||
|
|
||||||
|
@ -69,8 +72,9 @@ Reading and writing compressed files
|
||||||
file will not be closed when the :class:`LZMAFile` is closed.
|
file will not be closed when the :class:`LZMAFile` is closed.
|
||||||
|
|
||||||
The *mode* argument can be either ``"r"`` for reading (default), ``"w"`` for
|
The *mode* argument can be either ``"r"`` for reading (default), ``"w"`` for
|
||||||
overwriting, or ``"a"`` for appending. These can equivalently be given as
|
overwriting, ``"x"`` for exclusive creation, or ``"a"`` for appending. These
|
||||||
``"rb"``, ``"wb"``, and ``"ab"`` respectively.
|
can equivalently be given as ``"rb"``, ``"wb"``, ``"xb"`` and ``"ab"``
|
||||||
|
respectively.
|
||||||
|
|
||||||
If *filename* is a file object (rather than an actual file name), a mode of
|
If *filename* is a file object (rather than an actual file name), a mode of
|
||||||
``"w"`` does not truncate the file, and is instead equivalent to ``"a"``.
|
``"w"`` does not truncate the file, and is instead equivalent to ``"a"``.
|
||||||
|
@ -98,6 +102,9 @@ Reading and writing compressed files
|
||||||
byte of data will be returned, unless EOF has been reached. The exact
|
byte of data will be returned, unless EOF has been reached. The exact
|
||||||
number of bytes returned is unspecified (the *size* argument is ignored).
|
number of bytes returned is unspecified (the *size* argument is ignored).
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4
|
||||||
|
Added support for the ``"x"`` and ``"xb"`` modes.
|
||||||
|
|
||||||
|
|
||||||
Compressing and decompressing data in memory
|
Compressing and decompressing data in memory
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
13
Lib/lzma.py
13
Lib/lzma.py
|
@ -54,9 +54,9 @@ class LZMAFile(io.BufferedIOBase):
|
||||||
bytes object), in which case the named file is opened, or it can
|
bytes object), in which case the named file is opened, or it can
|
||||||
be an existing file object to read from or write to.
|
be an existing file object to read from or write to.
|
||||||
|
|
||||||
mode can be "r" for reading (default), "w" for (over)writing, or
|
mode can be "r" for reading (default), "w" for (over)writing,
|
||||||
"a" for appending. These can equivalently be given as "rb", "wb"
|
"x" for creating exclusively, or "a" for appending. These can
|
||||||
and "ab" respectively.
|
equivalently be given as "rb", "wb", "xb" and "ab" respectively.
|
||||||
|
|
||||||
format specifies the container format to use for the file.
|
format specifies the container format to use for the file.
|
||||||
If mode is "r", this defaults to FORMAT_AUTO. Otherwise, the
|
If mode is "r", this defaults to FORMAT_AUTO. Otherwise, the
|
||||||
|
@ -112,7 +112,7 @@ class LZMAFile(io.BufferedIOBase):
|
||||||
self._decompressor = LZMADecompressor(**self._init_args)
|
self._decompressor = LZMADecompressor(**self._init_args)
|
||||||
self._buffer = b""
|
self._buffer = b""
|
||||||
self._buffer_offset = 0
|
self._buffer_offset = 0
|
||||||
elif mode in ("w", "wb", "a", "ab"):
|
elif mode in ("w", "wb", "a", "ab", "x", "xb"):
|
||||||
if format is None:
|
if format is None:
|
||||||
format = FORMAT_XZ
|
format = FORMAT_XZ
|
||||||
mode_code = _MODE_WRITE
|
mode_code = _MODE_WRITE
|
||||||
|
@ -426,8 +426,9 @@ def open(filename, mode="rb", *,
|
||||||
object), in which case the named file is opened, or it can be an
|
object), in which case the named file is opened, or it can be an
|
||||||
existing file object to read from or write to.
|
existing file object to read from or write to.
|
||||||
|
|
||||||
The mode argument can be "r", "rb" (default), "w", "wb", "a" or "ab"
|
The mode argument can be "r", "rb" (default), "w", "wb", "x", "xb",
|
||||||
for binary mode, or "rt", "wt" or "at" for text mode.
|
"a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text
|
||||||
|
mode.
|
||||||
|
|
||||||
The format, check, preset and filters arguments specify the
|
The format, check, preset and filters arguments specify the
|
||||||
compression settings, as for LZMACompressor, LZMADecompressor and
|
compression settings, as for LZMACompressor, LZMADecompressor and
|
||||||
|
|
|
@ -362,6 +362,8 @@ class FileTestCase(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
with LZMAFile(BytesIO(), "w") as f:
|
with LZMAFile(BytesIO(), "w") as f:
|
||||||
pass
|
pass
|
||||||
|
with LZMAFile(BytesIO(), "x") as f:
|
||||||
|
pass
|
||||||
with LZMAFile(BytesIO(), "a") as f:
|
with LZMAFile(BytesIO(), "a") as f:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -389,13 +391,29 @@ class FileTestCase(unittest.TestCase):
|
||||||
with LZMAFile(TESTFN, "ab"):
|
with LZMAFile(TESTFN, "ab"):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def test_init_with_x_mode(self):
|
||||||
|
self.addCleanup(unlink, TESTFN)
|
||||||
|
for mode in ("x", "xb"):
|
||||||
|
unlink(TESTFN)
|
||||||
|
with LZMAFile(TESTFN, mode):
|
||||||
|
pass
|
||||||
|
with self.assertRaises(FileExistsError):
|
||||||
|
with LZMAFile(TESTFN, mode):
|
||||||
|
pass
|
||||||
|
|
||||||
def test_init_bad_mode(self):
|
def test_init_bad_mode(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
LZMAFile(BytesIO(COMPRESSED_XZ), (3, "x"))
|
LZMAFile(BytesIO(COMPRESSED_XZ), (3, "x"))
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
LZMAFile(BytesIO(COMPRESSED_XZ), "")
|
LZMAFile(BytesIO(COMPRESSED_XZ), "")
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
LZMAFile(BytesIO(COMPRESSED_XZ), "x")
|
LZMAFile(BytesIO(COMPRESSED_XZ), "xt")
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
LZMAFile(BytesIO(COMPRESSED_XZ), "x+")
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
LZMAFile(BytesIO(COMPRESSED_XZ), "rx")
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
LZMAFile(BytesIO(COMPRESSED_XZ), "wx")
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
LZMAFile(BytesIO(COMPRESSED_XZ), "rt")
|
LZMAFile(BytesIO(COMPRESSED_XZ), "rt")
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
|
@ -1021,8 +1039,6 @@ class OpenTestCase(unittest.TestCase):
|
||||||
# Test invalid parameter combinations.
|
# Test invalid parameter combinations.
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
lzma.open(TESTFN, "")
|
lzma.open(TESTFN, "")
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
lzma.open(TESTFN, "x")
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
lzma.open(TESTFN, "rbt")
|
lzma.open(TESTFN, "rbt")
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
|
@ -1072,6 +1088,16 @@ class OpenTestCase(unittest.TestCase):
|
||||||
with lzma.open(bio, "rt", newline="\r") as f:
|
with lzma.open(bio, "rt", newline="\r") as f:
|
||||||
self.assertEqual(f.readlines(), [text])
|
self.assertEqual(f.readlines(), [text])
|
||||||
|
|
||||||
|
def test_x_mode(self):
|
||||||
|
self.addCleanup(unlink, TESTFN)
|
||||||
|
for mode in ("x", "xb", "xt"):
|
||||||
|
unlink(TESTFN)
|
||||||
|
with lzma.open(TESTFN, mode):
|
||||||
|
pass
|
||||||
|
with self.assertRaises(FileExistsError):
|
||||||
|
with lzma.open(TESTFN, mode):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MiscellaneousTestCase(unittest.TestCase):
|
class MiscellaneousTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -506,6 +506,7 @@ Janko Hauser
|
||||||
Rycharde Hawkes
|
Rycharde Hawkes
|
||||||
Ben Hayden
|
Ben Hayden
|
||||||
Jochen Hayek
|
Jochen Hayek
|
||||||
|
Tim Heaney
|
||||||
Henrik Heimbuerger
|
Henrik Heimbuerger
|
||||||
Christian Heimes
|
Christian Heimes
|
||||||
Thomas Heller
|
Thomas Heller
|
||||||
|
|
|
@ -54,6 +54,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #19201: Add "x" mode (exclusive creation) in opening file to lzma
|
||||||
|
module. Patch by Tim Heaney and Vajrasky Kok.
|
||||||
|
|
||||||
- Fix a reference count leak in _sre.
|
- Fix a reference count leak in _sre.
|
||||||
|
|
||||||
- Issue #19262: Initial check in of the 'asyncio' package (a.k.a. Tulip,
|
- Issue #19262: Initial check in of the 'asyncio' package (a.k.a. Tulip,
|
||||||
|
|
Loading…
Reference in New Issue