diff options
author | Barry Warsaw <barry@python.org> | 2022-04-24 22:50:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-24 22:50:07 (GMT) |
commit | 440332072706c5e422e6c54a2ec0ebb88e09c85c (patch) | |
tree | 76e0e5a12d37b250849b3a23486c33e57dda019c | |
parent | e93d2fbddaee329b2e8f405cbb5aec44ca221de6 (diff) | |
download | cpython-440332072706c5e422e6c54a2ec0ebb88e09c85c.zip cpython-440332072706c5e422e6c54a2ec0ebb88e09c85c.tar.gz cpython-440332072706c5e422e6c54a2ec0ebb88e09c85c.tar.bz2 |
Rewrite audio.py to jive with image.py (#91886)
Similar to the rewrite of email/mime/image.py and associated test after the
deprecation of imghdr.py, thisrewrites email/mime/audio.py and associated
tests after the deprecation of sndhdr.py.
Closes #91885
-rw-r--r-- | Lib/email/mime/audio.py | 108 | ||||
-rw-r--r-- | Lib/test/test_email/data/sndhdr.aifc | bin | 0 -> 106 bytes | |||
-rw-r--r-- | Lib/test/test_email/data/sndhdr.aiff | bin | 0 -> 108 bytes | |||
-rw-r--r-- | Lib/test/test_email/data/sndhdr.au (renamed from Lib/test/test_email/data/audiotest.au) | bin | 28144 -> 28144 bytes | |||
-rw-r--r-- | Lib/test/test_email/data/sndhdr.wav | bin | 0 -> 64 bytes | |||
-rw-r--r-- | Lib/test/test_email/test_email.py | 34 |
6 files changed, 78 insertions, 64 deletions
diff --git a/Lib/email/mime/audio.py b/Lib/email/mime/audio.py index e859c2e..8815f5c 100644 --- a/Lib/email/mime/audio.py +++ b/Lib/email/mime/audio.py @@ -11,58 +11,6 @@ from email import encoders from email.mime.nonmultipart import MIMENonMultipart -_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?? -def _whatsnd(data): - """Try to identify a sound file type. - - sndhdr.what() has a pretty cruddy interface, unfortunately. This is why - we re-do it here. It would be easier to reverse engineer the Unix 'file' - command and use the standard 'magic' file, as shipped with a modern Unix. - """ - hdr = data[:512] - fakefile = BytesIO(hdr) - for testfn in _tests: - res = testfn(hdr, fakefile) - if res is not None: - return res - else: - return None - - class MIMEAudio(MIMENonMultipart): """Class for generating audio/* MIME documents.""" @@ -89,10 +37,64 @@ class MIMEAudio(MIMENonMultipart): header. """ if _subtype is None: - _subtype = _whatsnd(_audiodata) + _subtype = _what(_audiodata) if _subtype is None: raise TypeError('Could not find audio MIME subtype') MIMENonMultipart.__init__(self, 'audio', _subtype, policy=policy, **_params) self.set_payload(_audiodata) _encoder(self) + + +_rules = [] + + +# Originally from the sndhdr module. +# +# There are others in sndhdr that don't have MIME types. :( +# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma?? +def _what(data): + # Try to identify a sound file type. + # + # sndhdr.what() had a pretty cruddy interface, unfortunately. This is why + # we re-do it here. It would be easier to reverse engineer the Unix 'file' + # command and use the standard 'magic' file, as shipped with a modern Unix. + hdr = data[:512] + fakefile = BytesIO(hdr) + for testfn in _rules: + if res := testfn(hdr, fakefile): + return res + else: + return None + + +def rule(rulefunc): + _rules.append(rulefunc) + return rulefunc + + +@rule +def _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 + + +@rule +def _au(h, f): + if h.startswith(b'.snd'): + return 'basic' + else: + return None + + +@rule +def _wav(h, f): + # '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" diff --git a/Lib/test/test_email/data/sndhdr.aifc b/Lib/test/test_email/data/sndhdr.aifc Binary files differnew file mode 100644 index 0000000..8aae4e7 --- /dev/null +++ b/Lib/test/test_email/data/sndhdr.aifc diff --git a/Lib/test/test_email/data/sndhdr.aiff b/Lib/test/test_email/data/sndhdr.aiff Binary files differnew file mode 100644 index 0000000..8c279a7 --- /dev/null +++ b/Lib/test/test_email/data/sndhdr.aiff diff --git a/Lib/test/test_email/data/audiotest.au b/Lib/test/test_email/data/sndhdr.au Binary files differindex f76b050..f76b050 100644 --- a/Lib/test/test_email/data/audiotest.au +++ b/Lib/test/test_email/data/sndhdr.au diff --git a/Lib/test/test_email/data/sndhdr.wav b/Lib/test/test_email/data/sndhdr.wav Binary files differnew file mode 100644 index 0000000..0dca367 --- /dev/null +++ b/Lib/test/test_email/data/sndhdr.wav diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 6ead594..933aa4c 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -1515,37 +1515,49 @@ Blah blah blah # Test the basic MIMEAudio class class TestMIMEAudio(unittest.TestCase): - def setUp(self): - with openfile('audiotest.au', 'rb') as fp: + def _make_audio(self, ext): + with openfile(f'sndhdr.{ext}', 'rb') as fp: self._audiodata = fp.read() self._au = MIMEAudio(self._audiodata) def test_guess_minor_type(self): - self.assertEqual(self._au.get_content_type(), 'audio/basic') + for ext, subtype in { + 'aifc': 'x-aiff', + 'aiff': 'x-aiff', + 'wav': 'x-wav', + 'au': 'basic', + }.items(): + self._make_audio(ext) + subtype = ext if subtype is None else subtype + self.assertEqual(self._au.get_content_type(), f'audio/{subtype}') def test_encoding(self): + self._make_audio('au') payload = self._au.get_payload() self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), - self._audiodata) + self._audiodata) def test_checkSetMinor(self): + self._make_audio('au') au = MIMEAudio(self._audiodata, 'fish') self.assertEqual(au.get_content_type(), 'audio/fish') def test_add_header(self): + self._make_audio('au') eq = self.assertEqual self._au.add_header('Content-Disposition', 'attachment', - filename='audiotest.au') + filename='sndhdr.au') eq(self._au['content-disposition'], - 'attachment; filename="audiotest.au"') + 'attachment; filename="sndhdr.au"') eq(self._au.get_params(header='content-disposition'), - [('attachment', ''), ('filename', 'audiotest.au')]) + [('attachment', ''), ('filename', 'sndhdr.au')]) eq(self._au.get_param('filename', header='content-disposition'), - 'audiotest.au') + 'sndhdr.au') missing = [] eq(self._au.get_param('attachment', header='content-disposition'), '') - self.assertIs(self._au.get_param('foo', failobj=missing, - header='content-disposition'), missing) + self.assertIs(self._au.get_param( + 'foo', failobj=missing, + header='content-disposition'), missing) # Try some missing stuff self.assertIs(self._au.get_param('foobar', missing), missing) self.assertIs(self._au.get_param('attachment', missing, @@ -3462,7 +3474,7 @@ multipart/report self.assertEqual(s.getvalue(), msgtxt) def test_mime_classes_policy_argument(self): - with openfile('audiotest.au', 'rb') as fp: + with openfile('sndhdr.au', 'rb') as fp: audiodata = fp.read() with openfile('python.gif', 'rb') as fp: bindata = fp.read() |