Skip to content

Commit e7929cb

Browse files
brettcannonhugovk
andauthored
gh-91217: deprecate-sndhdr (#91806)
Also inline necessary functionality from `sndhdr` into `email.mime.audio` for `MIMEAudio`. Co-authored-by: Hugo van Kemenade <[email protected]>
1 parent 5576ddb commit e7929cb

File tree

6 files changed

+49
-16
lines changed

6 files changed

+49
-16
lines changed

Doc/library/email.mime.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Here are the classes:
146146
A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the
147147
:class:`MIMEAudio` class is used to create MIME message objects of major type
148148
:mimetype:`audio`. *_audiodata* is a string containing the raw audio data. If
149-
this data can be decoded by the standard Python module :mod:`sndhdr`, then the
149+
this data can be decoded as au, wav, aiff, or aifc, then the
150150
subtype will be automatically included in the :mailheader:`Content-Type` header.
151151
Otherwise you can explicitly specify the audio subtype via the *_subtype*
152152
argument. If the minor type could not be guessed and *_subtype* was not given,

Doc/whatsnew/3.11.rst

+1
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,7 @@ Deprecated
920920
* :mod:`nntplib`
921921
* :mod:`ossaudiodev`
922922
* :mod:`pipes`
923+
* :mod:`sndhdr`
923924

924925
(Contributed by Brett Cannon in :issue:`47061`.)
925926

Lib/email/mime/audio.py

+37-13
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,43 @@
66

77
__all__ = ['MIMEAudio']
88

9-
import sndhdr
10-
119
from io import BytesIO
1210
from email import encoders
1311
from email.mime.nonmultipart import MIMENonMultipart
1412

1513

16-
17-
_sndhdr_MIMEmap = {'au' : 'basic',
18-
'wav' :'x-wav',
19-
'aiff':'x-aiff',
20-
'aifc':'x-aiff',
21-
}
14+
_tests = []
15+
16+
def _test_aifc_aiff(h, f):
17+
if not h.startswith(b'FORM'):
18+
return None
19+
if h[8:12] in {b'AIFC', b'AIFF'}:
20+
return 'x-aiff'
21+
else:
22+
return None
23+
24+
_tests.append(_test_aifc_aiff)
25+
26+
27+
def _test_au(h, f):
28+
if h.startswith(b'.snd'):
29+
return 'basic'
30+
else:
31+
return None
32+
33+
_tests.append(_test_au)
34+
35+
36+
def _test_wav(h, f):
37+
import wave
38+
# 'RIFF' <len> 'WAVE' 'fmt ' <len>
39+
if not h.startswith(b'RIFF') or h[8:12] != b'WAVE' or h[12:16] != b'fmt ':
40+
return None
41+
else:
42+
return "x-wav"
43+
44+
_tests.append(_test_wav)
45+
2246

2347
# There are others in sndhdr that don't have MIME types. :(
2448
# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma??
@@ -31,14 +55,14 @@ def _whatsnd(data):
3155
"""
3256
hdr = data[:512]
3357
fakefile = BytesIO(hdr)
34-
for testfn in sndhdr.tests:
58+
for testfn in _tests:
3559
res = testfn(hdr, fakefile)
3660
if res is not None:
37-
return _sndhdr_MIMEmap.get(res[0])
38-
return None
61+
return res
62+
else:
63+
return None
3964

4065

41-
4266
class MIMEAudio(MIMENonMultipart):
4367
"""Class for generating audio/* MIME documents."""
4468

@@ -47,7 +71,7 @@ def __init__(self, _audiodata, _subtype=None,
4771
"""Create an audio/* type MIME document.
4872
4973
_audiodata is a string containing the raw audio data. If this data
50-
can be decoded by the standard Python `sndhdr' module, then the
74+
can be decoded as au, wav, aiff, or aifc, then the
5175
subtype will be automatically included in the Content-Type header.
5276
Otherwise, you can specify the specific audio subtype via the
5377
_subtype parameter. If _subtype is not given, and no subtype can be

Lib/sndhdr.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@
2727
explicitly given directories.
2828
"""
2929

30+
import warnings
31+
32+
warnings._deprecated(__name__, remove=(3, 13))
33+
3034
# The file structure is top-down except that the test program and its
3135
# subroutine come last.
3236

3337
__all__ = ['what', 'whathdr']
3438

3539
from collections import namedtuple
36-
import warnings
3740

3841
SndHeaders = namedtuple('SndHeaders',
3942
'filetype framerate nchannels nframes sampwidth')

Lib/test/test_sndhdr.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import sndhdr
21
import pickle
32
import unittest
43
from test.support import findfile
4+
from test.support import warnings_helper
5+
6+
sndhdr = warnings_helper.import_deprecated("sndhdr")
7+
58

69
class TestFormats(unittest.TestCase):
710
def test_data(self):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Deprecate the sndhdr module, as well as inline needed functionality for
2+
``email.mime.MIMEAudio``.

0 commit comments

Comments
 (0)