Skip to content

Commit 4fd6c81

Browse files
committed
GH-132445: Allowing to reset parameters of Wave_write
1 parent 1e5798e commit 4fd6c81

File tree

4 files changed

+72
-11
lines changed

4 files changed

+72
-11
lines changed

Doc/library/wave.rst

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,20 @@ Wave_write Objects
198198

199199
Set the number of channels.
200200

201+
Raises an :exc:`wave.Error`, if the value is set after data was written.
202+
203+
.. versionchanged:: 3.14
204+
:exc:`wave.Error` is not raised, if the value is the same.
201205

202206
.. method:: setsampwidth(n)
203207

204208
Set the sample width to *n* bytes.
205209

210+
Raises an :exc:`wave.Error`, if the value is set after data was written.
211+
212+
.. versionchanged:: 3.14
213+
:exc:`wave.Error` is not raised, if the value is the same.
214+
206215

207216
.. method:: setframerate(n)
208217

@@ -212,26 +221,43 @@ Wave_write Objects
212221
A non-integral input to this method is rounded to the nearest
213222
integer.
214223

224+
Raises an :exc:`wave.Error`, if the value is set after data was written.
225+
226+
.. versionchanged:: 3.14
227+
:exc:`wave.Error` is not raised, if the value is the same.
228+
215229

216230
.. method:: setnframes(n)
217231

218232
Set the number of frames to *n*. This will be changed later if the number
219233
of frames actually written is different (this update attempt will
220234
raise an error if the output stream is not seekable).
221235

236+
Raises an :exc:`wave.Error`, if the value is set after data was written.
237+
238+
.. versionchanged:: 3.14
239+
:exc:`wave.Error` is not raised, if the value is the same.
222240

223241
.. method:: setcomptype(type, name)
224242

225243
Set the compression type and description. At the moment, only compression type
226244
``NONE`` is supported, meaning no compression.
227245

246+
Raises an Error, if the value is set after data was written.
247+
248+
.. versionchanged:: 3.14
249+
:exc:`wave.Error` is not raised, if the value is the same.
228250

229251
.. method:: setparams(tuple)
230252

231253
The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype,
232254
compname)``, with values valid for the ``set*()`` methods. Sets all
233255
parameters.
234256

257+
Raises an :exc:`wave.Error`, if the value is set after data was written.
258+
259+
.. versionchanged:: 3.14
260+
:exc:`wave.Error` is not raised, if the value is the same.
235261

236262
.. method:: tell()
237263

@@ -257,6 +283,6 @@ Wave_write Objects
257283
.. versionchanged:: 3.4
258284
Any :term:`bytes-like object` is now accepted.
259285

260-
Note that it is invalid to set any parameters after calling :meth:`writeframes`
286+
Note that it is invalid to change any parameters after calling :meth:`writeframes`
261287
or :meth:`writeframesraw`, and any attempt to do so will raise
262-
:exc:`wave.Error`.
288+
:exc:`wave.Error`, if the value is different from the current value.

Lib/test/test_wave.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,39 @@ def test_write_deprecations(self):
162162
with self.assertWarns(DeprecationWarning):
163163
self.assertIsNone(writer.getmarkers())
164164

165+
def test_setters(self):
166+
with io.BytesIO(b'') as tmpfile:
167+
with wave.open(tmpfile, 'wb') as writer:
168+
writer.setnchannels(1)
169+
writer.setsampwidth(1)
170+
writer.setframerate(1)
171+
writer.setcomptype('NONE', 'not compressed')
172+
173+
# no errors, when chaning and nothing was written
174+
writer.setnchannels(2)
175+
writer.setsampwidth(2)
176+
writer.setframerate(2)
177+
writer.setcomptype('NONE', 'uncompressed')
178+
179+
# write some frames
180+
writer.writeframes(b'\0' * 16)
181+
182+
# changeing now should result in an error
183+
with self.assertRaises(wave.Error):
184+
writer.setnchannels(1)
185+
with self.assertRaises(wave.Error):
186+
writer.setsampwidth(1)
187+
with self.assertRaises(wave.Error):
188+
writer.setframerate(1)
189+
with self.assertRaises(wave.Error):
190+
writer.setcomptype('NONE', 'other')
191+
192+
# same value, so it should not raise Error
193+
writer.setnchannels(2)
194+
writer.setsampwidth(2)
195+
writer.setframerate(2)
196+
writer.setcomptype('NONE', 'uncompressed')
197+
165198

166199
class WaveLowLevelTest(unittest.TestCase):
167200

Lib/wave.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ def __exit__(self, *args):
478478
# User visible methods.
479479
#
480480
def setnchannels(self, nchannels):
481-
if self._datawritten:
481+
if self._datawritten and self._nchannels != nchannels:
482482
raise Error('cannot change parameters after starting to write')
483483
if nchannels < 1:
484484
raise Error('bad # of channels')
@@ -490,7 +490,7 @@ def getnchannels(self):
490490
return self._nchannels
491491

492492
def setsampwidth(self, sampwidth):
493-
if self._datawritten:
493+
if self._datawritten and self._sampwidth != sampwidth:
494494
raise Error('cannot change parameters after starting to write')
495495
if sampwidth < 1 or sampwidth > 4:
496496
raise Error('bad sample width')
@@ -502,27 +502,28 @@ def getsampwidth(self):
502502
return self._sampwidth
503503

504504
def setframerate(self, framerate):
505-
if self._datawritten:
505+
rounded_framerate = int(round(framerate))
506+
if self._datawritten and self._framerate != rounded_framerate:
506507
raise Error('cannot change parameters after starting to write')
507-
if framerate <= 0:
508+
if rounded_framerate <= 0:
508509
raise Error('bad frame rate')
509-
self._framerate = int(round(framerate))
510+
self._framerate = rounded_framerate
510511

511512
def getframerate(self):
512513
if not self._framerate:
513514
raise Error('frame rate not set')
514515
return self._framerate
515516

516517
def setnframes(self, nframes):
517-
if self._datawritten:
518+
if self._datawritten and self._nframes != nframes:
518519
raise Error('cannot change parameters after starting to write')
519520
self._nframes = nframes
520521

521522
def getnframes(self):
522523
return self._nframeswritten
523524

524525
def setcomptype(self, comptype, compname):
525-
if self._datawritten:
526+
if self._datawritten and (self._comptype != comptype or self._compname != compname):
526527
raise Error('cannot change parameters after starting to write')
527528
if comptype not in ('NONE',):
528529
raise Error('unsupported compression type')
@@ -537,8 +538,8 @@ def getcompname(self):
537538

538539
def setparams(self, params):
539540
nchannels, sampwidth, framerate, nframes, comptype, compname = params
540-
if self._datawritten:
541-
raise Error('cannot change parameters after starting to write')
541+
# no check for value change required: either the properties have the same
542+
# value or they throw the exception them selfs
542543
self.setnchannels(nchannels)
543544
self.setsampwidth(sampwidth)
544545
self.setframerate(framerate)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:class:`Wave_write` setters don't raise an error anymore, if the value did not change after frames where written.

0 commit comments

Comments
 (0)