diff -r 3f1deecd8d50 Lib/lzma.py --- a/Lib/lzma.py Sun Oct 13 00:36:08 2013 -0400 +++ b/Lib/lzma.py Sun Oct 13 15:45:39 2013 +0800 @@ -54,9 +54,9 @@ 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 @@ 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,8 @@ 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 -r 3f1deecd8d50 Lib/test/test_lzma.py --- a/Lib/test/test_lzma.py Sun Oct 13 00:36:08 2013 -0400 +++ b/Lib/test/test_lzma.py Sun Oct 13 15:45:39 2013 +0800 @@ -362,6 +362,8 @@ 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,28 @@ with LZMAFile(TESTFN, "ab"): pass + def test_init_with_x_mode(self): + 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 +1039,6 @@ 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 +1087,15 @@ with lzma.open(bio, "rt", newline="\r") as f: self.assertEqual(f.readlines(), [text]) + def test_x_mode(self): + 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 -r 3f1deecd8d50 Misc/NEWS --- a/Misc/NEWS Sun Oct 13 00:36:08 2013 -0400 +++ b/Misc/NEWS Sun Oct 13 15:45:39 2013 +0800 @@ -42,6 +42,9 @@ Library ------- +- Issue #19201: Add "x" mode (exclusive creation) in opening file to lzma + module. + - Issue #19218: Rename collections.abc to _collections_abc in order to speed up interpreter start.