Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitce79274

Browse files
gh-131492,gh-131461: handle exceptions in GzipFile constructor while owning resources (#131462)
Co-authored-by: Victor Stinner <vstinner@python.org>
1 parentf53e7de commitce79274

File tree

4 files changed

+68
-52
lines changed

4 files changed

+68
-52
lines changed

‎Lib/gzip.py

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -202,51 +202,58 @@ def __init__(self, filename=None, mode=None,
202202
raiseValueError("Invalid mode: {!r}".format(mode))
203203
ifmodeand'b'notinmode:
204204
mode+='b'
205-
iffileobjisNone:
206-
fileobj=self.myfileobj=builtins.open(filename,modeor'rb')
207-
iffilenameisNone:
208-
filename=getattr(fileobj,'name','')
209-
ifnotisinstance(filename, (str,bytes)):
210-
filename=''
211-
else:
212-
filename=os.fspath(filename)
213-
origmode=mode
214-
ifmodeisNone:
215-
mode=getattr(fileobj,'mode','rb')
216-
217-
218-
ifmode.startswith('r'):
219-
self.mode=READ
220-
raw=_GzipReader(fileobj)
221-
self._buffer=io.BufferedReader(raw)
222-
self.name=filename
223-
224-
elifmode.startswith(('w','a','x')):
225-
iforigmodeisNone:
226-
importwarnings
227-
warnings.warn(
228-
"GzipFile was opened for writing, but this will "
229-
"change in future Python releases. "
230-
"Specify the mode argument for opening it for writing.",
231-
FutureWarning,2)
232-
self.mode=WRITE
233-
self._init_write(filename)
234-
self.compress=zlib.compressobj(compresslevel,
235-
zlib.DEFLATED,
236-
-zlib.MAX_WBITS,
237-
zlib.DEF_MEM_LEVEL,
238-
0)
239-
self._write_mtime=mtime
240-
self._buffer_size=_WRITE_BUFFER_SIZE
241-
self._buffer=io.BufferedWriter(_WriteBufferStream(self),
242-
buffer_size=self._buffer_size)
243-
else:
244-
raiseValueError("Invalid mode: {!r}".format(mode))
245205

246-
self.fileobj=fileobj
206+
try:
207+
iffileobjisNone:
208+
fileobj=self.myfileobj=builtins.open(filename,modeor'rb')
209+
iffilenameisNone:
210+
filename=getattr(fileobj,'name','')
211+
ifnotisinstance(filename, (str,bytes)):
212+
filename=''
213+
else:
214+
filename=os.fspath(filename)
215+
origmode=mode
216+
ifmodeisNone:
217+
mode=getattr(fileobj,'mode','rb')
218+
219+
220+
ifmode.startswith('r'):
221+
self.mode=READ
222+
raw=_GzipReader(fileobj)
223+
self._buffer=io.BufferedReader(raw)
224+
self.name=filename
225+
226+
elifmode.startswith(('w','a','x')):
227+
iforigmodeisNone:
228+
importwarnings
229+
warnings.warn(
230+
"GzipFile was opened for writing, but this will "
231+
"change in future Python releases. "
232+
"Specify the mode argument for opening it for writing.",
233+
FutureWarning,2)
234+
self.mode=WRITE
235+
self._init_write(filename)
236+
self.compress=zlib.compressobj(compresslevel,
237+
zlib.DEFLATED,
238+
-zlib.MAX_WBITS,
239+
zlib.DEF_MEM_LEVEL,
240+
0)
241+
self._write_mtime=mtime
242+
self._buffer_size=_WRITE_BUFFER_SIZE
243+
self._buffer=io.BufferedWriter(_WriteBufferStream(self),
244+
buffer_size=self._buffer_size)
245+
else:
246+
raiseValueError("Invalid mode: {!r}".format(mode))
247+
248+
self.fileobj=fileobj
247249

248-
ifself.mode==WRITE:
249-
self._write_gzip_header(compresslevel)
250+
ifself.mode==WRITE:
251+
self._write_gzip_header(compresslevel)
252+
except:
253+
# Avoid a ResourceWarning if the write fails,
254+
# eg read-only file or KeyboardInterrupt
255+
self._close()
256+
raise
250257

251258
@property
252259
defmtime(self):
@@ -387,11 +394,14 @@ def close(self):
387394
elifself.mode==READ:
388395
self._buffer.close()
389396
finally:
390-
self.fileobj=None
391-
myfileobj=self.myfileobj
392-
ifmyfileobj:
393-
self.myfileobj=None
394-
myfileobj.close()
397+
self._close()
398+
399+
def_close(self):
400+
self.fileobj=None
401+
myfileobj=self.myfileobj
402+
ifmyfileobjisnotNone:
403+
self.myfileobj=None
404+
myfileobj.close()
395405

396406
defflush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
397407
self._check_not_closed()

‎Lib/test/test_tarfile.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
fromtestimportsupport
2020
fromtest.supportimportos_helper
2121
fromtest.supportimportscript_helper
22+
fromtest.supportimportwarnings_helper
2223

2324
# Check for our compression modules.
2425
try:
@@ -1638,10 +1639,13 @@ def write(self, data):
16381639
raiseexctype
16391640

16401641
f=BadFile()
1641-
withself.assertRaises(exctype):
1642-
tar=tarfile.open(tmpname,self.mode,fileobj=f,
1643-
format=tarfile.PAX_FORMAT,
1644-
pax_headers={'non':'empty'})
1642+
with (
1643+
warnings_helper.check_no_resource_warning(self),
1644+
self.assertRaises(exctype),
1645+
):
1646+
tarfile.open(tmpname,self.mode,fileobj=f,
1647+
format=tarfile.PAX_FORMAT,
1648+
pax_headers={'non':'empty'})
16451649
self.assertFalse(f.closed)
16461650

16471651
deftest_missing_fileobj(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix:exc:`ResourceWarning` when constructing a:class:`gzip.GzipFile` in write mode with a broken file object.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a resource leak when constructing a:class:`gzip.GzipFile` with a filename fails, for example when passing an invalid ``compresslevel``.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp