Skip to content

Commit f4f3f19

Browse files
committed
gh-136523: fix Wave_write.__del__ raise after wb open
1 parent 49365bd commit f4f3f19

3 files changed

Lines changed: 42 additions & 6 deletions

File tree

Lib/test/support/os_helper.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,26 @@ def make_bad_fd():
169169
unlink(TESTFN)
170170

171171

172+
@contextlib.contextmanager
173+
def unwritable_filepath():
174+
"""
175+
Create a filepath that is not writable by the current user.
176+
"""
177+
import tempfile
178+
fd, path = tempfile.mkstemp()
179+
original_permissions = stat.S_IMODE(os.lstat(path).st_mode)
180+
os.close(fd)
181+
182+
try:
183+
os.chmod(path, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
184+
yield path
185+
finally:
186+
try:
187+
os.chmod(path, original_permissions)
188+
os.remove(path)
189+
except OSError as e:
190+
pass
191+
172192
_can_symlink = None
173193

174194

Lib/test/test_wave.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22
from test import audiotests
33
from test import support
4+
from test.support.os_helper import unwritable_filepath
45
import io
56
import struct
67
import sys
@@ -196,6 +197,21 @@ def test_read_wrong_sample_width(self):
196197
with self.assertRaisesRegex(wave.Error, 'bad sample width'):
197198
wave.open(io.BytesIO(b))
198199

200+
def test_write_to_protected_file(self):
201+
# gh-136523: Wave_write.__del__ should not throw
202+
stderr = io.StringIO()
203+
sys.stderr = stderr
204+
try:
205+
try:
206+
with unwritable_filepath() as path:
207+
with wave.open(path, "wb"):
208+
pass
209+
except PermissionError:
210+
pass
211+
self.assertEqual(stderr.getvalue(), "")
212+
finally:
213+
sys.stderr = sys.__stderr__
214+
199215

200216
if __name__ == '__main__':
201217
unittest.main()

Lib/wave.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -429,15 +429,15 @@ class Wave_write:
429429

430430
def __init__(self, f):
431431
self._i_opened_the_file = None
432-
if isinstance(f, str):
433-
f = builtins.open(f, 'wb')
434-
self._i_opened_the_file = f
435432
try:
436-
self.initfp(f)
433+
if isinstance(f, str):
434+
f = builtins.open(f, 'wb')
435+
self._i_opened_the_file = f
437436
except:
438-
if self._i_opened_the_file:
439-
f.close()
437+
f = None
440438
raise
439+
finally:
440+
self.initfp(f)
441441

442442
def initfp(self, file):
443443
self._file = file

0 commit comments

Comments
 (0)