]> granicus.if.org Git - python/commitdiff
Issue #28229: lzma module now supports pathlib
authorBerker Peksag <berker.peksag@gmail.com>
Tue, 4 Oct 2016 17:41:20 +0000 (20:41 +0300)
committerBerker Peksag <berker.peksag@gmail.com>
Tue, 4 Oct 2016 17:41:20 +0000 (20:41 +0300)
Doc/library/lzma.rst
Lib/lzma.py
Lib/test/test_lzma.py
Misc/NEWS

index 61b3ba3bb6906440c6e5f34176fcc1b1181bf1ac..5edb23de83bcff1ca11faae1878703cae0fb647e 100644 (file)
@@ -39,8 +39,9 @@ Reading and writing compressed files
    object`.
 
    The *filename* argument can be either an actual file name (given as a
-   :class:`str` or :class:`bytes` object), in which case the named file is
-   opened, or it can be an existing file object to read from or write to.
+   :class:`str`, :class:`bytes` or :term:`path-like object` 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 any of ``"r"``, ``"rb"``, ``"w"``, ``"wb"``,
    ``"x"``, ``"xb"``, ``"a"`` or ``"ab"`` for binary mode, or ``"rt"``,
@@ -64,6 +65,9 @@ Reading and writing compressed files
    .. versionchanged:: 3.4
       Added support for the ``"x"``, ``"xb"`` and ``"xt"`` modes.
 
+   .. versionchanged:: 3.6
+      Accepts a :term:`path-like object`.
+
 
 .. class:: LZMAFile(filename=None, mode="r", \*, format=None, check=-1, preset=None, filters=None)
 
@@ -71,9 +75,10 @@ Reading and writing compressed files
 
    An :class:`LZMAFile` can wrap an already-open :term:`file object`, or operate
    directly on a named file. The *filename* argument specifies either the file
-   object to wrap, or the name of the file to open (as a :class:`str` or
-   :class:`bytes` object). When wrapping an existing file object, the wrapped
-   file will not be closed when the :class:`LZMAFile` is closed.
+   object to wrap, or the name of the file to open (as a :class:`str`,
+   :class:`bytes` or :term:`path-like object` object). When wrapping an
+   existing file object, the wrapped file will not be closed when the
+   :class:`LZMAFile` is closed.
 
    The *mode* argument can be either ``"r"`` for reading (default), ``"w"`` for
    overwriting, ``"x"`` for exclusive creation, or ``"a"`` for appending. These
@@ -118,6 +123,9 @@ Reading and writing compressed files
       The :meth:`~io.BufferedIOBase.read` method now accepts an argument of
       ``None``.
 
+   .. versionchanged:: 3.6
+      Accepts a :term:`path-like object`.
+
 
 Compressing and decompressing data in memory
 --------------------------------------------
index 7dff1c319a6c251f27c302ce9ee8aa3440ffc714..0817b872d2019f2198b17e382cdc9beb3899ac80 100644 (file)
@@ -23,6 +23,7 @@ __all__ = [
 
 import builtins
 import io
+import os
 from _lzma import *
 from _lzma import _encode_filter_properties, _decode_filter_properties
 import _compression
@@ -49,9 +50,10 @@ class LZMAFile(_compression.BaseStream):
                  format=None, check=-1, preset=None, filters=None):
         """Open an LZMA-compressed file in binary mode.
 
-        filename can be either an actual file name (given as a str or
-        bytes object), in which case the named file is opened, or it can
-        be an existing file object to read from or write to.
+        filename can be either an actual file name (given as a str,
+        bytes, or PathLike 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,
         "x" for creating exclusively, or "a" for appending. These can
@@ -112,7 +114,7 @@ class LZMAFile(_compression.BaseStream):
         else:
             raise ValueError("Invalid mode: {!r}".format(mode))
 
-        if isinstance(filename, (str, bytes)):
+        if isinstance(filename, (str, bytes, os.PathLike)):
             if "b" not in mode:
                 mode += "b"
             self._fp = builtins.open(filename, mode)
@@ -122,7 +124,7 @@ class LZMAFile(_compression.BaseStream):
             self._fp = filename
             self._mode = mode_code
         else:
-            raise TypeError("filename must be a str or bytes object, or a file")
+            raise TypeError("filename must be a str, bytes, file or PathLike object")
 
         if self._mode == _MODE_READ:
             raw = _compression.DecompressReader(self._fp, LZMADecompressor,
@@ -263,9 +265,9 @@ def open(filename, mode="rb", *,
          encoding=None, errors=None, newline=None):
     """Open an LZMA-compressed file in binary or text mode.
 
-    filename can be either an actual file name (given as a str or bytes
-    object), in which case the named file is opened, or it can be an
-    existing file object to read from or write to.
+    filename can be either an actual file name (given as a str, bytes,
+    or PathLike 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", "x", "xb",
     "a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text
index 228db66c432b4d48c25bb1ca803a2b3b5461427f..fdc8e11f63e8f7b37f9611fa84a58a5dc488090a 100644 (file)
@@ -1,6 +1,7 @@
 import _compression
 from io import BytesIO, UnsupportedOperation, DEFAULT_BUFFER_SIZE
 import os
+import pathlib
 import pickle
 import random
 import unittest
@@ -488,6 +489,16 @@ class FileTestCase(unittest.TestCase):
         with LZMAFile(BytesIO(), "a") as f:
             pass
 
+    def test_init_with_PathLike_filename(self):
+        filename = pathlib.Path(TESTFN)
+        with TempFile(filename, COMPRESSED_XZ):
+            with LZMAFile(filename) as f:
+                self.assertEqual(f.read(), INPUT)
+            with LZMAFile(filename, "a") as f:
+                f.write(INPUT)
+            with LZMAFile(filename) as f:
+                self.assertEqual(f.read(), INPUT * 2)
+
     def test_init_with_filename(self):
         with TempFile(TESTFN, COMPRESSED_XZ):
             with LZMAFile(TESTFN) as f:
@@ -1180,6 +1191,17 @@ class OpenTestCase(unittest.TestCase):
             with lzma.open(TESTFN, "rb") as f:
                 self.assertEqual(f.read(), INPUT * 2)
 
+    def test_with_pathlike_filename(self):
+        filename = pathlib.Path(TESTFN)
+        with TempFile(filename):
+            with lzma.open(filename, "wb") as f:
+                f.write(INPUT)
+            with open(filename, "rb") as f:
+                file_data = lzma.decompress(f.read())
+                self.assertEqual(file_data, INPUT)
+            with lzma.open(filename, "rb") as f:
+                self.assertEqual(f.read(), INPUT)
+
     def test_bad_params(self):
         # Test invalid parameter combinations.
         with self.assertRaises(ValueError):
index 1a7924ddfada95c926ec4da31ae15e3ae553d5c0..814a0630b914790ff6dc7598a78c0a6df9135b8d 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #28229: lzma module now supports pathlib.
+
 - Issue #28321: Fixed writing non-BMP characters with binary format in plistlib.
 
 - Issue #28225: bz2 module now supports pathlib.  Initial patch by Ethan Furman.