summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadeem Vawda <nadeem.vawda@gmail.com>2013-10-18 22:06:19 (GMT)
committerNadeem Vawda <nadeem.vawda@gmail.com>2013-10-18 22:06:19 (GMT)
commit42ca98217ca544220fdf4d33875c811f342edc56 (patch)
tree4ca867f69d20ab9c69779ae4a87dda0b116649b4
parentc5168153538b46885a5345033c124d4a3d6c9dcc (diff)
downloadcpython-42ca98217ca544220fdf4d33875c811f342edc56.zip
cpython-42ca98217ca544220fdf4d33875c811f342edc56.tar.gz
cpython-42ca98217ca544220fdf4d33875c811f342edc56.tar.bz2
Issue #19201: Add support for the 'x' mode to the lzma module.
Patch by Tim Heaney and Vajrasky Kok.
-rw-r--r--Doc/library/lzma.rst15
-rw-r--r--Lib/lzma.py13
-rw-r--r--Lib/test/test_lzma.py32
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
5 files changed, 51 insertions, 13 deletions
diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst
index 5fd5039..b201206 100644
--- a/Doc/library/lzma.rst
+++ b/Doc/library/lzma.rst
@@ -39,8 +39,8 @@ Reading and writing compressed files
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"``,
- ``"a"`` or ``"ab"`` for binary mode, or ``"rt"``, ``"wt"``, or ``"at"`` for
- text mode. The default is ``"rb"``.
+ ``"x"``, ``"xb"``, ``"a"`` or ``"ab"`` for binary mode, or ``"rt"``,
+ ``"wt"``, ``"xt"``, or ``"at"`` for text mode. The default is ``"rb"``.
When opening a file for reading, the *format* and *filters* arguments have
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
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)
@@ -69,8 +72,9 @@ Reading and writing compressed files
file will not be closed when the :class:`LZMAFile` is closed.
The *mode* argument can be either ``"r"`` for reading (default), ``"w"`` for
- overwriting, or ``"a"`` for appending. These can equivalently be given as
- ``"rb"``, ``"wb"``, and ``"ab"`` respectively.
+ overwriting, ``"x"`` for exclusive creation, or ``"a"`` for appending. These
+ 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
``"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
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
--------------------------------------------
diff --git a/Lib/lzma.py b/Lib/lzma.py
index b2e2f7e..011ad27 100644
--- a/Lib/lzma.py
+++ b/Lib/lzma.py
@@ -54,9 +54,9 @@ class LZMAFile(io.BufferedIOBase):
bytes object), in which case the named file is opened, or it can
be an existing file object to read from or write to.
- mode can be "r" for reading (default), "w" for (over)writing, or
- "a" for appending. These can equivalently be given as "rb", "wb"
- and "ab" respectively.
+ mode can be "r" for reading (default), "w" for (over)writing,
+ "x" for creating exclusively, or "a" for appending. These can
+ equivalently be given as "rb", "wb", "xb" and "ab" respectively.
format specifies the container format to use for the file.
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._buffer = b""
self._buffer_offset = 0
- elif mode in ("w", "wb", "a", "ab"):
+ elif mode in ("w", "wb", "a", "ab", "x", "xb"):
if format is None:
format = FORMAT_XZ
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
existing file object to read from or write to.
- The mode argument can be "r", "rb" (default), "w", "wb", "a" or "ab"
- for binary mode, or "rt", "wt" or "at" for text mode.
+ The mode argument can be "r", "rb" (default), "w", "wb", "x", "xb",
+ "a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text
+ mode.
The format, check, preset and filters arguments specify the
compression settings, as for LZMACompressor, LZMADecompressor and
diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py
index 20d8582..b6af563 100644
--- a/Lib/test/test_lzma.py
+++ b/Lib/test/test_lzma.py
@@ -362,6 +362,8 @@ class FileTestCase(unittest.TestCase):
pass
with LZMAFile(BytesIO(), "w") as f:
pass
+ with LZMAFile(BytesIO(), "x") as f:
+ pass
with LZMAFile(BytesIO(), "a") as f:
pass
@@ -389,13 +391,29 @@ class FileTestCase(unittest.TestCase):
with LZMAFile(TESTFN, "ab"):
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):
with self.assertRaises(ValueError):
LZMAFile(BytesIO(COMPRESSED_XZ), (3, "x"))
with self.assertRaises(ValueError):
LZMAFile(BytesIO(COMPRESSED_XZ), "")
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):
LZMAFile(BytesIO(COMPRESSED_XZ), "rt")
with self.assertRaises(ValueError):
@@ -1022,8 +1040,6 @@ class OpenTestCase(unittest.TestCase):
with self.assertRaises(ValueError):
lzma.open(TESTFN, "")
with self.assertRaises(ValueError):
- lzma.open(TESTFN, "x")
- with self.assertRaises(ValueError):
lzma.open(TESTFN, "rbt")
with self.assertRaises(ValueError):
lzma.open(TESTFN, "rb", encoding="utf-8")
@@ -1072,6 +1088,16 @@ class OpenTestCase(unittest.TestCase):
with lzma.open(bio, "rt", newline="\r") as f:
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):
diff --git a/Misc/ACKS b/Misc/ACKS
index e204bc3..880e4f0 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -506,6 +506,7 @@ Janko Hauser
Rycharde Hawkes
Ben Hayden
Jochen Hayek
+Tim Heaney
Henrik Heimbuerger
Christian Heimes
Thomas Heller
diff --git a/Misc/NEWS b/Misc/NEWS
index a0af8cd..4d514f5 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -54,6 +54,9 @@ Core and Builtins
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.
- Issue #19262: Initial check in of the 'asyncio' package (a.k.a. Tulip,