Skip to content

Commit

Permalink
gh-91217: deprecate-sndhdr (#91806)
Browse files Browse the repository at this point in the history
Also inline necessary functionality from `sndhdr` into `email.mime.audio` for `MIMEAudio`.

Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
  • Loading branch information
brettcannon and hugovk authored Apr 22, 2022
1 parent 5576ddb commit e7929cb
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Doc/library/email.mime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ Here are the classes:
A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the
:class:`MIMEAudio` class is used to create MIME message objects of major type
:mimetype:`audio`. *_audiodata* is a string containing the raw audio data. If
this data can be decoded by the standard Python module :mod:`sndhdr`, then the
this data can be decoded as au, wav, aiff, or aifc, then the
subtype will be automatically included in the :mailheader:`Content-Type` header.
Otherwise you can explicitly specify the audio subtype via the *_subtype*
argument. If the minor type could not be guessed and *_subtype* was not given,
Expand Down
1 change: 1 addition & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ Deprecated
* :mod:`nntplib`
* :mod:`ossaudiodev`
* :mod:`pipes`
* :mod:`sndhdr`

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

Expand Down
50 changes: 37 additions & 13 deletions Lib/email/mime/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,43 @@

__all__ = ['MIMEAudio']

import sndhdr

from io import BytesIO
from email import encoders
from email.mime.nonmultipart import MIMENonMultipart



_sndhdr_MIMEmap = {'au' : 'basic',
'wav' :'x-wav',
'aiff':'x-aiff',
'aifc':'x-aiff',
}
_tests = []

def _test_aifc_aiff(h, f):
if not h.startswith(b'FORM'):
return None
if h[8:12] in {b'AIFC', b'AIFF'}:
return 'x-aiff'
else:
return None

_tests.append(_test_aifc_aiff)


def _test_au(h, f):
if h.startswith(b'.snd'):
return 'basic'
else:
return None

_tests.append(_test_au)


def _test_wav(h, f):
import wave
# 'RIFF' <len> 'WAVE' 'fmt ' <len>
if not h.startswith(b'RIFF') or h[8:12] != b'WAVE' or h[12:16] != b'fmt ':
return None
else:
return "x-wav"

_tests.append(_test_wav)


# There are others in sndhdr that don't have MIME types. :(
# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma??
Expand All @@ -31,14 +55,14 @@ def _whatsnd(data):
"""
hdr = data[:512]
fakefile = BytesIO(hdr)
for testfn in sndhdr.tests:
for testfn in _tests:
res = testfn(hdr, fakefile)
if res is not None:
return _sndhdr_MIMEmap.get(res[0])
return None
return res
else:
return None



class MIMEAudio(MIMENonMultipart):
"""Class for generating audio/* MIME documents."""

Expand All @@ -47,7 +71,7 @@ def __init__(self, _audiodata, _subtype=None,
"""Create an audio/* type MIME document.
_audiodata is a string containing the raw audio data. If this data
can be decoded by the standard Python `sndhdr' module, then the
can be decoded as au, wav, aiff, or aifc, then the
subtype will be automatically included in the Content-Type header.
Otherwise, you can specify the specific audio subtype via the
_subtype parameter. If _subtype is not given, and no subtype can be
Expand Down
5 changes: 4 additions & 1 deletion Lib/sndhdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@
explicitly given directories.
"""

import warnings

warnings._deprecated(__name__, remove=(3, 13))

# The file structure is top-down except that the test program and its
# subroutine come last.

__all__ = ['what', 'whathdr']

from collections import namedtuple
import warnings

SndHeaders = namedtuple('SndHeaders',
'filetype framerate nchannels nframes sampwidth')
Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_sndhdr.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import sndhdr
import pickle
import unittest
from test.support import findfile
from test.support import warnings_helper

sndhdr = warnings_helper.import_deprecated("sndhdr")


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

0 comments on commit e7929cb

Please sign in to comment.