https://github.com/python/cpython/commit/ff287a72de43e7fc6517aba9049cb23470e000b2
commit: ff287a72de43e7fc6517aba9049cb23470e000b2
branch: main
author: Michiel W. Beijen <[email protected]>
committer: encukou <[email protected]>
date: 2026-03-17T18:01:18+01:00
summary:
gh-144975: Fix wave.Wave_write.setframerate() validation order (GH-144976)
Validate the frame rate after rounding to an integer, not before.
This prevents values like 0.5 from passing validation (0.5 > 0)
but then rounding to 0, which would cause a confusing delayed error
"sampling rate not specified" when writing frames.
With this fix, setframerate(0.5) immediately raises "bad frame rate",
providing clear feedback at the point of the error.
files:
A Misc/NEWS.d/next/Library/2026-02-18-21-45-00.gh-issue-144975.Ab3XyZ.rst
M Lib/test/test_wave.py
M Lib/wave.py
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.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]