mirror of https://github.com/python/cpython
gh-115961: Add name and mode attributes for compressed file-like objects (GH-116036)
* Add name and mode attributes for compressed and archived file-like objects in modules bz2, lzma, tarfile and zipfile. * Change the value of the mode attribute of GzipFile from integer (1 or 2) to string ('rb' or 'wb'). * Change the value of the mode attribute of ZipExtFile from 'r' to 'rb'.
This commit is contained in:
parent
ccda738284
commit
51ef89cd9a
|
@ -91,7 +91,7 @@ The :mod:`bz2` module contains:
|
||||||
and :meth:`~io.IOBase.truncate`.
|
and :meth:`~io.IOBase.truncate`.
|
||||||
Iteration and the :keyword:`with` statement are supported.
|
Iteration and the :keyword:`with` statement are supported.
|
||||||
|
|
||||||
:class:`BZ2File` also provides the following methods:
|
:class:`BZ2File` also provides the following methods and attributes:
|
||||||
|
|
||||||
.. method:: peek([n])
|
.. method:: peek([n])
|
||||||
|
|
||||||
|
@ -148,6 +148,19 @@ The :mod:`bz2` module contains:
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
.. attribute:: mode
|
||||||
|
|
||||||
|
``'rb'`` for reading and ``'wb'`` for writing.
|
||||||
|
|
||||||
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
.. attribute:: name
|
||||||
|
|
||||||
|
The bzip2 file name. Equivalent to the :attr:`~io.FileIO.name`
|
||||||
|
attribute of the underlying :term:`file object`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. versionchanged:: 3.1
|
.. versionchanged:: 3.1
|
||||||
Support for the :keyword:`with` statement was added.
|
Support for the :keyword:`with` statement was added.
|
||||||
|
|
|
@ -133,6 +133,13 @@ The module defines the following items:
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. attribute:: mode
|
||||||
|
|
||||||
|
``'rb'`` for reading and ``'wb'`` for writing.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
In previous versions it was an integer ``1`` or ``2``.
|
||||||
|
|
||||||
.. attribute:: mtime
|
.. attribute:: mtime
|
||||||
|
|
||||||
When decompressing, this attribute is set to the last timestamp in the most
|
When decompressing, this attribute is set to the last timestamp in the most
|
||||||
|
@ -168,14 +175,14 @@ The module defines the following items:
|
||||||
.. versionchanged:: 3.6
|
.. versionchanged:: 3.6
|
||||||
Accepts a :term:`path-like object`.
|
Accepts a :term:`path-like object`.
|
||||||
|
|
||||||
.. versionchanged:: 3.12
|
|
||||||
Remove the ``filename`` attribute, use the :attr:`~GzipFile.name`
|
|
||||||
attribute instead.
|
|
||||||
|
|
||||||
.. deprecated:: 3.9
|
.. deprecated:: 3.9
|
||||||
Opening :class:`GzipFile` for writing without specifying the *mode*
|
Opening :class:`GzipFile` for writing without specifying the *mode*
|
||||||
argument is deprecated.
|
argument is deprecated.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.12
|
||||||
|
Remove the ``filename`` attribute, use the :attr:`~GzipFile.name`
|
||||||
|
attribute instead.
|
||||||
|
|
||||||
|
|
||||||
.. function:: compress(data, compresslevel=9, *, mtime=None)
|
.. function:: compress(data, compresslevel=9, *, mtime=None)
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ Reading and writing compressed files
|
||||||
and :meth:`~io.IOBase.truncate`.
|
and :meth:`~io.IOBase.truncate`.
|
||||||
Iteration and the :keyword:`with` statement are supported.
|
Iteration and the :keyword:`with` statement are supported.
|
||||||
|
|
||||||
The following method is also provided:
|
The following method and attributes are also provided:
|
||||||
|
|
||||||
.. method:: peek(size=-1)
|
.. method:: peek(size=-1)
|
||||||
|
|
||||||
|
@ -117,6 +117,20 @@ Reading and writing compressed files
|
||||||
file object (e.g. if the :class:`LZMAFile` was constructed by passing a
|
file object (e.g. if the :class:`LZMAFile` was constructed by passing a
|
||||||
file object for *filename*).
|
file object for *filename*).
|
||||||
|
|
||||||
|
.. attribute:: mode
|
||||||
|
|
||||||
|
``'rb'`` for reading and ``'wb'`` for writing.
|
||||||
|
|
||||||
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
.. attribute:: name
|
||||||
|
|
||||||
|
The lzma file name. Equivalent to the :attr:`~io.FileIO.name`
|
||||||
|
attribute of the underlying :term:`file object`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. versionchanged:: 3.4
|
.. versionchanged:: 3.4
|
||||||
Added support for the ``"x"`` and ``"xb"`` modes.
|
Added support for the ``"x"`` and ``"xb"`` modes.
|
||||||
|
|
||||||
|
|
|
@ -565,6 +565,10 @@ be finalized; only the internally used file object will be closed. See the
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
Return an :class:`io.BufferedReader` object.
|
Return an :class:`io.BufferedReader` object.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
The returned :class:`io.BufferedReader` object has the :attr:`!mode`
|
||||||
|
attribute which is always equal to ``'rb'``.
|
||||||
|
|
||||||
.. attribute:: TarFile.errorlevel
|
.. attribute:: TarFile.errorlevel
|
||||||
:type: int
|
:type: int
|
||||||
|
|
||||||
|
|
|
@ -301,6 +301,10 @@ ZipFile Objects
|
||||||
attempting to read or write other files in the ZIP file will raise a
|
attempting to read or write other files in the ZIP file will raise a
|
||||||
:exc:`ValueError`.
|
:exc:`ValueError`.
|
||||||
|
|
||||||
|
In both cases the file-like object has also attributes :attr:`!name`,
|
||||||
|
which is equivalent to the name of a file within the archive, and
|
||||||
|
:attr:`!mode`, which is ``'rb'`` or ``'wb'`` depending on the input mode.
|
||||||
|
|
||||||
When writing a file, if the file size is not known in advance but may exceed
|
When writing a file, if the file size is not known in advance but may exceed
|
||||||
2 GiB, pass ``force_zip64=True`` to ensure that the header format is
|
2 GiB, pass ``force_zip64=True`` to ensure that the header format is
|
||||||
capable of supporting large files. If the file size is known in advance,
|
capable of supporting large files. If the file size is known in advance,
|
||||||
|
@ -325,6 +329,12 @@ ZipFile Objects
|
||||||
Calling :meth:`.open` on a closed ZipFile will raise a :exc:`ValueError`.
|
Calling :meth:`.open` on a closed ZipFile will raise a :exc:`ValueError`.
|
||||||
Previously, a :exc:`RuntimeError` was raised.
|
Previously, a :exc:`RuntimeError` was raised.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
Added attributes :attr:`!name` and :attr:`!mode` for the writeable
|
||||||
|
file-like object.
|
||||||
|
The value of the :attr:`!mode` attribute for the readable file-like
|
||||||
|
object was changed from ``'r'`` to ``'rb'``.
|
||||||
|
|
||||||
|
|
||||||
.. method:: ZipFile.extract(member, path=None, pwd=None)
|
.. method:: ZipFile.extract(member, path=None, pwd=None)
|
||||||
|
|
||||||
|
|
|
@ -206,6 +206,11 @@ Other Language Changes
|
||||||
|
|
||||||
(Contributed by Victor Stinner in :gh:`114570`.)
|
(Contributed by Victor Stinner in :gh:`114570`.)
|
||||||
|
|
||||||
|
* Added :attr:`!name` and :attr:`!mode` attributes for compressed
|
||||||
|
and archived file-like objects in modules :mod:`bz2`, :mod:`lzma`,
|
||||||
|
:mod:`tarfile` and :mod:`zipfile`.
|
||||||
|
(Contributed by Serhiy Storchaka in :gh:`115961`.)
|
||||||
|
|
||||||
* Allow controlling Expat >=2.6.0 reparse deferral (:cve:`2023-52425`)
|
* Allow controlling Expat >=2.6.0 reparse deferral (:cve:`2023-52425`)
|
||||||
by adding five new methods:
|
by adding five new methods:
|
||||||
|
|
||||||
|
@ -1605,6 +1610,12 @@ Changes in the Python API
|
||||||
than directories only. Users may add a trailing slash to match only
|
than directories only. Users may add a trailing slash to match only
|
||||||
directories.
|
directories.
|
||||||
|
|
||||||
|
* The value of the :attr:`!mode` attribute of :class:`gzip.GzipFile` was
|
||||||
|
changed from integer (``1`` or ``2``) to string (``'rb'`` or ``'wb'``).
|
||||||
|
The value of the :attr:`!mode` attribute of the readable file-like object
|
||||||
|
returned by :meth:`zipfile.ZipFile.open` was changed from ``'r'`` to ``'rb'``.
|
||||||
|
(Contributed by Serhiy Storchaka in :gh:`115961`.)
|
||||||
|
|
||||||
* :c:func:`!PyCode_GetFirstFree` is an unstable API now and has been renamed
|
* :c:func:`!PyCode_GetFirstFree` is an unstable API now and has been renamed
|
||||||
to :c:func:`PyUnstable_Code_GetFirstFree`.
|
to :c:func:`PyUnstable_Code_GetFirstFree`.
|
||||||
(Contributed by Bogdan Romanyuk in :gh:`115781`.)
|
(Contributed by Bogdan Romanyuk in :gh:`115781`.)
|
||||||
|
|
18
Lib/bz2.py
18
Lib/bz2.py
|
@ -17,7 +17,7 @@ import _compression
|
||||||
from _bz2 import BZ2Compressor, BZ2Decompressor
|
from _bz2 import BZ2Compressor, BZ2Decompressor
|
||||||
|
|
||||||
|
|
||||||
_MODE_CLOSED = 0
|
# Value 0 no longer used
|
||||||
_MODE_READ = 1
|
_MODE_READ = 1
|
||||||
# Value 2 no longer used
|
# Value 2 no longer used
|
||||||
_MODE_WRITE = 3
|
_MODE_WRITE = 3
|
||||||
|
@ -54,7 +54,7 @@ class BZ2File(_compression.BaseStream):
|
||||||
"""
|
"""
|
||||||
self._fp = None
|
self._fp = None
|
||||||
self._closefp = False
|
self._closefp = False
|
||||||
self._mode = _MODE_CLOSED
|
self._mode = None
|
||||||
|
|
||||||
if not (1 <= compresslevel <= 9):
|
if not (1 <= compresslevel <= 9):
|
||||||
raise ValueError("compresslevel must be between 1 and 9")
|
raise ValueError("compresslevel must be between 1 and 9")
|
||||||
|
@ -100,7 +100,7 @@ class BZ2File(_compression.BaseStream):
|
||||||
May be called more than once without error. Once the file is
|
May be called more than once without error. Once the file is
|
||||||
closed, any other operation on it will raise a ValueError.
|
closed, any other operation on it will raise a ValueError.
|
||||||
"""
|
"""
|
||||||
if self._mode == _MODE_CLOSED:
|
if self.closed:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
if self._mode == _MODE_READ:
|
if self._mode == _MODE_READ:
|
||||||
|
@ -115,13 +115,21 @@ class BZ2File(_compression.BaseStream):
|
||||||
finally:
|
finally:
|
||||||
self._fp = None
|
self._fp = None
|
||||||
self._closefp = False
|
self._closefp = False
|
||||||
self._mode = _MODE_CLOSED
|
|
||||||
self._buffer = None
|
self._buffer = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def closed(self):
|
def closed(self):
|
||||||
"""True if this file is closed."""
|
"""True if this file is closed."""
|
||||||
return self._mode == _MODE_CLOSED
|
return self._fp is None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
self._check_not_closed()
|
||||||
|
return self._fp.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
return 'wb' if self._mode == _MODE_WRITE else 'rb'
|
||||||
|
|
||||||
def fileno(self):
|
def fileno(self):
|
||||||
"""Return the file descriptor for the underlying file."""
|
"""Return the file descriptor for the underlying file."""
|
||||||
|
|
|
@ -15,7 +15,8 @@ __all__ = ["BadGzipFile", "GzipFile", "open", "compress", "decompress"]
|
||||||
|
|
||||||
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
|
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
|
||||||
|
|
||||||
READ, WRITE = 1, 2
|
READ = 'rb'
|
||||||
|
WRITE = 'wb'
|
||||||
|
|
||||||
_COMPRESS_LEVEL_FAST = 1
|
_COMPRESS_LEVEL_FAST = 1
|
||||||
_COMPRESS_LEVEL_TRADEOFF = 6
|
_COMPRESS_LEVEL_TRADEOFF = 6
|
||||||
|
|
18
Lib/lzma.py
18
Lib/lzma.py
|
@ -29,7 +29,7 @@ from _lzma import _encode_filter_properties, _decode_filter_properties
|
||||||
import _compression
|
import _compression
|
||||||
|
|
||||||
|
|
||||||
_MODE_CLOSED = 0
|
# Value 0 no longer used
|
||||||
_MODE_READ = 1
|
_MODE_READ = 1
|
||||||
# Value 2 no longer used
|
# Value 2 no longer used
|
||||||
_MODE_WRITE = 3
|
_MODE_WRITE = 3
|
||||||
|
@ -92,7 +92,7 @@ class LZMAFile(_compression.BaseStream):
|
||||||
"""
|
"""
|
||||||
self._fp = None
|
self._fp = None
|
||||||
self._closefp = False
|
self._closefp = False
|
||||||
self._mode = _MODE_CLOSED
|
self._mode = None
|
||||||
|
|
||||||
if mode in ("r", "rb"):
|
if mode in ("r", "rb"):
|
||||||
if check != -1:
|
if check != -1:
|
||||||
|
@ -137,7 +137,7 @@ class LZMAFile(_compression.BaseStream):
|
||||||
May be called more than once without error. Once the file is
|
May be called more than once without error. Once the file is
|
||||||
closed, any other operation on it will raise a ValueError.
|
closed, any other operation on it will raise a ValueError.
|
||||||
"""
|
"""
|
||||||
if self._mode == _MODE_CLOSED:
|
if self.closed:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
if self._mode == _MODE_READ:
|
if self._mode == _MODE_READ:
|
||||||
|
@ -153,12 +153,20 @@ class LZMAFile(_compression.BaseStream):
|
||||||
finally:
|
finally:
|
||||||
self._fp = None
|
self._fp = None
|
||||||
self._closefp = False
|
self._closefp = False
|
||||||
self._mode = _MODE_CLOSED
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def closed(self):
|
def closed(self):
|
||||||
"""True if this file is closed."""
|
"""True if this file is closed."""
|
||||||
return self._mode == _MODE_CLOSED
|
return self._fp is None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
self._check_not_closed()
|
||||||
|
return self._fp.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
return 'wb' if self._mode == _MODE_WRITE else 'rb'
|
||||||
|
|
||||||
def fileno(self):
|
def fileno(self):
|
||||||
"""Return the file descriptor for the underlying file."""
|
"""Return the file descriptor for the underlying file."""
|
||||||
|
|
|
@ -636,6 +636,10 @@ class _FileInFile(object):
|
||||||
def flush(self):
|
def flush(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
return 'rb'
|
||||||
|
|
||||||
def readable(self):
|
def readable(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -540,40 +540,54 @@ class BZ2FileTest(BaseTest):
|
||||||
def testOpenFilename(self):
|
def testOpenFilename(self):
|
||||||
with BZ2File(self.filename, "wb") as f:
|
with BZ2File(self.filename, "wb") as f:
|
||||||
f.write(b'content')
|
f.write(b'content')
|
||||||
|
self.assertEqual(f.name, self.filename)
|
||||||
self.assertIsInstance(f.fileno(), int)
|
self.assertIsInstance(f.fileno(), int)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertIs(f.readable(), False)
|
self.assertIs(f.readable(), False)
|
||||||
self.assertIs(f.writable(), True)
|
self.assertIs(f.writable(), True)
|
||||||
self.assertIs(f.seekable(), False)
|
self.assertIs(f.seekable(), False)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
|
||||||
with BZ2File(self.filename, "ab") as f:
|
with BZ2File(self.filename, "ab") as f:
|
||||||
f.write(b'appendix')
|
f.write(b'appendix')
|
||||||
|
self.assertEqual(f.name, self.filename)
|
||||||
self.assertIsInstance(f.fileno(), int)
|
self.assertIsInstance(f.fileno(), int)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertIs(f.readable(), False)
|
self.assertIs(f.readable(), False)
|
||||||
self.assertIs(f.writable(), True)
|
self.assertIs(f.writable(), True)
|
||||||
self.assertIs(f.seekable(), False)
|
self.assertIs(f.seekable(), False)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
|
||||||
with BZ2File(self.filename, 'rb') as f:
|
with BZ2File(self.filename, 'rb') as f:
|
||||||
self.assertEqual(f.read(), b'contentappendix')
|
self.assertEqual(f.read(), b'contentappendix')
|
||||||
|
self.assertEqual(f.name, self.filename)
|
||||||
self.assertIsInstance(f.fileno(), int)
|
self.assertIsInstance(f.fileno(), int)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertIs(f.readable(), True)
|
self.assertIs(f.readable(), True)
|
||||||
self.assertIs(f.writable(), False)
|
self.assertIs(f.writable(), False)
|
||||||
self.assertIs(f.seekable(), True)
|
self.assertIs(f.seekable(), True)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
f.fileno()
|
f.name
|
||||||
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -582,13 +596,18 @@ class BZ2FileTest(BaseTest):
|
||||||
with open(self.filename, 'wb') as raw:
|
with open(self.filename, 'wb') as raw:
|
||||||
with BZ2File(raw, 'wb') as f:
|
with BZ2File(raw, 'wb') as f:
|
||||||
f.write(b'content')
|
f.write(b'content')
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertIs(f.readable(), False)
|
self.assertIs(f.readable(), False)
|
||||||
self.assertIs(f.writable(), True)
|
self.assertIs(f.writable(), True)
|
||||||
self.assertIs(f.seekable(), False)
|
self.assertIs(f.seekable(), False)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -596,13 +615,18 @@ class BZ2FileTest(BaseTest):
|
||||||
with open(self.filename, 'ab') as raw:
|
with open(self.filename, 'ab') as raw:
|
||||||
with BZ2File(raw, 'ab') as f:
|
with BZ2File(raw, 'ab') as f:
|
||||||
f.write(b'appendix')
|
f.write(b'appendix')
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertIs(f.readable(), False)
|
self.assertIs(f.readable(), False)
|
||||||
self.assertIs(f.writable(), True)
|
self.assertIs(f.writable(), True)
|
||||||
self.assertIs(f.seekable(), False)
|
self.assertIs(f.seekable(), False)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -610,14 +634,18 @@ class BZ2FileTest(BaseTest):
|
||||||
with open(self.filename, 'rb') as raw:
|
with open(self.filename, 'rb') as raw:
|
||||||
with BZ2File(raw, 'rb') as f:
|
with BZ2File(raw, 'rb') as f:
|
||||||
self.assertEqual(f.read(), b'contentappendix')
|
self.assertEqual(f.read(), b'contentappendix')
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertIs(f.readable(), True)
|
self.assertIs(f.readable(), True)
|
||||||
self.assertIs(f.writable(), False)
|
self.assertIs(f.writable(), False)
|
||||||
self.assertIs(f.seekable(), True)
|
self.assertIs(f.seekable(), True)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
f.fileno()
|
f.name
|
||||||
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -626,61 +654,91 @@ class BZ2FileTest(BaseTest):
|
||||||
bio = BytesIO()
|
bio = BytesIO()
|
||||||
with BZ2File(bio, 'wb') as f:
|
with BZ2File(bio, 'wb') as f:
|
||||||
f.write(b'content')
|
f.write(b'content')
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
f.name
|
||||||
self.assertRaises(io.UnsupportedOperation, f.fileno)
|
self.assertRaises(io.UnsupportedOperation, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
|
||||||
with BZ2File(bio, 'ab') as f:
|
with BZ2File(bio, 'ab') as f:
|
||||||
f.write(b'appendix')
|
f.write(b'appendix')
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
f.name
|
||||||
self.assertRaises(io.UnsupportedOperation, f.fileno)
|
self.assertRaises(io.UnsupportedOperation, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
|
||||||
bio.seek(0)
|
bio.seek(0)
|
||||||
with BZ2File(bio, 'rb') as f:
|
with BZ2File(bio, 'rb') as f:
|
||||||
self.assertEqual(f.read(), b'contentappendix')
|
self.assertEqual(f.read(), b'contentappendix')
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
f.name
|
||||||
self.assertRaises(io.UnsupportedOperation, f.fileno)
|
self.assertRaises(io.UnsupportedOperation, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
f.fileno()
|
f.name
|
||||||
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
|
||||||
def testOpenFileWithIntName(self):
|
def testOpenFileWithIntName(self):
|
||||||
fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
|
fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
|
||||||
with open(fd, 'wb') as raw:
|
with open(fd, 'wb') as raw:
|
||||||
with BZ2File(raw, 'wb') as f:
|
with BZ2File(raw, 'wb') as f:
|
||||||
f.write(b'content')
|
f.write(b'content')
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
|
||||||
fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_APPEND)
|
fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_APPEND)
|
||||||
with open(fd, 'ab') as raw:
|
with open(fd, 'ab') as raw:
|
||||||
with BZ2File(raw, 'ab') as f:
|
with BZ2File(raw, 'ab') as f:
|
||||||
f.write(b'appendix')
|
f.write(b'appendix')
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
|
||||||
fd = os.open(self.filename, os.O_RDONLY)
|
fd = os.open(self.filename, os.O_RDONLY)
|
||||||
with open(fd, 'rb') as raw:
|
with open(fd, 'rb') as raw:
|
||||||
with BZ2File(raw, 'rb') as f:
|
with BZ2File(raw, 'rb') as f:
|
||||||
self.assertEqual(f.read(), b'contentappendix')
|
self.assertEqual(f.read(), b'contentappendix')
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
f.fileno()
|
f.name
|
||||||
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
|
||||||
def testOpenBytesFilename(self):
|
def testOpenBytesFilename(self):
|
||||||
str_filename = self.filename
|
str_filename = self.filename
|
||||||
bytes_filename = os.fsencode(str_filename)
|
bytes_filename = os.fsencode(str_filename)
|
||||||
with BZ2File(bytes_filename, "wb") as f:
|
with BZ2File(bytes_filename, "wb") as f:
|
||||||
f.write(self.DATA)
|
f.write(self.DATA)
|
||||||
|
self.assertEqual(f.name, bytes_filename)
|
||||||
with BZ2File(bytes_filename, "rb") as f:
|
with BZ2File(bytes_filename, "rb") as f:
|
||||||
self.assertEqual(f.read(), self.DATA)
|
self.assertEqual(f.read(), self.DATA)
|
||||||
|
self.assertEqual(f.name, bytes_filename)
|
||||||
# Sanity check that we are actually operating on the right file.
|
# Sanity check that we are actually operating on the right file.
|
||||||
with BZ2File(str_filename, "rb") as f:
|
with BZ2File(str_filename, "rb") as f:
|
||||||
self.assertEqual(f.read(), self.DATA)
|
self.assertEqual(f.read(), self.DATA)
|
||||||
|
self.assertEqual(f.name, str_filename)
|
||||||
|
|
||||||
def testOpenPathLikeFilename(self):
|
def testOpenPathLikeFilename(self):
|
||||||
filename = FakePath(self.filename)
|
filename = FakePath(self.filename)
|
||||||
with BZ2File(filename, "wb") as f:
|
with BZ2File(filename, "wb") as f:
|
||||||
f.write(self.DATA)
|
f.write(self.DATA)
|
||||||
|
self.assertEqual(f.name, self.filename)
|
||||||
with BZ2File(filename, "rb") as f:
|
with BZ2File(filename, "rb") as f:
|
||||||
self.assertEqual(f.read(), self.DATA)
|
self.assertEqual(f.read(), self.DATA)
|
||||||
|
self.assertEqual(f.name, self.filename)
|
||||||
|
|
||||||
def testDecompressLimited(self):
|
def testDecompressLimited(self):
|
||||||
"""Decompressed data buffering should be limited"""
|
"""Decompressed data buffering should be limited"""
|
||||||
|
@ -701,6 +759,9 @@ class BZ2FileTest(BaseTest):
|
||||||
with BZ2File(bio) as bz2f:
|
with BZ2File(bio) as bz2f:
|
||||||
self.assertRaises(TypeError, bz2f.read, float())
|
self.assertRaises(TypeError, bz2f.read, float())
|
||||||
self.assertEqual(bz2f.read(), self.TEXT)
|
self.assertEqual(bz2f.read(), self.TEXT)
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
bz2.name
|
||||||
|
self.assertEqual(bz2f.mode, 'rb')
|
||||||
self.assertFalse(bio.closed)
|
self.assertFalse(bio.closed)
|
||||||
|
|
||||||
def testPeekBytesIO(self):
|
def testPeekBytesIO(self):
|
||||||
|
@ -716,6 +777,9 @@ class BZ2FileTest(BaseTest):
|
||||||
with BZ2File(bio, "w") as bz2f:
|
with BZ2File(bio, "w") as bz2f:
|
||||||
self.assertRaises(TypeError, bz2f.write)
|
self.assertRaises(TypeError, bz2f.write)
|
||||||
bz2f.write(self.TEXT)
|
bz2f.write(self.TEXT)
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
bz2.name
|
||||||
|
self.assertEqual(bz2f.mode, 'wb')
|
||||||
self.assertEqual(ext_decompress(bio.getvalue()), self.TEXT)
|
self.assertEqual(ext_decompress(bio.getvalue()), self.TEXT)
|
||||||
self.assertFalse(bio.closed)
|
self.assertFalse(bio.closed)
|
||||||
|
|
||||||
|
|
|
@ -587,6 +587,8 @@ class TestGzip(BaseTest):
|
||||||
self.assertRaises(AttributeError, f.fileno)
|
self.assertRaises(AttributeError, f.fileno)
|
||||||
|
|
||||||
def test_fileobj_mode(self):
|
def test_fileobj_mode(self):
|
||||||
|
self.assertEqual(gzip.READ, 'rb')
|
||||||
|
self.assertEqual(gzip.WRITE, 'wb')
|
||||||
gzip.GzipFile(self.filename, "wb").close()
|
gzip.GzipFile(self.filename, "wb").close()
|
||||||
with open(self.filename, "r+b") as f:
|
with open(self.filename, "r+b") as f:
|
||||||
with gzip.GzipFile(fileobj=f, mode='r') as g:
|
with gzip.GzipFile(fileobj=f, mode='r') as g:
|
||||||
|
|
|
@ -551,19 +551,25 @@ class FileTestCase(unittest.TestCase):
|
||||||
with TempFile(filename, COMPRESSED_XZ):
|
with TempFile(filename, COMPRESSED_XZ):
|
||||||
with LZMAFile(filename) as f:
|
with LZMAFile(filename) as f:
|
||||||
self.assertEqual(f.read(), INPUT)
|
self.assertEqual(f.read(), INPUT)
|
||||||
|
self.assertEqual(f.name, TESTFN)
|
||||||
with LZMAFile(filename, "a") as f:
|
with LZMAFile(filename, "a") as f:
|
||||||
f.write(INPUT)
|
f.write(INPUT)
|
||||||
|
self.assertEqual(f.name, TESTFN)
|
||||||
with LZMAFile(filename) as f:
|
with LZMAFile(filename) as f:
|
||||||
self.assertEqual(f.read(), INPUT * 2)
|
self.assertEqual(f.read(), INPUT * 2)
|
||||||
|
self.assertEqual(f.name, TESTFN)
|
||||||
|
|
||||||
def test_init_with_filename(self):
|
def test_init_with_filename(self):
|
||||||
with TempFile(TESTFN, COMPRESSED_XZ):
|
with TempFile(TESTFN, COMPRESSED_XZ):
|
||||||
with LZMAFile(TESTFN) as f:
|
with LZMAFile(TESTFN) as f:
|
||||||
pass
|
self.assertEqual(f.name, TESTFN)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
with LZMAFile(TESTFN, "w") as f:
|
with LZMAFile(TESTFN, "w") as f:
|
||||||
pass
|
self.assertEqual(f.name, TESTFN)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
with LZMAFile(TESTFN, "a") as f:
|
with LZMAFile(TESTFN, "a") as f:
|
||||||
pass
|
self.assertEqual(f.name, TESTFN)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
|
|
||||||
def test_init_mode(self):
|
def test_init_mode(self):
|
||||||
with TempFile(TESTFN):
|
with TempFile(TESTFN):
|
||||||
|
@ -586,6 +592,7 @@ class FileTestCase(unittest.TestCase):
|
||||||
unlink(TESTFN)
|
unlink(TESTFN)
|
||||||
with LZMAFile(TESTFN, mode) as f:
|
with LZMAFile(TESTFN, mode) as f:
|
||||||
pass
|
pass
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
with self.assertRaises(FileExistsError):
|
with self.assertRaises(FileExistsError):
|
||||||
LZMAFile(TESTFN, mode)
|
LZMAFile(TESTFN, mode)
|
||||||
|
|
||||||
|
@ -865,13 +872,18 @@ class FileTestCase(unittest.TestCase):
|
||||||
with LZMAFile(TESTFN) as f:
|
with LZMAFile(TESTFN) as f:
|
||||||
self.assertEqual(f.read(), INPUT)
|
self.assertEqual(f.read(), INPUT)
|
||||||
self.assertEqual(f.read(), b"")
|
self.assertEqual(f.read(), b"")
|
||||||
|
self.assertEqual(f.name, TESTFN)
|
||||||
self.assertIsInstance(f.fileno(), int)
|
self.assertIsInstance(f.fileno(), int)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertIs(f.readable(), True)
|
self.assertIs(f.readable(), True)
|
||||||
self.assertIs(f.writable(), False)
|
self.assertIs(f.writable(), False)
|
||||||
self.assertIs(f.seekable(), True)
|
self.assertIs(f.seekable(), True)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -882,6 +894,7 @@ class FileTestCase(unittest.TestCase):
|
||||||
with LZMAFile(bytes_filename) as f:
|
with LZMAFile(bytes_filename) as f:
|
||||||
self.assertEqual(f.read(), INPUT)
|
self.assertEqual(f.read(), INPUT)
|
||||||
self.assertEqual(f.read(), b"")
|
self.assertEqual(f.read(), b"")
|
||||||
|
self.assertEqual(f.name, bytes_filename)
|
||||||
|
|
||||||
def test_read_from_fileobj(self):
|
def test_read_from_fileobj(self):
|
||||||
with TempFile(TESTFN, COMPRESSED_XZ):
|
with TempFile(TESTFN, COMPRESSED_XZ):
|
||||||
|
@ -889,13 +902,18 @@ class FileTestCase(unittest.TestCase):
|
||||||
with LZMAFile(raw) as f:
|
with LZMAFile(raw) as f:
|
||||||
self.assertEqual(f.read(), INPUT)
|
self.assertEqual(f.read(), INPUT)
|
||||||
self.assertEqual(f.read(), b"")
|
self.assertEqual(f.read(), b"")
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertIs(f.readable(), True)
|
self.assertIs(f.readable(), True)
|
||||||
self.assertIs(f.writable(), False)
|
self.assertIs(f.writable(), False)
|
||||||
self.assertIs(f.seekable(), True)
|
self.assertIs(f.seekable(), True)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -907,13 +925,18 @@ class FileTestCase(unittest.TestCase):
|
||||||
with LZMAFile(raw) as f:
|
with LZMAFile(raw) as f:
|
||||||
self.assertEqual(f.read(), INPUT)
|
self.assertEqual(f.read(), INPUT)
|
||||||
self.assertEqual(f.read(), b"")
|
self.assertEqual(f.read(), b"")
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertIs(f.readable(), True)
|
self.assertIs(f.readable(), True)
|
||||||
self.assertIs(f.writable(), False)
|
self.assertIs(f.writable(), False)
|
||||||
self.assertIs(f.seekable(), True)
|
self.assertIs(f.seekable(), True)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'rb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -1045,6 +1068,8 @@ class FileTestCase(unittest.TestCase):
|
||||||
with BytesIO() as dst:
|
with BytesIO() as dst:
|
||||||
with LZMAFile(dst, "w") as f:
|
with LZMAFile(dst, "w") as f:
|
||||||
f.write(INPUT)
|
f.write(INPUT)
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
f.name
|
||||||
expected = lzma.compress(INPUT)
|
expected = lzma.compress(INPUT)
|
||||||
self.assertEqual(dst.getvalue(), expected)
|
self.assertEqual(dst.getvalue(), expected)
|
||||||
with BytesIO() as dst:
|
with BytesIO() as dst:
|
||||||
|
@ -1081,23 +1106,31 @@ class FileTestCase(unittest.TestCase):
|
||||||
with BytesIO() as dst:
|
with BytesIO() as dst:
|
||||||
with LZMAFile(dst, "w") as f:
|
with LZMAFile(dst, "w") as f:
|
||||||
f.write(part1)
|
f.write(part1)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
with LZMAFile(dst, "a") as f:
|
with LZMAFile(dst, "a") as f:
|
||||||
f.write(part2)
|
f.write(part2)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
with LZMAFile(dst, "a") as f:
|
with LZMAFile(dst, "a") as f:
|
||||||
f.write(part3)
|
f.write(part3)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertEqual(dst.getvalue(), expected)
|
self.assertEqual(dst.getvalue(), expected)
|
||||||
|
|
||||||
def test_write_to_file(self):
|
def test_write_to_file(self):
|
||||||
try:
|
try:
|
||||||
with LZMAFile(TESTFN, "w") as f:
|
with LZMAFile(TESTFN, "w") as f:
|
||||||
f.write(INPUT)
|
f.write(INPUT)
|
||||||
|
self.assertEqual(f.name, TESTFN)
|
||||||
self.assertIsInstance(f.fileno(), int)
|
self.assertIsInstance(f.fileno(), int)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertIs(f.readable(), False)
|
self.assertIs(f.readable(), False)
|
||||||
self.assertIs(f.writable(), True)
|
self.assertIs(f.writable(), True)
|
||||||
self.assertIs(f.seekable(), False)
|
self.assertIs(f.seekable(), False)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -1113,6 +1146,7 @@ class FileTestCase(unittest.TestCase):
|
||||||
try:
|
try:
|
||||||
with LZMAFile(bytes_filename, "w") as f:
|
with LZMAFile(bytes_filename, "w") as f:
|
||||||
f.write(INPUT)
|
f.write(INPUT)
|
||||||
|
self.assertEqual(f.name, bytes_filename)
|
||||||
expected = lzma.compress(INPUT)
|
expected = lzma.compress(INPUT)
|
||||||
with open(TESTFN, "rb") as f:
|
with open(TESTFN, "rb") as f:
|
||||||
self.assertEqual(f.read(), expected)
|
self.assertEqual(f.read(), expected)
|
||||||
|
@ -1124,13 +1158,18 @@ class FileTestCase(unittest.TestCase):
|
||||||
with open(TESTFN, "wb") as raw:
|
with open(TESTFN, "wb") as raw:
|
||||||
with LZMAFile(raw, "w") as f:
|
with LZMAFile(raw, "w") as f:
|
||||||
f.write(INPUT)
|
f.write(INPUT)
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertIs(f.readable(), False)
|
self.assertIs(f.readable(), False)
|
||||||
self.assertIs(f.writable(), True)
|
self.assertIs(f.writable(), True)
|
||||||
self.assertIs(f.seekable(), False)
|
self.assertIs(f.seekable(), False)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -1147,13 +1186,18 @@ class FileTestCase(unittest.TestCase):
|
||||||
with open(fd, 'wb') as raw:
|
with open(fd, 'wb') as raw:
|
||||||
with LZMAFile(raw, "w") as f:
|
with LZMAFile(raw, "w") as f:
|
||||||
f.write(INPUT)
|
f.write(INPUT)
|
||||||
|
self.assertEqual(f.name, raw.name)
|
||||||
self.assertEqual(f.fileno(), raw.fileno())
|
self.assertEqual(f.fileno(), raw.fileno())
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertIs(f.readable(), False)
|
self.assertIs(f.readable(), False)
|
||||||
self.assertIs(f.writable(), True)
|
self.assertIs(f.writable(), True)
|
||||||
self.assertIs(f.seekable(), False)
|
self.assertIs(f.seekable(), False)
|
||||||
self.assertIs(f.closed, False)
|
self.assertIs(f.closed, False)
|
||||||
self.assertIs(f.closed, True)
|
self.assertIs(f.closed, True)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
f.name
|
||||||
self.assertRaises(ValueError, f.fileno)
|
self.assertRaises(ValueError, f.fileno)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
self.assertRaises(ValueError, f.readable)
|
self.assertRaises(ValueError, f.readable)
|
||||||
self.assertRaises(ValueError, f.writable)
|
self.assertRaises(ValueError, f.writable)
|
||||||
self.assertRaises(ValueError, f.seekable)
|
self.assertRaises(ValueError, f.seekable)
|
||||||
|
@ -1172,10 +1216,13 @@ class FileTestCase(unittest.TestCase):
|
||||||
try:
|
try:
|
||||||
with LZMAFile(TESTFN, "w") as f:
|
with LZMAFile(TESTFN, "w") as f:
|
||||||
f.write(part1)
|
f.write(part1)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
with LZMAFile(TESTFN, "a") as f:
|
with LZMAFile(TESTFN, "a") as f:
|
||||||
f.write(part2)
|
f.write(part2)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
with LZMAFile(TESTFN, "a") as f:
|
with LZMAFile(TESTFN, "a") as f:
|
||||||
f.write(part3)
|
f.write(part3)
|
||||||
|
self.assertEqual(f.mode, 'wb')
|
||||||
with open(TESTFN, "rb") as f:
|
with open(TESTFN, "rb") as f:
|
||||||
self.assertEqual(f.read(), expected)
|
self.assertEqual(f.read(), expected)
|
||||||
finally:
|
finally:
|
||||||
|
@ -1373,11 +1420,13 @@ class OpenTestCase(unittest.TestCase):
|
||||||
with TempFile(filename):
|
with TempFile(filename):
|
||||||
with lzma.open(filename, "wb") as f:
|
with lzma.open(filename, "wb") as f:
|
||||||
f.write(INPUT)
|
f.write(INPUT)
|
||||||
|
self.assertEqual(f.name, TESTFN)
|
||||||
with open(filename, "rb") as f:
|
with open(filename, "rb") as f:
|
||||||
file_data = lzma.decompress(f.read())
|
file_data = lzma.decompress(f.read())
|
||||||
self.assertEqual(file_data, INPUT)
|
self.assertEqual(file_data, INPUT)
|
||||||
with lzma.open(filename, "rb") as f:
|
with lzma.open(filename, "rb") as f:
|
||||||
self.assertEqual(f.read(), INPUT)
|
self.assertEqual(f.read(), INPUT)
|
||||||
|
self.assertEqual(f.name, TESTFN)
|
||||||
|
|
||||||
def test_bad_params(self):
|
def test_bad_params(self):
|
||||||
# Test invalid parameter combinations.
|
# Test invalid parameter combinations.
|
||||||
|
|
|
@ -513,6 +513,7 @@ class CommonReadTest(ReadTest):
|
||||||
with self.tar.extractfile(file) as fobj:
|
with self.tar.extractfile(file) as fobj:
|
||||||
self.assertEqual(fobj.name, 'ustar/regtype')
|
self.assertEqual(fobj.name, 'ustar/regtype')
|
||||||
self.assertRaises(AttributeError, fobj.fileno)
|
self.assertRaises(AttributeError, fobj.fileno)
|
||||||
|
self.assertEqual(fobj.mode, 'rb')
|
||||||
self.assertIs(fobj.readable(), True)
|
self.assertIs(fobj.readable(), True)
|
||||||
self.assertIs(fobj.writable(), False)
|
self.assertIs(fobj.writable(), False)
|
||||||
if self.is_stream:
|
if self.is_stream:
|
||||||
|
@ -523,6 +524,7 @@ class CommonReadTest(ReadTest):
|
||||||
self.assertIs(fobj.closed, True)
|
self.assertIs(fobj.closed, True)
|
||||||
self.assertEqual(fobj.name, 'ustar/regtype')
|
self.assertEqual(fobj.name, 'ustar/regtype')
|
||||||
self.assertRaises(AttributeError, fobj.fileno)
|
self.assertRaises(AttributeError, fobj.fileno)
|
||||||
|
self.assertEqual(fobj.mode, 'rb')
|
||||||
self.assertIs(fobj.readable(), True)
|
self.assertIs(fobj.readable(), True)
|
||||||
self.assertIs(fobj.writable(), False)
|
self.assertIs(fobj.writable(), False)
|
||||||
if self.is_stream:
|
if self.is_stream:
|
||||||
|
@ -533,11 +535,8 @@ class CommonReadTest(ReadTest):
|
||||||
|
|
||||||
class MiscReadTestBase(CommonReadTest):
|
class MiscReadTestBase(CommonReadTest):
|
||||||
is_stream = False
|
is_stream = False
|
||||||
def requires_name_attribute(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_no_name_argument(self):
|
def test_no_name_argument(self):
|
||||||
self.requires_name_attribute()
|
|
||||||
with open(self.tarname, "rb") as fobj:
|
with open(self.tarname, "rb") as fobj:
|
||||||
self.assertIsInstance(fobj.name, str)
|
self.assertIsInstance(fobj.name, str)
|
||||||
with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
|
with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
|
||||||
|
@ -570,7 +569,6 @@ class MiscReadTestBase(CommonReadTest):
|
||||||
self.assertIsNone(tar.name)
|
self.assertIsNone(tar.name)
|
||||||
|
|
||||||
def test_bytes_name_attribute(self):
|
def test_bytes_name_attribute(self):
|
||||||
self.requires_name_attribute()
|
|
||||||
tarname = os.fsencode(self.tarname)
|
tarname = os.fsencode(self.tarname)
|
||||||
with open(tarname, 'rb') as fobj:
|
with open(tarname, 'rb') as fobj:
|
||||||
self.assertIsInstance(fobj.name, bytes)
|
self.assertIsInstance(fobj.name, bytes)
|
||||||
|
@ -839,12 +837,10 @@ class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase):
|
class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase):
|
||||||
def requires_name_attribute(self):
|
pass
|
||||||
self.skipTest("BZ2File have no name attribute")
|
|
||||||
|
|
||||||
class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase):
|
class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase):
|
||||||
def requires_name_attribute(self):
|
pass
|
||||||
self.skipTest("LZMAFile have no name attribute")
|
|
||||||
|
|
||||||
|
|
||||||
class StreamReadTest(CommonReadTest, unittest.TestCase):
|
class StreamReadTest(CommonReadTest, unittest.TestCase):
|
||||||
|
|
|
@ -389,7 +389,6 @@ class AbstractTestsWithSourceFile:
|
||||||
with zipfp.open(fname) as zipopen:
|
with zipfp.open(fname) as zipopen:
|
||||||
r = repr(zipopen)
|
r = repr(zipopen)
|
||||||
self.assertIn('name=%r' % fname, r)
|
self.assertIn('name=%r' % fname, r)
|
||||||
self.assertIn("mode='r'", r)
|
|
||||||
if self.compression != zipfile.ZIP_STORED:
|
if self.compression != zipfile.ZIP_STORED:
|
||||||
self.assertIn('compress_type=', r)
|
self.assertIn('compress_type=', r)
|
||||||
self.assertIn('[closed]', repr(zipopen))
|
self.assertIn('[closed]', repr(zipopen))
|
||||||
|
@ -455,14 +454,14 @@ class AbstractTestsWithSourceFile:
|
||||||
with zipfp.open(fname) as fid:
|
with zipfp.open(fname) as fid:
|
||||||
self.assertEqual(fid.name, fname)
|
self.assertEqual(fid.name, fname)
|
||||||
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
||||||
self.assertEqual(fid.mode, 'r')
|
self.assertEqual(fid.mode, 'rb')
|
||||||
self.assertIs(fid.readable(), True)
|
self.assertIs(fid.readable(), True)
|
||||||
self.assertIs(fid.writable(), False)
|
self.assertIs(fid.writable(), False)
|
||||||
self.assertIs(fid.seekable(), True)
|
self.assertIs(fid.seekable(), True)
|
||||||
self.assertIs(fid.closed, False)
|
self.assertIs(fid.closed, False)
|
||||||
self.assertIs(fid.closed, True)
|
self.assertIs(fid.closed, True)
|
||||||
self.assertEqual(fid.name, fname)
|
self.assertEqual(fid.name, fname)
|
||||||
self.assertEqual(fid.mode, 'r')
|
self.assertEqual(fid.mode, 'rb')
|
||||||
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
||||||
self.assertRaises(ValueError, fid.readable)
|
self.assertRaises(ValueError, fid.readable)
|
||||||
self.assertIs(fid.writable(), False)
|
self.assertIs(fid.writable(), False)
|
||||||
|
@ -1308,12 +1307,16 @@ class AbstractWriterTests:
|
||||||
fname = "somefile.txt"
|
fname = "somefile.txt"
|
||||||
with zipfile.ZipFile(TESTFN2, mode="w", compression=self.compression) as zipfp:
|
with zipfile.ZipFile(TESTFN2, mode="w", compression=self.compression) as zipfp:
|
||||||
with zipfp.open(fname, 'w') as fid:
|
with zipfp.open(fname, 'w') as fid:
|
||||||
|
self.assertEqual(fid.name, fname)
|
||||||
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
||||||
|
self.assertEqual(fid.mode, 'wb')
|
||||||
self.assertIs(fid.readable(), False)
|
self.assertIs(fid.readable(), False)
|
||||||
self.assertIs(fid.writable(), True)
|
self.assertIs(fid.writable(), True)
|
||||||
self.assertIs(fid.seekable(), False)
|
self.assertIs(fid.seekable(), False)
|
||||||
self.assertIs(fid.closed, False)
|
self.assertIs(fid.closed, False)
|
||||||
self.assertIs(fid.closed, True)
|
self.assertIs(fid.closed, True)
|
||||||
|
self.assertEqual(fid.name, fname)
|
||||||
|
self.assertEqual(fid.mode, 'wb')
|
||||||
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
self.assertRaises(io.UnsupportedOperation, fid.fileno)
|
||||||
self.assertIs(fid.readable(), False)
|
self.assertIs(fid.readable(), False)
|
||||||
self.assertIs(fid.writable(), True)
|
self.assertIs(fid.writable(), True)
|
||||||
|
|
|
@ -940,7 +940,7 @@ class ZipExtFile(io.BufferedIOBase):
|
||||||
result = ['<%s.%s' % (self.__class__.__module__,
|
result = ['<%s.%s' % (self.__class__.__module__,
|
||||||
self.__class__.__qualname__)]
|
self.__class__.__qualname__)]
|
||||||
if not self.closed:
|
if not self.closed:
|
||||||
result.append(' name=%r mode=%r' % (self.name, self.mode))
|
result.append(' name=%r' % (self.name,))
|
||||||
if self._compress_type != ZIP_STORED:
|
if self._compress_type != ZIP_STORED:
|
||||||
result.append(' compress_type=%s' %
|
result.append(' compress_type=%s' %
|
||||||
compressor_names.get(self._compress_type,
|
compressor_names.get(self._compress_type,
|
||||||
|
@ -1217,6 +1217,14 @@ class _ZipWriteFile(io.BufferedIOBase):
|
||||||
def _fileobj(self):
|
def _fileobj(self):
|
||||||
return self._zipfile.fp
|
return self._zipfile.fp
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._zinfo.filename
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
return 'wb'
|
||||||
|
|
||||||
def writable(self):
|
def writable(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -1687,7 +1695,7 @@ class ZipFile:
|
||||||
else:
|
else:
|
||||||
pwd = None
|
pwd = None
|
||||||
|
|
||||||
return ZipExtFile(zef_file, mode, zinfo, pwd, True)
|
return ZipExtFile(zef_file, mode + 'b', zinfo, pwd, True)
|
||||||
except:
|
except:
|
||||||
zef_file.close()
|
zef_file.close()
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
Added :attr:`!name` and :attr:`!mode` attributes for compressed and archived
|
||||||
|
file-like objects in modules :mod:`bz2`, :mod:`lzma`, :mod:`tarfile` and
|
||||||
|
:mod:`zipfile`. The value of the :attr:`!mode` attribute of
|
||||||
|
:class:`gzip.GzipFile` was changed from integer (``1`` or ``2``) to string
|
||||||
|
(``'rb'`` or ``'wb'``). The value of the :attr:`!mode` attribute of the
|
||||||
|
readable file-like object returned by :meth:`zipfile.ZipFile.open` was
|
||||||
|
changed from ``'r'`` to ``'rb'``.
|
Loading…
Reference in New Issue