Commit 33c34da5 authored by Nadeem Vawda's avatar Nadeem Vawda

Simplify usage of LZMAFile's fileobj support, like with BZ2File.

parent af518c19
...@@ -29,18 +29,20 @@ from multiple threads, it is necessary to protect it with a lock. ...@@ -29,18 +29,20 @@ from multiple threads, it is necessary to protect it with a lock.
Reading and writing compressed files Reading and writing compressed files
------------------------------------ ------------------------------------
.. class:: LZMAFile(filename=None, mode="r", \*, fileobj=None, format=None, check=-1, preset=None, filters=None) .. class:: LZMAFile(filename=None, mode="r", \*, format=None, check=-1, preset=None, filters=None)
Open an LZMA-compressed file. Open an LZMA-compressed file in binary mode.
An :class:`LZMAFile` can wrap an existing :term:`file object` (given by An :class:`LZMAFile` can wrap an already-open :term:`file object`, or operate
*fileobj*), or operate directly on a named file (named by *filename*). directly on a named file. The *filename* argument specifies either the file
Exactly one of these two parameters should be provided. If *fileobj* is object to wrap, or the name of the file to open (as a :class:`str` or
provided, it is not closed when the :class:`LZMAFile` is closed. :class:`bytes` 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 The *mode* argument can be either ``"r"`` for reading (default), ``"w"`` for
overwriting, or ``"a"`` for appending. If *fileobj* is provided, a mode of overwriting, or ``"a"`` for appending. If *filename* is an existing file
``"w"`` does not truncate the file, and is instead equivalent to ``"a"``. object, a mode of ``"w"`` does not truncate the file, and is instead
equivalent to ``"a"``.
When opening a file for reading, the input file may be the concatenation of When opening a file for reading, the input file may be the concatenation of
multiple separate compressed streams. These are transparently decoded as a multiple separate compressed streams. These are transparently decoded as a
...@@ -360,7 +362,7 @@ Writing compressed data to an already-open file:: ...@@ -360,7 +362,7 @@ Writing compressed data to an already-open file::
import lzma import lzma
with open("file.xz", "wb") as f: with open("file.xz", "wb") as f:
f.write(b"This data will not be compressed\n") f.write(b"This data will not be compressed\n")
with lzma.LZMAFile(fileobj=f, mode="w") as lzf: with lzma.LZMAFile(f, "w") as lzf:
lzf.write(b"This *will* be compressed\n") lzf.write(b"This *will* be compressed\n")
f.write(b"Not compressed\n") f.write(b"Not compressed\n")
......
...@@ -46,13 +46,12 @@ class LZMAFile(io.BufferedIOBase): ...@@ -46,13 +46,12 @@ class LZMAFile(io.BufferedIOBase):
""" """
def __init__(self, filename=None, mode="r", *, def __init__(self, filename=None, mode="r", *,
fileobj=None, format=None, check=-1, format=None, check=-1, preset=None, filters=None):
preset=None, filters=None): """Open an LZMA-compressed file in binary mode.
"""Open an LZMA-compressed file.
If filename is given, open the named file. Otherwise, operate on filename can be either an actual file name (given as a str or
the file object given by fileobj. Exactly one of these two bytes object), in which case the named file is opened, or it can
parameters should be provided. 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, or
"a" for appending. "a" for appending.
...@@ -119,16 +118,16 @@ class LZMAFile(io.BufferedIOBase): ...@@ -119,16 +118,16 @@ class LZMAFile(io.BufferedIOBase):
else: else:
raise ValueError("Invalid mode: {!r}".format(mode)) raise ValueError("Invalid mode: {!r}".format(mode))
if filename is not None and fileobj is None: if isinstance(filename, (str, bytes)):
mode += "b" mode += "b"
self._fp = open(filename, mode) self._fp = open(filename, mode)
self._closefp = True self._closefp = True
self._mode = mode_code self._mode = mode_code
elif fileobj is not None and filename is None: elif hasattr(filename, "read") or hasattr(filename, "write"):
self._fp = fileobj self._fp = filename
self._mode = mode_code self._mode = mode_code
else: else:
raise ValueError("Must give exactly one of filename and fileobj") raise TypeError("filename must be a str or bytes object, or a file")
def close(self): def close(self):
"""Flush and close the file. """Flush and close the file.
......
...@@ -1681,8 +1681,7 @@ class TarFile(object): ...@@ -1681,8 +1681,7 @@ class TarFile(object):
except ImportError: except ImportError:
raise CompressionError("lzma module is not available") raise CompressionError("lzma module is not available")
fileobj = lzma.LZMAFile(filename=name if fileobj is None else None, fileobj = lzma.LZMAFile(fileobj or name, mode, preset=preset)
mode=mode, fileobj=fileobj, preset=preset)
try: try:
t = cls.taropen(name, mode, fileobj, **kwargs) t = cls.taropen(name, mode, fileobj, **kwargs)
......
This diff is collapsed.
...@@ -18,8 +18,8 @@ Library ...@@ -18,8 +18,8 @@ Library
- The bz2 module now contains an open() function, allowing compressed files to - The bz2 module now contains an open() function, allowing compressed files to
conveniently be opened in text mode as well as binary mode. conveniently be opened in text mode as well as binary mode.
- BZ2File.__init__() now accepts a file object as its first argument, rather - BZ2File.__init__() and LZMAFile.__init__() now accept a file object as their
than requiring a separate "fileobj" argument. first argument, rather than requiring a separate "fileobj" argument.
- gzip.open() now accepts file objects as well as filenames. - gzip.open() now accepts file objects as well as filenames.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment