]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-104773: PEP 594: Remove the sunau module (#104863)
authorVictor Stinner <vstinner@python.org>
Wed, 24 May 2023 13:51:59 +0000 (15:51 +0200)
committerGitHub <noreply@github.com>
Wed, 24 May 2023 13:51:59 +0000 (13:51 +0000)
* Remove Lib/test/audiodata/pluck-*.au files.
* Remove Lib/test/audiotest.au file.

21 files changed:
Doc/library/sunau.rst [deleted file]
Doc/library/superseded.rst
Doc/tools/.nitignore
Doc/whatsnew/3.11.rst
Doc/whatsnew/3.12.rst
Doc/whatsnew/3.13.rst
Doc/whatsnew/3.4.rst
Doc/whatsnew/3.7.rst
Lib/sunau.py [deleted file]
Lib/test/audiodata/pluck-pcm16.au [deleted file]
Lib/test/audiodata/pluck-pcm24.au [deleted file]
Lib/test/audiodata/pluck-pcm32.au [deleted file]
Lib/test/audiodata/pluck-pcm8.au [deleted file]
Lib/test/audiodata/pluck-ulaw.au [deleted file]
Lib/test/audiotest.au [deleted file]
Lib/test/test_sunau.py [deleted file]
Misc/NEWS.d/3.7.0b3.rst
Misc/NEWS.d/3.8.0a1.rst
Misc/NEWS.d/next/Library/2023-05-24-14-58-13.gh-issue-104773.sQaXrY.rst [new file with mode: 0644]
Python/stdlib_module_names.h
Tools/wasm/wasm_assets.py

diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst
deleted file mode 100644 (file)
index c7a38d9..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-:mod:`sunau` --- Read and write Sun AU files
-============================================
-
-.. module:: sunau
-   :synopsis: Provide an interface to the Sun AU sound format.
-   :deprecated:
-
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
-
-**Source code:** :source:`Lib/sunau.py`
-
-.. deprecated-removed:: 3.11 3.13
-   The :mod:`sunau` module is deprecated
-   (see :pep:`PEP 594 <594#sunau>` for details).
-
---------------
-
-The :mod:`sunau` module provides a convenient interface to the Sun AU sound
-format.  Note that this module is interface-compatible with the modules
-:mod:`aifc` and :mod:`wave`.
-
-An audio file consists of a header followed by the data.  The fields of the
-header are:
-
-+---------------+-----------------------------------------------+
-| Field         | Contents                                      |
-+===============+===============================================+
-| magic word    | The four bytes ``.snd``.                      |
-+---------------+-----------------------------------------------+
-| header size   | Size of the header, including info, in bytes. |
-+---------------+-----------------------------------------------+
-| data size     | Physical size of the data, in bytes.          |
-+---------------+-----------------------------------------------+
-| encoding      | Indicates how the audio samples are encoded.  |
-+---------------+-----------------------------------------------+
-| sample rate   | The sampling rate.                            |
-+---------------+-----------------------------------------------+
-| # of channels | The number of channels in the samples.        |
-+---------------+-----------------------------------------------+
-| info          | ASCII string giving a description of the      |
-|               | audio file (padded with null bytes).          |
-+---------------+-----------------------------------------------+
-
-Apart from the info field, all header fields are 4 bytes in size. They are all
-32-bit unsigned integers encoded in big-endian byte order.
-
-The :mod:`sunau` module defines the following functions:
-
-
-.. function:: open(file, mode)
-
-   If *file* is a string, open the file by that name, otherwise treat it as a
-   seekable file-like object. *mode* can be any of
-
-   ``'r'``
-      Read only mode.
-
-   ``'w'``
-      Write only mode.
-
-   Note that it does not allow read/write files.
-
-   A *mode* of ``'r'`` returns an :class:`AU_read` object, while a *mode* of ``'w'``
-   or ``'wb'`` returns an :class:`AU_write` object.
-
-
-The :mod:`sunau` module defines the following exception:
-
-.. exception:: Error
-
-   An error raised when something is impossible because of Sun AU specs or
-   implementation deficiency.
-
-
-The :mod:`sunau` module defines the following data items:
-
-.. data:: AUDIO_FILE_MAGIC
-
-   An integer every valid Sun AU file begins with, stored in big-endian form.  This
-   is the string ``.snd`` interpreted as an integer.
-
-
-.. data:: AUDIO_FILE_ENCODING_MULAW_8
-          AUDIO_FILE_ENCODING_LINEAR_8
-          AUDIO_FILE_ENCODING_LINEAR_16
-          AUDIO_FILE_ENCODING_LINEAR_24
-          AUDIO_FILE_ENCODING_LINEAR_32
-          AUDIO_FILE_ENCODING_ALAW_8
-
-   Values of the encoding field from the AU header which are supported by this
-   module.
-
-
-.. data:: AUDIO_FILE_ENCODING_FLOAT
-          AUDIO_FILE_ENCODING_DOUBLE
-          AUDIO_FILE_ENCODING_ADPCM_G721
-          AUDIO_FILE_ENCODING_ADPCM_G722
-          AUDIO_FILE_ENCODING_ADPCM_G723_3
-          AUDIO_FILE_ENCODING_ADPCM_G723_5
-
-   Additional known values of the encoding field from the AU header, but which are
-   not supported by this module.
-
-
-.. _au-read-objects:
-
-AU_read Objects
----------------
-
-AU_read objects, as returned by :func:`.open` above, have the following methods:
-
-
-.. method:: AU_read.close()
-
-   Close the stream, and make the instance unusable. (This is  called automatically
-   on deletion.)
-
-
-.. method:: AU_read.getnchannels()
-
-   Returns number of audio channels (1 for mono, 2 for stereo).
-
-
-.. method:: AU_read.getsampwidth()
-
-   Returns sample width in bytes.
-
-
-.. method:: AU_read.getframerate()
-
-   Returns sampling frequency.
-
-
-.. method:: AU_read.getnframes()
-
-   Returns number of audio frames.
-
-
-.. method:: AU_read.getcomptype()
-
-   Returns compression type. Supported compression types are ``'ULAW'``, ``'ALAW'``
-   and ``'NONE'``.
-
-
-.. method:: AU_read.getcompname()
-
-   Human-readable version of :meth:`getcomptype`.  The supported types have the
-   respective names ``'CCITT G.711 u-law'``, ``'CCITT G.711 A-law'`` and ``'not
-   compressed'``.
-
-
-.. method:: AU_read.getparams()
-
-   Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth,
-   framerate, nframes, comptype, compname)``, equivalent to output of the
-   :meth:`get\*` methods.
-
-
-.. method:: AU_read.readframes(n)
-
-   Reads and returns at most *n* frames of audio, as a :class:`bytes` object.  The data
-   will be returned in linear format.  If the original data is in u-LAW format, it
-   will be converted.
-
-
-.. method:: AU_read.rewind()
-
-   Rewind the file pointer to the beginning of the audio stream.
-
-The following two methods define a term "position" which is compatible between
-them, and is otherwise implementation dependent.
-
-
-.. method:: AU_read.setpos(pos)
-
-   Set the file pointer to the specified position.  Only values returned from
-   :meth:`tell` should be used for *pos*.
-
-
-.. method:: AU_read.tell()
-
-   Return current file pointer position.  Note that the returned value has nothing
-   to do with the actual position in the file.
-
-The following two functions are defined for compatibility with the  :mod:`aifc`,
-and don't do anything interesting.
-
-
-.. method:: AU_read.getmarkers()
-
-   Returns ``None``.
-
-
-.. method:: AU_read.getmark(id)
-
-   Raise an error.
-
-
-.. _au-write-objects:
-
-AU_write Objects
-----------------
-
-AU_write objects, as returned by :func:`.open` above, have the following methods:
-
-
-.. method:: AU_write.setnchannels(n)
-
-   Set the number of channels.
-
-
-.. method:: AU_write.setsampwidth(n)
-
-   Set the sample width (in bytes.)
-
-   .. versionchanged:: 3.4
-      Added support for 24-bit samples.
-
-
-.. method:: AU_write.setframerate(n)
-
-   Set the frame rate.
-
-
-.. method:: AU_write.setnframes(n)
-
-   Set the number of frames. This can be later changed, when and if more  frames
-   are written.
-
-
-.. method:: AU_write.setcomptype(type, name)
-
-   Set the compression type and description. Only ``'NONE'`` and ``'ULAW'`` are
-   supported on output.
-
-
-.. method:: AU_write.setparams(tuple)
-
-   The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype,
-   compname)``, with values valid for the :meth:`set\*` methods.  Set all
-   parameters.
-
-
-.. method:: AU_write.tell()
-
-   Return current position in the file, with the same disclaimer for the
-   :meth:`AU_read.tell` and :meth:`AU_read.setpos` methods.
-
-
-.. method:: AU_write.writeframesraw(data)
-
-   Write audio frames, without correcting *nframes*.
-
-   .. versionchanged:: 3.4
-      Any :term:`bytes-like object` is now accepted.
-
-
-.. method:: AU_write.writeframes(data)
-
-   Write audio frames and make sure *nframes* is correct.
-
-   .. versionchanged:: 3.4
-      Any :term:`bytes-like object` is now accepted.
-
-
-.. method:: AU_write.close()
-
-   Make sure *nframes* is correct, and close the file.
-
-   This method is called upon deletion.
-
-Note that it is invalid to set any parameters after calling  :meth:`writeframes`
-or :meth:`writeframesraw`.
-
index a655c09c956fb24e5cf4fe687305d3ca9429d042..1ab7b08d4d202cedc759031e3056d119c234aaec 100644 (file)
@@ -21,6 +21,5 @@ backwards compatibility. They have been superseded by other modules.
    nntplib.rst
    optparse.rst
    spwd.rst
-   sunau.rst
    uu.rst
    xdrlib.rst
index b8d3e7d0374a4e8a1bcd4ff20935bcd37b3901d6..cdd896eda1aa5ef0742b50a515f99354cb35104e 100644 (file)
@@ -207,7 +207,6 @@ Doc/library/stdtypes.rst
 Doc/library/string.rst
 Doc/library/struct.rst
 Doc/library/subprocess.rst
-Doc/library/sunau.rst
 Doc/library/sys.rst
 Doc/library/sys_path_init.rst
 Doc/library/sysconfig.rst
index e59604e7778f7b5128387c5f6f192c85a9c4e6c6..9734d43ef87d2515f4bc3970c59e611b0aa3a089 100644 (file)
@@ -1737,7 +1737,7 @@ Modules
   +---------------------+---------------------+---------------------+---------------------+---------------------+
   | :mod:`!cgi`         | :mod:`imghdr`       | :mod:`nntplib`      | :mod:`spwd`         | :mod:`xdrlib`       |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
-  | :mod:`!cgitb`       | :mod:`mailcap`      | :mod:`!ossaudiodev` | :mod:`sunau`        |                     |
+  | :mod:`!cgitb`       | :mod:`mailcap`      | :mod:`!ossaudiodev` | :mod:`!sunau`       |                     |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
 
   (Contributed by Brett Cannon in :issue:`47061` and Victor Stinner in
index 844d063dbab62fa76073384ed2931440b06595c8..316296ae038e4ea22d2d237c684e8272175d6bfc 100644 (file)
@@ -901,7 +901,7 @@ Modules (see :pep:`594`):
 * :mod:`!pipes`
 * :mod:`!sndhdr`
 * :mod:`spwd`
-* :mod:`sunau`
+* :mod:`!sunau`
 * :mod:`!telnetlib`
 * :mod:`uu`
 * :mod:`xdrlib`
index d086f3c12e5e3a93ab91c1f46e29c5099ea389b1..83d539b6fc3d9a84c5470a1d12aa5fe7c9d8cec3 100644 (file)
@@ -161,6 +161,9 @@ Removed
   use the `pygame project <https://www.pygame.org/>`_ for audio playback.
   (Contributed by Victor Stinner in :gh:`104780`.)
 
+* :pep:`594`: Remove the :mod:`!sunau` module, deprecated in Python 3.11.
+  (Contributed by Victor Stinner in :gh:`104773`.)
+
 
 Porting to Python 3.13
 ======================
index d4ed8abe772aaf2c2fe03e087971832cce4d8dec..b9008328b49fd5bb210c4f02fa606cf6faff183a 100644 (file)
@@ -1528,10 +1528,10 @@ work on Windows.  This change was actually inadvertently made in 3.3.4.
 sunau
 -----
 
-The :meth:`~sunau.getparams` method now returns a namedtuple rather than a
+The :meth:`~!sunau.getparams` method now returns a namedtuple rather than a
 plain tuple.  (Contributed by Claudiu Popa in :issue:`18901`.)
 
-:meth:`sunau.open` now supports the context management protocol: when used in a
+:meth:`!sunau.open` now supports the context management protocol: when used in a
 :keyword:`with` block, the ``close`` method of the returned object will be
 called automatically at the end of the block.  (Contributed by Serhiy Storchaka
 in :issue:`18878`.)
@@ -1540,8 +1540,8 @@ in :issue:`18878`.)
 support for writing 24 sample using the module.  (Contributed by
 Serhiy Storchaka in :issue:`19261`.)
 
-The :meth:`~sunau.AU_write.writeframesraw` and
-:meth:`~sunau.AU_write.writeframes` methods now accept any :term:`bytes-like
+The :meth:`~!sunau.AU_write.writeframesraw` and
+:meth:`~!sunau.AU_write.writeframes` methods now accept any :term:`bytes-like
 object`.  (Contributed by Serhiy Storchaka in :issue:`8311`.)
 
 
index 41d7e08f2b39aa49cbf0804c6e38e3d4e4625135..967608d512f1d5fb00c3962383eb47ee7a1c6329 100644 (file)
@@ -2061,8 +2061,8 @@ ssl
 sunau
 -----
 
-:func:`sunau.openfp` has been deprecated and will be removed in Python 3.9.
-Use :func:`sunau.open` instead.
+:func:`!sunau.openfp` has been deprecated and will be removed in Python 3.9.
+Use :func:`!sunau.open` instead.
 (Contributed by Brian Curtin in :issue:`31985`.)
 
 
diff --git a/Lib/sunau.py b/Lib/sunau.py
deleted file mode 100644 (file)
index c6caab9..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-"""Stuff to parse Sun and NeXT audio files.
-
-An audio file consists of a header followed by the data.  The structure
-of the header is as follows.
-
-        +---------------+
-        | magic word    |
-        +---------------+
-        | header size   |
-        +---------------+
-        | data size     |
-        +---------------+
-        | encoding      |
-        +---------------+
-        | sample rate   |
-        +---------------+
-        | # of channels |
-        +---------------+
-        | info          |
-        |               |
-        +---------------+
-
-The magic word consists of the 4 characters '.snd'.  Apart from the
-info field, all header fields are 4 bytes in size.  They are all
-32-bit unsigned integers encoded in big-endian byte order.
-
-The header size really gives the start of the data.
-The data size is the physical size of the data.  From the other
-parameters the number of frames can be calculated.
-The encoding gives the way in which audio samples are encoded.
-Possible values are listed below.
-The info field currently consists of an ASCII string giving a
-human-readable description of the audio file.  The info field is
-padded with NUL bytes to the header size.
-
-Usage.
-
-Reading audio files:
-        f = sunau.open(file, 'r')
-where file is either the name of a file or an open file pointer.
-The open file pointer must have methods read(), seek(), and close().
-When the setpos() and rewind() methods are not used, the seek()
-method is not  necessary.
-
-This returns an instance of a class with the following public methods:
-        getnchannels()  -- returns number of audio channels (1 for
-                           mono, 2 for stereo)
-        getsampwidth()  -- returns sample width in bytes
-        getframerate()  -- returns sampling frequency
-        getnframes()    -- returns number of audio frames
-        getcomptype()   -- returns compression type ('NONE' or 'ULAW')
-        getcompname()   -- returns human-readable version of
-                           compression type ('not compressed' matches 'NONE')
-        getparams()     -- returns a namedtuple consisting of all of the
-                           above in the above order
-        getmarkers()    -- returns None (for compatibility with the
-                           aifc module)
-        getmark(id)     -- raises an error since the mark does not
-                           exist (for compatibility with the aifc module)
-        readframes(n)   -- returns at most n frames of audio
-        rewind()        -- rewind to the beginning of the audio stream
-        setpos(pos)     -- seek to the specified position
-        tell()          -- return the current position
-        close()         -- close the instance (make it unusable)
-The position returned by tell() and the position given to setpos()
-are compatible and have nothing to do with the actual position in the
-file.
-The close() method is called automatically when the class instance
-is destroyed.
-
-Writing audio files:
-        f = sunau.open(file, 'w')
-where file is either the name of a file or an open file pointer.
-The open file pointer must have methods write(), tell(), seek(), and
-close().
-
-This returns an instance of a class with the following public methods:
-        setnchannels(n) -- set the number of channels
-        setsampwidth(n) -- set the sample width
-        setframerate(n) -- set the frame rate
-        setnframes(n)   -- set the number of frames
-        setcomptype(type, name)
-                        -- set the compression type and the
-                           human-readable compression type
-        setparams(tuple)-- set all parameters at once
-        tell()          -- return current position in output file
-        writeframesraw(data)
-                        -- write audio frames without pathing up the
-                           file header
-        writeframes(data)
-                        -- write audio frames and patch up the file header
-        close()         -- patch up the file header and close the
-                           output file
-You should set the parameters before the first writeframesraw or
-writeframes.  The total number of frames does not need to be set,
-but when it is set to the correct value, the header does not have to
-be patched up.
-It is best to first set all parameters, perhaps possibly the
-compression type, and then write audio frames using writeframesraw.
-When all frames have been written, either call writeframes(b'') or
-close() to patch up the sizes in the header.
-The close() method is called automatically when the class instance
-is destroyed.
-"""
-
-from collections import namedtuple
-import warnings
-
-warnings._deprecated(__name__, remove=(3, 13))
-
-
-_sunau_params = namedtuple('_sunau_params',
-                           'nchannels sampwidth framerate nframes comptype compname')
-
-# from <multimedia/audio_filehdr.h>
-AUDIO_FILE_MAGIC = 0x2e736e64
-AUDIO_FILE_ENCODING_MULAW_8 = 1
-AUDIO_FILE_ENCODING_LINEAR_8 = 2
-AUDIO_FILE_ENCODING_LINEAR_16 = 3
-AUDIO_FILE_ENCODING_LINEAR_24 = 4
-AUDIO_FILE_ENCODING_LINEAR_32 = 5
-AUDIO_FILE_ENCODING_FLOAT = 6
-AUDIO_FILE_ENCODING_DOUBLE = 7
-AUDIO_FILE_ENCODING_ADPCM_G721 = 23
-AUDIO_FILE_ENCODING_ADPCM_G722 = 24
-AUDIO_FILE_ENCODING_ADPCM_G723_3 = 25
-AUDIO_FILE_ENCODING_ADPCM_G723_5 = 26
-AUDIO_FILE_ENCODING_ALAW_8 = 27
-
-# from <multimedia/audio_hdr.h>
-AUDIO_UNKNOWN_SIZE = 0xFFFFFFFF        # ((unsigned)(~0))
-
-_simple_encodings = [AUDIO_FILE_ENCODING_MULAW_8,
-                     AUDIO_FILE_ENCODING_LINEAR_8,
-                     AUDIO_FILE_ENCODING_LINEAR_16,
-                     AUDIO_FILE_ENCODING_LINEAR_24,
-                     AUDIO_FILE_ENCODING_LINEAR_32,
-                     AUDIO_FILE_ENCODING_ALAW_8]
-
-class Error(Exception):
-    pass
-
-def _read_u32(file):
-    x = 0
-    for i in range(4):
-        byte = file.read(1)
-        if not byte:
-            raise EOFError
-        x = x*256 + ord(byte)
-    return x
-
-def _write_u32(file, x):
-    data = []
-    for i in range(4):
-        d, m = divmod(x, 256)
-        data.insert(0, int(m))
-        x = d
-    file.write(bytes(data))
-
-class Au_read:
-
-    def __init__(self, f):
-        if isinstance(f, str):
-            import builtins
-            f = builtins.open(f, 'rb')
-            self._opened = True
-        else:
-            self._opened = False
-        self.initfp(f)
-
-    def __del__(self):
-        if self._file:
-            self.close()
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, *args):
-        self.close()
-
-    def initfp(self, file):
-        self._file = file
-        self._soundpos = 0
-        magic = int(_read_u32(file))
-        if magic != AUDIO_FILE_MAGIC:
-            raise Error('bad magic number')
-        self._hdr_size = int(_read_u32(file))
-        if self._hdr_size < 24:
-            raise Error('header size too small')
-        if self._hdr_size > 100:
-            raise Error('header size ridiculously large')
-        self._data_size = _read_u32(file)
-        if self._data_size != AUDIO_UNKNOWN_SIZE:
-            self._data_size = int(self._data_size)
-        self._encoding = int(_read_u32(file))
-        if self._encoding not in _simple_encodings:
-            raise Error('encoding not (yet) supported')
-        if self._encoding in (AUDIO_FILE_ENCODING_MULAW_8,
-                  AUDIO_FILE_ENCODING_ALAW_8):
-            self._sampwidth = 2
-            self._framesize = 1
-        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_8:
-            self._framesize = self._sampwidth = 1
-        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_16:
-            self._framesize = self._sampwidth = 2
-        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_24:
-            self._framesize = self._sampwidth = 3
-        elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_32:
-            self._framesize = self._sampwidth = 4
-        else:
-            raise Error('unknown encoding')
-        self._framerate = int(_read_u32(file))
-        self._nchannels = int(_read_u32(file))
-        if not self._nchannels:
-            raise Error('bad # of channels')
-        self._framesize = self._framesize * self._nchannels
-        if self._hdr_size > 24:
-            self._info = file.read(self._hdr_size - 24)
-            self._info, _, _ = self._info.partition(b'\0')
-        else:
-            self._info = b''
-        try:
-            self._data_pos = file.tell()
-        except (AttributeError, OSError):
-            self._data_pos = None
-
-    def getfp(self):
-        return self._file
-
-    def getnchannels(self):
-        return self._nchannels
-
-    def getsampwidth(self):
-        return self._sampwidth
-
-    def getframerate(self):
-        return self._framerate
-
-    def getnframes(self):
-        if self._data_size == AUDIO_UNKNOWN_SIZE:
-            return AUDIO_UNKNOWN_SIZE
-        if self._encoding in _simple_encodings:
-            return self._data_size // self._framesize
-        return 0                # XXX--must do some arithmetic here
-
-    def getcomptype(self):
-        if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
-            return 'ULAW'
-        elif self._encoding == AUDIO_FILE_ENCODING_ALAW_8:
-            return 'ALAW'
-        else:
-            return 'NONE'
-
-    def getcompname(self):
-        if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
-            return 'CCITT G.711 u-law'
-        elif self._encoding == AUDIO_FILE_ENCODING_ALAW_8:
-            return 'CCITT G.711 A-law'
-        else:
-            return 'not compressed'
-
-    def getparams(self):
-        return _sunau_params(self.getnchannels(), self.getsampwidth(),
-                  self.getframerate(), self.getnframes(),
-                  self.getcomptype(), self.getcompname())
-
-    def getmarkers(self):
-        return None
-
-    def getmark(self, id):
-        raise Error('no marks')
-
-    def readframes(self, nframes):
-        if self._encoding in _simple_encodings:
-            if nframes == AUDIO_UNKNOWN_SIZE:
-                data = self._file.read()
-            else:
-                data = self._file.read(nframes * self._framesize)
-            self._soundpos += len(data) // self._framesize
-            if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
-                with warnings.catch_warnings():
-                    warnings.simplefilter('ignore', category=DeprecationWarning)
-                    import audioop
-                data = audioop.ulaw2lin(data, self._sampwidth)
-            return data
-        return None             # XXX--not implemented yet
-
-    def rewind(self):
-        if self._data_pos is None:
-            raise OSError('cannot seek')
-        self._file.seek(self._data_pos)
-        self._soundpos = 0
-
-    def tell(self):
-        return self._soundpos
-
-    def setpos(self, pos):
-        if pos < 0 or pos > self.getnframes():
-            raise Error('position not in range')
-        if self._data_pos is None:
-            raise OSError('cannot seek')
-        self._file.seek(self._data_pos + pos * self._framesize)
-        self._soundpos = pos
-
-    def close(self):
-        file = self._file
-        if file:
-            self._file = None
-            if self._opened:
-                file.close()
-
-class Au_write:
-
-    def __init__(self, f):
-        if isinstance(f, str):
-            import builtins
-            f = builtins.open(f, 'wb')
-            self._opened = True
-        else:
-            self._opened = False
-        self.initfp(f)
-
-    def __del__(self):
-        if self._file:
-            self.close()
-        self._file = None
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, *args):
-        self.close()
-
-    def initfp(self, file):
-        self._file = file
-        self._framerate = 0
-        self._nchannels = 0
-        self._sampwidth = 0
-        self._framesize = 0
-        self._nframes = AUDIO_UNKNOWN_SIZE
-        self._nframeswritten = 0
-        self._datawritten = 0
-        self._datalength = 0
-        self._info = b''
-        self._comptype = 'ULAW' # default is U-law
-
-    def setnchannels(self, nchannels):
-        if self._nframeswritten:
-            raise Error('cannot change parameters after starting to write')
-        if nchannels not in (1, 2, 4):
-            raise Error('only 1, 2, or 4 channels supported')
-        self._nchannels = nchannels
-
-    def getnchannels(self):
-        if not self._nchannels:
-            raise Error('number of channels not set')
-        return self._nchannels
-
-    def setsampwidth(self, sampwidth):
-        if self._nframeswritten:
-            raise Error('cannot change parameters after starting to write')
-        if sampwidth not in (1, 2, 3, 4):
-            raise Error('bad sample width')
-        self._sampwidth = sampwidth
-
-    def getsampwidth(self):
-        if not self._framerate:
-            raise Error('sample width not specified')
-        return self._sampwidth
-
-    def setframerate(self, framerate):
-        if self._nframeswritten:
-            raise Error('cannot change parameters after starting to write')
-        self._framerate = framerate
-
-    def getframerate(self):
-        if not self._framerate:
-            raise Error('frame rate not set')
-        return self._framerate
-
-    def setnframes(self, nframes):
-        if self._nframeswritten:
-            raise Error('cannot change parameters after starting to write')
-        if nframes < 0:
-            raise Error('# of frames cannot be negative')
-        self._nframes = nframes
-
-    def getnframes(self):
-        return self._nframeswritten
-
-    def setcomptype(self, type, name):
-        if type in ('NONE', 'ULAW'):
-            self._comptype = type
-        else:
-            raise Error('unknown compression type')
-
-    def getcomptype(self):
-        return self._comptype
-
-    def getcompname(self):
-        if self._comptype == 'ULAW':
-            return 'CCITT G.711 u-law'
-        elif self._comptype == 'ALAW':
-            return 'CCITT G.711 A-law'
-        else:
-            return 'not compressed'
-
-    def setparams(self, params):
-        nchannels, sampwidth, framerate, nframes, comptype, compname = params
-        self.setnchannels(nchannels)
-        self.setsampwidth(sampwidth)
-        self.setframerate(framerate)
-        self.setnframes(nframes)
-        self.setcomptype(comptype, compname)
-
-    def getparams(self):
-        return _sunau_params(self.getnchannels(), self.getsampwidth(),
-                  self.getframerate(), self.getnframes(),
-                  self.getcomptype(), self.getcompname())
-
-    def tell(self):
-        return self._nframeswritten
-
-    def writeframesraw(self, data):
-        if not isinstance(data, (bytes, bytearray)):
-            data = memoryview(data).cast('B')
-        self._ensure_header_written()
-        if self._comptype == 'ULAW':
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', category=DeprecationWarning)
-                import audioop
-            data = audioop.lin2ulaw(data, self._sampwidth)
-        nframes = len(data) // self._framesize
-        self._file.write(data)
-        self._nframeswritten = self._nframeswritten + nframes
-        self._datawritten = self._datawritten + len(data)
-
-    def writeframes(self, data):
-        self.writeframesraw(data)
-        if self._nframeswritten != self._nframes or \
-                  self._datalength != self._datawritten:
-            self._patchheader()
-
-    def close(self):
-        if self._file:
-            try:
-                self._ensure_header_written()
-                if self._nframeswritten != self._nframes or \
-                        self._datalength != self._datawritten:
-                    self._patchheader()
-                self._file.flush()
-            finally:
-                file = self._file
-                self._file = None
-                if self._opened:
-                    file.close()
-
-    #
-    # private methods
-    #
-
-    def _ensure_header_written(self):
-        if not self._nframeswritten:
-            if not self._nchannels:
-                raise Error('# of channels not specified')
-            if not self._sampwidth:
-                raise Error('sample width not specified')
-            if not self._framerate:
-                raise Error('frame rate not specified')
-            self._write_header()
-
-    def _write_header(self):
-        if self._comptype == 'NONE':
-            if self._sampwidth == 1:
-                encoding = AUDIO_FILE_ENCODING_LINEAR_8
-                self._framesize = 1
-            elif self._sampwidth == 2:
-                encoding = AUDIO_FILE_ENCODING_LINEAR_16
-                self._framesize = 2
-            elif self._sampwidth == 3:
-                encoding = AUDIO_FILE_ENCODING_LINEAR_24
-                self._framesize = 3
-            elif self._sampwidth == 4:
-                encoding = AUDIO_FILE_ENCODING_LINEAR_32
-                self._framesize = 4
-            else:
-                raise Error('internal error')
-        elif self._comptype == 'ULAW':
-            encoding = AUDIO_FILE_ENCODING_MULAW_8
-            self._framesize = 1
-        else:
-            raise Error('internal error')
-        self._framesize = self._framesize * self._nchannels
-        _write_u32(self._file, AUDIO_FILE_MAGIC)
-        header_size = 25 + len(self._info)
-        header_size = (header_size + 7) & ~7
-        _write_u32(self._file, header_size)
-        if self._nframes == AUDIO_UNKNOWN_SIZE:
-            length = AUDIO_UNKNOWN_SIZE
-        else:
-            length = self._nframes * self._framesize
-        try:
-            self._form_length_pos = self._file.tell()
-        except (AttributeError, OSError):
-            self._form_length_pos = None
-        _write_u32(self._file, length)
-        self._datalength = length
-        _write_u32(self._file, encoding)
-        _write_u32(self._file, self._framerate)
-        _write_u32(self._file, self._nchannels)
-        self._file.write(self._info)
-        self._file.write(b'\0'*(header_size - len(self._info) - 24))
-
-    def _patchheader(self):
-        if self._form_length_pos is None:
-            raise OSError('cannot seek')
-        self._file.seek(self._form_length_pos)
-        _write_u32(self._file, self._datawritten)
-        self._datalength = self._datawritten
-        self._file.seek(0, 2)
-
-def open(f, mode=None):
-    if mode is None:
-        if hasattr(f, 'mode'):
-            mode = f.mode
-        else:
-            mode = 'rb'
-    if mode in ('r', 'rb'):
-        return Au_read(f)
-    elif mode in ('w', 'wb'):
-        return Au_write(f)
-    else:
-        raise Error("mode must be 'r', 'rb', 'w', or 'wb'")
diff --git a/Lib/test/audiodata/pluck-pcm16.au b/Lib/test/audiodata/pluck-pcm16.au
deleted file mode 100644 (file)
index 398f07f..0000000
Binary files a/Lib/test/audiodata/pluck-pcm16.au and /dev/null differ
diff --git a/Lib/test/audiodata/pluck-pcm24.au b/Lib/test/audiodata/pluck-pcm24.au
deleted file mode 100644 (file)
index 0bb2304..0000000
Binary files a/Lib/test/audiodata/pluck-pcm24.au and /dev/null differ
diff --git a/Lib/test/audiodata/pluck-pcm32.au b/Lib/test/audiodata/pluck-pcm32.au
deleted file mode 100644 (file)
index 92ee596..0000000
Binary files a/Lib/test/audiodata/pluck-pcm32.au and /dev/null differ
diff --git a/Lib/test/audiodata/pluck-pcm8.au b/Lib/test/audiodata/pluck-pcm8.au
deleted file mode 100644 (file)
index b7172c8..0000000
Binary files a/Lib/test/audiodata/pluck-pcm8.au and /dev/null differ
diff --git a/Lib/test/audiodata/pluck-ulaw.au b/Lib/test/audiodata/pluck-ulaw.au
deleted file mode 100644 (file)
index 1110353..0000000
Binary files a/Lib/test/audiodata/pluck-ulaw.au and /dev/null differ
diff --git a/Lib/test/audiotest.au b/Lib/test/audiotest.au
deleted file mode 100644 (file)
index f76b050..0000000
Binary files a/Lib/test/audiotest.au and /dev/null differ
diff --git a/Lib/test/test_sunau.py b/Lib/test/test_sunau.py
deleted file mode 100644 (file)
index 40408b0..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-import unittest
-from test import audiotests
-import io
-import struct
-import sys
-from test.support import warnings_helper
-
-sunau = warnings_helper.import_deprecated("sunau")
-audioop = warnings_helper.import_deprecated("audioop")
-
-
-class SunauTest(audiotests.AudioWriteTests,
-                audiotests.AudioTestsWithSourceFile):
-    module = sunau
-
-
-class SunauPCM8Test(SunauTest, unittest.TestCase):
-    sndfilename = 'pluck-pcm8.au'
-    sndfilenframes = 3307
-    nchannels = 2
-    sampwidth = 1
-    framerate = 11025
-    nframes = 48
-    comptype = 'NONE'
-    compname = 'not compressed'
-    frames = bytes.fromhex("""\
-      02FF 4B00 3104 8008 CB06 4803 BF01 03FE B8FA B4F3 29EB 1AE6 \
-      EDE4 C6E2 0EE0 EFE0 57E2 FBE8 13EF D8F7 97FB F5FC 08FB DFFB \
-      11FA 3EFB BCFC 66FF CF04 4309 C10E 5112 EE17 8216 7F14 8012 \
-      490E 520D EF0F CE0F E40C 630A 080A 2B0B 510E 8B11 B60E 440A \
-      """)
-
-
-class SunauPCM16Test(SunauTest, unittest.TestCase):
-    sndfilename = 'pluck-pcm16.au'
-    sndfilenframes = 3307
-    nchannels = 2
-    sampwidth = 2
-    framerate = 11025
-    nframes = 48
-    comptype = 'NONE'
-    compname = 'not compressed'
-    frames = bytes.fromhex("""\
-      022EFFEA 4B5C00F9 311404EF 80DB0844 CBE006B0 48AB03F3 BFE601B5 0367FE80 \
-      B853FA42 B4AFF351 2997EBCD 1A5AE6DC EDF9E492 C627E277 0E06E0B7 EF29E029 \
-      5759E271 FB34E83F 1377EF85 D82CF727 978EFB79 F5F7FC12 0864FB9E DF30FB40 \
-      1183FA30 3EEAFB59 BC78FCB4 66D5FF60 CF130415 431A097D C1BA0EC7 512312A0 \
-      EEE11754 82071666 7FFE1448 80001298 49990EB7 52B40DC1 EFAD0F65 CE3A0FBE \
-      E4B70CE6 63490A57 08CC0A1D 2BBC0B09 51480E46 8BCB113C B6F60EE9 44150A5A \
-      """)
-
-
-class SunauPCM24Test(SunauTest, unittest.TestCase):
-    sndfilename = 'pluck-pcm24.au'
-    sndfilenframes = 3307
-    nchannels = 2
-    sampwidth = 3
-    framerate = 11025
-    nframes = 48
-    comptype = 'NONE'
-    compname = 'not compressed'
-    frames = bytes.fromhex("""\
-      022D65FFEB9D 4B5A0F00FA54 3113C304EE2B 80DCD6084303 \
-      CBDEC006B261 48A99803F2F8 BFE82401B07D 036BFBFE7B5D \
-      B85756FA3EC9 B4B055F3502B 299830EBCB62 1A5CA7E6D99A \
-      EDFA3EE491BD C625EBE27884 0E05A9E0B6CF EF2929E02922 \
-      5758D8E27067 FB3557E83E16 1377BFEF8402 D82C5BF7272A \
-      978F16FB7745 F5F865FC1013 086635FB9C4E DF30FCFB40EE \
-      117FE0FA3438 3EE6B8FB5AC3 BC77A3FCB2F4 66D6DAFF5F32 \
-      CF13B9041275 431D69097A8C C1BB600EC74E 5120B912A2BA \
-      EEDF641754C0 8207001664B7 7FFFFF14453F 8000001294E6 \
-      499C1B0EB3B2 52B73E0DBCA0 EFB2B20F5FD8 CE3CDB0FBE12 \
-      E4B49C0CEA2D 6344A80A5A7C 08C8FE0A1FFE 2BB9860B0A0E \
-      51486F0E44E1 8BCC64113B05 B6F4EC0EEB36 4413170A5B48 \
-      """)
-
-
-class SunauPCM32Test(SunauTest, unittest.TestCase):
-    sndfilename = 'pluck-pcm32.au'
-    sndfilenframes = 3307
-    nchannels = 2
-    sampwidth = 4
-    framerate = 11025
-    nframes = 48
-    comptype = 'NONE'
-    compname = 'not compressed'
-    frames = bytes.fromhex("""\
-      022D65BCFFEB9D92 4B5A0F8000FA549C 3113C34004EE2BC0 80DCD680084303E0 \
-      CBDEC0C006B26140 48A9980003F2F8FC BFE8248001B07D92 036BFB60FE7B5D34 \
-      B8575600FA3EC920 B4B05500F3502BC0 29983000EBCB6240 1A5CA7A0E6D99A60 \
-      EDFA3E80E491BD40 C625EB80E27884A0 0E05A9A0E0B6CFE0 EF292940E0292280 \
-      5758D800E2706700 FB3557D8E83E1640 1377BF00EF840280 D82C5B80F7272A80 \
-      978F1600FB774560 F5F86510FC101364 086635A0FB9C4E20 DF30FC40FB40EE28 \
-      117FE0A0FA3438B0 3EE6B840FB5AC3F0 BC77A380FCB2F454 66D6DA80FF5F32B4 \
-      CF13B980041275B0 431D6980097A8C00 C1BB60000EC74E00 5120B98012A2BAA0 \
-      EEDF64C01754C060 820700001664B780 7FFFFFFF14453F40 800000001294E6E0 \
-      499C1B000EB3B270 52B73E000DBCA020 EFB2B2E00F5FD880 CE3CDB400FBE1270 \
-      E4B49CC00CEA2D90 6344A8800A5A7CA0 08C8FE800A1FFEE0 2BB986C00B0A0E00 \
-      51486F800E44E190 8BCC6480113B0580 B6F4EC000EEB3630 441317800A5B48A0 \
-      """)
-
-
-class SunauULAWTest(SunauTest, unittest.TestCase):
-    sndfilename = 'pluck-ulaw.au'
-    sndfilenframes = 3307
-    nchannels = 2
-    sampwidth = 2
-    framerate = 11025
-    nframes = 48
-    comptype = 'ULAW'
-    compname = 'CCITT G.711 u-law'
-    frames = bytes.fromhex("""\
-      022CFFE8 497C00F4 307C04DC 8284083C CB84069C 497C03DC BE8401AC 036CFE74 \
-      B684FA24 B684F344 2A7CEC04 19FCE704 EE04E504 C584E204 0E3CE104 EF04DF84 \
-      557CE204 FB24E804 12FCEF04 D784F744 9684FB64 F5C4FC24 083CFBA4 DF84FB24 \
-      11FCFA24 3E7CFB64 BA84FCB4 657CFF5C CF84041C 417C09BC C1840EBC 517C12FC \
-      EF0416FC 828415FC 7D7C13FC 828412FC 497C0EBC 517C0DBC F0040F3C CD840FFC \
-      E5040CBC 617C0A3C 08BC0A3C 2C7C0B3C 517C0E3C 8A8410FC B6840EBC 457C0A3C \
-      """)
-    if sys.byteorder != 'big':
-        frames = audioop.byteswap(frames, 2)
-
-
-class SunauLowLevelTest(unittest.TestCase):
-
-    def test_read_bad_magic_number(self):
-        b = b'SPA'
-        with self.assertRaises(EOFError):
-            sunau.open(io.BytesIO(b))
-        b = b'SPAM'
-        with self.assertRaisesRegex(sunau.Error, 'bad magic number'):
-            sunau.open(io.BytesIO(b))
-
-    def test_read_too_small_header(self):
-        b = struct.pack('>LLLLL', sunau.AUDIO_FILE_MAGIC, 20, 0,
-                        sunau.AUDIO_FILE_ENCODING_LINEAR_8, 11025)
-        with self.assertRaisesRegex(sunau.Error, 'header size too small'):
-            sunau.open(io.BytesIO(b))
-
-    def test_read_too_large_header(self):
-        b = struct.pack('>LLLLLL', sunau.AUDIO_FILE_MAGIC, 124, 0,
-                        sunau.AUDIO_FILE_ENCODING_LINEAR_8, 11025, 1)
-        b += b'\0' * 100
-        with self.assertRaisesRegex(sunau.Error, 'header size ridiculously large'):
-            sunau.open(io.BytesIO(b))
-
-    def test_read_wrong_encoding(self):
-        b = struct.pack('>LLLLLL', sunau.AUDIO_FILE_MAGIC, 24, 0, 0, 11025, 1)
-        with self.assertRaisesRegex(sunau.Error, r'encoding not \(yet\) supported'):
-            sunau.open(io.BytesIO(b))
-
-    def test_read_wrong_number_of_channels(self):
-        b = struct.pack('>LLLLLL', sunau.AUDIO_FILE_MAGIC, 24, 0,
-                        sunau.AUDIO_FILE_ENCODING_LINEAR_8, 11025, 0)
-        with self.assertRaisesRegex(sunau.Error, 'bad # of channels'):
-            sunau.open(io.BytesIO(b))
-
-
-if __name__ == "__main__":
-    unittest.main()
index 547fb50f5ecfdde9cad60360f97362a31abb68a4..980110646b294054a79eafb035b399cd623595b4 100644 (file)
@@ -326,7 +326,7 @@ documentation.
 
 Improved exceptions raised for invalid number of channels and sample width
 when read an audio file in modules :mod:`aifc`, :mod:`wave` and
-:mod:`sunau`.
+:mod:`!sunau`.
 
 ..
 
index 2564167cdf08955382dcb79b3027ace5bd87646a..75902b47169419c8c1c853463fa5d6146648942d 100644 (file)
@@ -5577,7 +5577,7 @@ documentation.
 
 Improved exceptions raised for invalid number of channels and sample width
 when read an audio file in modules :mod:`aifc`, :mod:`wave` and
-:mod:`sunau`.
+:mod:`!sunau`.
 
 ..
 
diff --git a/Misc/NEWS.d/next/Library/2023-05-24-14-58-13.gh-issue-104773.sQaXrY.rst b/Misc/NEWS.d/next/Library/2023-05-24-14-58-13.gh-issue-104773.sQaXrY.rst
new file mode 100644 (file)
index 0000000..fc103cd
--- /dev/null
@@ -0,0 +1,2 @@
+:pep:`594`: Remove the :mod:`!sunau` module, deprecated in Python 3.11.
+Patch by Victor Stinner.
index fe396a896ce34e2ae7715e5a5a53683e8bcd37c1..37d5c05579ebe1560acea1db9dc63d964fbeda4d 100644 (file)
@@ -248,7 +248,6 @@ static const char* _Py_stdlib_module_names[] = {
 "stringprep",
 "struct",
 "subprocess",
-"sunau",
 "symtable",
 "sys",
 "sysconfig",
index a2ec54ec9867a2b473d53bbadb8f06fc925881a2..47bc238c64819f5dce785938b733b002344d8d2a 100755 (executable)
@@ -84,7 +84,7 @@ OMIT_NETWORKING_FILES = (
 
 OMIT_MODULE_FILES = {
     "_asyncio": ["asyncio/"],
-    "audioop": ["aifc.py", "sunau.py", "wave.py"],
+    "audioop": ["aifc.py", "wave.py"],
     "_crypt": ["crypt.py"],
     "_curses": ["curses/"],
     "_ctypes": ["ctypes/"],