diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index 4c21f16553775c..05e7d377517798 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -207,6 +207,43 @@ def test_open_in_write_raises(self): support.gc_collect() self.assertIsNone(cm.unraisable) + @support.subTests('arg', ( + # rounds to 0, should raise: + 0.5, + 0.4, + # Negative values should still raise: + -1, + -0.5, + -0.4, + # 0 should raise: + 0, + )) + def test_setframerate_validates_rounded_values(self, arg): + """Test that setframerate that round to 0 or negative are rejected""" + with wave.open(io.BytesIO(), 'wb') as f: + f.setnchannels(1) + f.setsampwidth(2) + with self.assertRaises(wave.Error): + f.setframerate(arg) + with self.assertRaises(wave.Error): + f.close() + + @support.subTests(('arg', 'expected'), ( + (1.4, 1), + (1.5, 2), + (1.6, 2), + (44100.4, 44100), + (44100.5, 44100), + (44100.6, 44101), + )) + def test_setframerate_rounds(self, arg, expected): + """Test that setframerate is rounded""" + with wave.open(io.BytesIO(), 'wb') as f: + f.setnchannels(1) + f.setsampwidth(2) + f.setframerate(arg) + self.assertEqual(f.getframerate(), expected) + class WaveOpen(unittest.TestCase): def test_open_pathlike(self): diff --git a/Lib/wave.py b/Lib/wave.py index 25ca9ef168e8a5..841da8c49e9a2f 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -493,9 +493,10 @@ def getsampwidth(self): def setframerate(self, framerate): if self._datawritten: raise Error('cannot change parameters after starting to write') + framerate = int(round(framerate)) if framerate <= 0: raise Error('bad frame rate') - self._framerate = int(round(framerate)) + self._framerate = framerate def getframerate(self): if not self._framerate: diff --git a/Misc/NEWS.d/next/Library/2026-02-18-21-45-00.gh-issue-144975.Ab3XyZ.rst b/Misc/NEWS.d/next/Library/2026-02-18-21-45-00.gh-issue-144975.Ab3XyZ.rst new file mode 100644 index 00000000000000..37658064c2c351 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-18-21-45-00.gh-issue-144975.Ab3XyZ.rst @@ -0,0 +1,3 @@ +:meth:`wave.Wave_write.setframerate` now validates the frame rate after +rounding to an integer, preventing values like ``0.5`` from being accepted +and causing confusing errors later. Patch by Michiel Beijen.