Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 51ef89c

Browse filesBrowse files
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'.
1 parent ccda738 commit 51ef89c
Copy full SHA for 51ef89c

File tree

Expand file treeCollapse file tree

17 files changed

+246
-37
lines changed
Filter options
Expand file treeCollapse file tree

17 files changed

+246
-37
lines changed

‎Doc/library/bz2.rst

Copy file name to clipboardExpand all lines: Doc/library/bz2.rst
+14-1Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ The :mod:`bz2` module contains:
9191
and :meth:`~io.IOBase.truncate`.
9292
Iteration and the :keyword:`with` statement are supported.
9393

94-
:class:`BZ2File` also provides the following methods:
94+
:class:`BZ2File` also provides the following methods and attributes:
9595

9696
.. method:: peek([n])
9797

@@ -148,6 +148,19 @@ The :mod:`bz2` module contains:
148148

149149
.. versionadded:: 3.3
150150

151+
.. attribute:: mode
152+
153+
``'rb'`` for reading and ``'wb'`` for writing.
154+
155+
.. versionadded:: 3.13
156+
157+
.. attribute:: name
158+
159+
The bzip2 file name. Equivalent to the :attr:`~io.FileIO.name`
160+
attribute of the underlying :term:`file object`.
161+
162+
.. versionadded:: 3.13
163+
151164

152165
.. versionchanged:: 3.1
153166
Support for the :keyword:`with` statement was added.

‎Doc/library/gzip.rst

Copy file name to clipboardExpand all lines: Doc/library/gzip.rst
+11-4Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ The module defines the following items:
133133

134134
.. versionadded:: 3.2
135135

136+
.. attribute:: mode
137+
138+
``'rb'`` for reading and ``'wb'`` for writing.
139+
140+
.. versionchanged:: 3.13
141+
In previous versions it was an integer ``1`` or ``2``.
142+
136143
.. attribute:: mtime
137144

138145
When decompressing, this attribute is set to the last timestamp in the most
@@ -168,14 +175,14 @@ The module defines the following items:
168175
.. versionchanged:: 3.6
169176
Accepts a :term:`path-like object`.
170177

171-
.. versionchanged:: 3.12
172-
Remove the ``filename`` attribute, use the :attr:`~GzipFile.name`
173-
attribute instead.
174-
175178
.. deprecated:: 3.9
176179
Opening :class:`GzipFile` for writing without specifying the *mode*
177180
argument is deprecated.
178181

182+
.. versionchanged:: 3.12
183+
Remove the ``filename`` attribute, use the :attr:`~GzipFile.name`
184+
attribute instead.
185+
179186

180187
.. function:: compress(data, compresslevel=9, *, mtime=None)
181188

‎Doc/library/lzma.rst

Copy file name to clipboardExpand all lines: Doc/library/lzma.rst
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Reading and writing compressed files
104104
and :meth:`~io.IOBase.truncate`.
105105
Iteration and the :keyword:`with` statement are supported.
106106

107-
The following method is also provided:
107+
The following method and attributes are also provided:
108108

109109
.. method:: peek(size=-1)
110110

@@ -117,6 +117,20 @@ Reading and writing compressed files
117117
file object (e.g. if the :class:`LZMAFile` was constructed by passing a
118118
file object for *filename*).
119119

120+
.. attribute:: mode
121+
122+
``'rb'`` for reading and ``'wb'`` for writing.
123+
124+
.. versionadded:: 3.13
125+
126+
.. attribute:: name
127+
128+
The lzma file name. Equivalent to the :attr:`~io.FileIO.name`
129+
attribute of the underlying :term:`file object`.
130+
131+
.. versionadded:: 3.13
132+
133+
120134
.. versionchanged:: 3.4
121135
Added support for the ``"x"`` and ``"xb"`` modes.
122136

‎Doc/library/tarfile.rst

Copy file name to clipboardExpand all lines: Doc/library/tarfile.rst
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,10 @@ be finalized; only the internally used file object will be closed. See the
565565
.. versionchanged:: 3.3
566566
Return an :class:`io.BufferedReader` object.
567567

568+
.. versionchanged:: 3.13
569+
The returned :class:`io.BufferedReader` object has the :attr:`!mode`
570+
attribute which is always equal to ``'rb'``.
571+
568572
.. attribute:: TarFile.errorlevel
569573
:type: int
570574

‎Doc/library/zipfile.rst

Copy file name to clipboardExpand all lines: Doc/library/zipfile.rst
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ ZipFile Objects
301301
attempting to read or write other files in the ZIP file will raise a
302302
:exc:`ValueError`.
303303

304+
In both cases the file-like object has also attributes :attr:`!name`,
305+
which is equivalent to the name of a file within the archive, and
306+
:attr:`!mode`, which is ``'rb'`` or ``'wb'`` depending on the input mode.
307+
304308
When writing a file, if the file size is not known in advance but may exceed
305309
2 GiB, pass ``force_zip64=True`` to ensure that the header format is
306310
capable of supporting large files. If the file size is known in advance,
@@ -325,6 +329,12 @@ ZipFile Objects
325329
Calling :meth:`.open` on a closed ZipFile will raise a :exc:`ValueError`.
326330
Previously, a :exc:`RuntimeError` was raised.
327331

332+
.. versionchanged:: 3.13
333+
Added attributes :attr:`!name` and :attr:`!mode` for the writeable
334+
file-like object.
335+
The value of the :attr:`!mode` attribute for the readable file-like
336+
object was changed from ``'r'`` to ``'rb'``.
337+
328338

329339
.. method:: ZipFile.extract(member, path=None, pwd=None)
330340

‎Doc/whatsnew/3.13.rst

Copy file name to clipboardExpand all lines: Doc/whatsnew/3.13.rst
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ Other Language Changes
206206

207207
(Contributed by Victor Stinner in :gh:`114570`.)
208208

209+
* Added :attr:`!name` and :attr:`!mode` attributes for compressed
210+
and archived file-like objects in modules :mod:`bz2`, :mod:`lzma`,
211+
:mod:`tarfile` and :mod:`zipfile`.
212+
(Contributed by Serhiy Storchaka in :gh:`115961`.)
213+
209214
* Allow controlling Expat >=2.6.0 reparse deferral (:cve:`2023-52425`)
210215
by adding five new methods:
211216

@@ -1605,6 +1610,12 @@ Changes in the Python API
16051610
than directories only. Users may add a trailing slash to match only
16061611
directories.
16071612

1613+
* The value of the :attr:`!mode` attribute of :class:`gzip.GzipFile` was
1614+
changed from integer (``1`` or ``2``) to string (``'rb'`` or ``'wb'``).
1615+
The value of the :attr:`!mode` attribute of the readable file-like object
1616+
returned by :meth:`zipfile.ZipFile.open` was changed from ``'r'`` to ``'rb'``.
1617+
(Contributed by Serhiy Storchaka in :gh:`115961`.)
1618+
16081619
* :c:func:`!PyCode_GetFirstFree` is an unstable API now and has been renamed
16091620
to :c:func:`PyUnstable_Code_GetFirstFree`.
16101621
(Contributed by Bogdan Romanyuk in :gh:`115781`.)

‎Lib/bz2.py

Copy file name to clipboardExpand all lines: Lib/bz2.py
+13-5Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from _bz2 import BZ2Compressor, BZ2Decompressor
1818

1919

20-
_MODE_CLOSED = 0
20+
# Value 0 no longer used
2121
_MODE_READ = 1
2222
# Value 2 no longer used
2323
_MODE_WRITE = 3
@@ -54,7 +54,7 @@ def __init__(self, filename, mode="r", *, compresslevel=9):
5454
"""
5555
self._fp = None
5656
self._closefp = False
57-
self._mode = _MODE_CLOSED
57+
self._mode = None
5858

5959
if not (1 <= compresslevel <= 9):
6060
raise ValueError("compresslevel must be between 1 and 9")
@@ -100,7 +100,7 @@ def close(self):
100100
May be called more than once without error. Once the file is
101101
closed, any other operation on it will raise a ValueError.
102102
"""
103-
if self._mode == _MODE_CLOSED:
103+
if self.closed:
104104
return
105105
try:
106106
if self._mode == _MODE_READ:
@@ -115,13 +115,21 @@ def close(self):
115115
finally:
116116
self._fp = None
117117
self._closefp = False
118-
self._mode = _MODE_CLOSED
119118
self._buffer = None
120119

121120
@property
122121
def closed(self):
123122
"""True if this file is closed."""
124-
return self._mode == _MODE_CLOSED
123+
return self._fp is None
124+
125+
@property
126+
def name(self):
127+
self._check_not_closed()
128+
return self._fp.name
129+
130+
@property
131+
def mode(self):
132+
return 'wb' if self._mode == _MODE_WRITE else 'rb'
125133

126134
def fileno(self):
127135
"""Return the file descriptor for the underlying file."""

‎Lib/gzip.py

Copy file name to clipboardExpand all lines: Lib/gzip.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
1717

18-
READ, WRITE = 1, 2
18+
READ = 'rb'
19+
WRITE = 'wb'
1920

2021
_COMPRESS_LEVEL_FAST = 1
2122
_COMPRESS_LEVEL_TRADEOFF = 6

‎Lib/lzma.py

Copy file name to clipboardExpand all lines: Lib/lzma.py
+13-5Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import _compression
3030

3131

32-
_MODE_CLOSED = 0
32+
# Value 0 no longer used
3333
_MODE_READ = 1
3434
# Value 2 no longer used
3535
_MODE_WRITE = 3
@@ -92,7 +92,7 @@ def __init__(self, filename=None, mode="r", *,
9292
"""
9393
self._fp = None
9494
self._closefp = False
95-
self._mode = _MODE_CLOSED
95+
self._mode = None
9696

9797
if mode in ("r", "rb"):
9898
if check != -1:
@@ -137,7 +137,7 @@ def close(self):
137137
May be called more than once without error. Once the file is
138138
closed, any other operation on it will raise a ValueError.
139139
"""
140-
if self._mode == _MODE_CLOSED:
140+
if self.closed:
141141
return
142142
try:
143143
if self._mode == _MODE_READ:
@@ -153,12 +153,20 @@ def close(self):
153153
finally:
154154
self._fp = None
155155
self._closefp = False
156-
self._mode = _MODE_CLOSED
157156

158157
@property
159158
def closed(self):
160159
"""True if this file is closed."""
161-
return self._mode == _MODE_CLOSED
160+
return self._fp is None
161+
162+
@property
163+
def name(self):
164+
self._check_not_closed()
165+
return self._fp.name
166+
167+
@property
168+
def mode(self):
169+
return 'wb' if self._mode == _MODE_WRITE else 'rb'
162170

163171
def fileno(self):
164172
"""Return the file descriptor for the underlying file."""

‎Lib/tarfile.py

Copy file name to clipboardExpand all lines: Lib/tarfile.py
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,10 @@ def __init__(self, fileobj, offset, size, name, blockinfo=None):
636636
def flush(self):
637637
pass
638638

639+
@property
640+
def mode(self):
641+
return 'rb'
642+
639643
def readable(self):
640644
return True
641645

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.