summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2022-09-23 15:08:21 (GMT)
committerGitHub <noreply@github.com>2022-09-23 15:08:21 (GMT)
commita4ac14faa5c2be433738dfbbed14b0eaa1a2399e (patch)
tree15ec10f6bde2352ebf524e97ef8df7b528dcdc9f
parentf1cca801f50a92c0affede6bc22c3c1ec211358d (diff)
downloadcpython-a4ac14faa5c2be433738dfbbed14b0eaa1a2399e.zip
cpython-a4ac14faa5c2be433738dfbbed14b0eaa1a2399e.tar.gz
cpython-a4ac14faa5c2be433738dfbbed14b0eaa1a2399e.tar.bz2
gh-77171: Fixes SubFormat check to compare the entire value. Add docs (GH-97509)
-rw-r--r--Doc/library/wave.rst7
-rw-r--r--Lib/test/test_wave.py2
-rw-r--r--Lib/wave.py18
3 files changed, 21 insertions, 6 deletions
diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst
index f63e0d3..04a28d9 100644
--- a/Doc/library/wave.rst
+++ b/Doc/library/wave.rst
@@ -12,7 +12,12 @@
--------------
The :mod:`wave` module provides a convenient interface to the WAV sound format.
-It does not support compression/decompression, but it does support mono/stereo.
+Only PCM encoded wave files are supported.
+
+.. versionchanged:: 3.12
+
+ Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the
+ extended format is ``KSDATAFORMAT_SUBTYPE_PCM``.
The :mod:`wave` module defines the following function and exception:
diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py
index 35660fd..6c33628 100644
--- a/Lib/test/test_wave.py
+++ b/Lib/test/test_wave.py
@@ -133,7 +133,7 @@ class WavePCM32Test(WaveTest, unittest.TestCase):
class MiscTestCase(unittest.TestCase):
def test__all__(self):
- not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE'}
+ not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE', 'KSDATAFORMAT_SUBTYPE_PCM'}
support.check__all__(self, wave, not_exported=not_exported)
diff --git a/Lib/wave.py b/Lib/wave.py
index e446174..d5858e5 100644
--- a/Lib/wave.py
+++ b/Lib/wave.py
@@ -84,6 +84,8 @@ class Error(Exception):
WAVE_FORMAT_PCM = 0x0001
WAVE_FORMAT_EXTENSIBLE = 0xFFFE
+# Derived from uuid.UUID("00000001-0000-0010-8000-00aa00389b71").bytes_le
+KSDATAFORMAT_SUBTYPE_PCM = b'\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x008\x9bq'
_array_fmts = None, 'b', 'h', None, 'i'
@@ -386,12 +388,20 @@ class Wave_read:
raise EOFError from None
if wFormatTag == WAVE_FORMAT_EXTENSIBLE:
try:
- # Only the first 2 bytes (of 16) of SubFormat are needed.
- cbSize, wValidBitsPerSample, dwChannelMask, SubFormatFmt = struct.unpack_from('<HHLH', chunk.read(10))
+ cbSize, wValidBitsPerSample, dwChannelMask = struct.unpack_from('<HHL', chunk.read(8))
+ # Read the entire UUID from the chunk
+ SubFormat = chunk.read(16)
+ if len(SubFormat) < 16:
+ raise EOFError
except struct.error:
raise EOFError from None
- if SubFormatFmt != WAVE_FORMAT_PCM:
- raise Error(f'unknown format: {SubFormatFmt}')
+ if SubFormat != KSDATAFORMAT_SUBTYPE_PCM:
+ try:
+ import uuid
+ subformat_msg = f'unknown extended format: {uuid.UUID(bytes_le=SubFormat)}'
+ except Exception:
+ subformat_msg = 'unknown extended format'
+ raise Error(subformat_msg)
self._sampwidth = (sampwidth + 7) // 8
if not self._sampwidth:
raise Error('bad sample width')