gh-104773: PEP 594: Remove the chunk module (#104868)

The module had no tests.
This commit is contained in:
Victor Stinner 2023-05-25 18:27:55 +02:00 committed by GitHub
parent f66be6b11a
commit 77d7ec5aa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 8 additions and 321 deletions

View File

@ -1,142 +0,0 @@
:mod:`chunk` --- Read IFF chunked data
======================================
.. module:: chunk
:synopsis: Module to read IFF chunks.
:deprecated:
.. moduleauthor:: Sjoerd Mullender <sjoerd@acm.org>
.. sectionauthor:: Sjoerd Mullender <sjoerd@acm.org>
**Source code:** :source:`Lib/chunk.py`
.. index::
single: Audio Interchange File Format
single: AIFF
single: AIFF-C
single: Real Media File Format
single: RMFF
.. deprecated-removed:: 3.11 3.13
The :mod:`chunk` module is deprecated
(see :pep:`PEP 594 <594#chunk>` for details).
--------------
This module provides an interface for reading files that use EA IFF 85 chunks.
[#]_ This format is used in at least the Audio Interchange File Format
(AIFF/AIFF-C) and the Real Media File Format (RMFF). The WAVE audio file format
is closely related and can also be read using this module.
A chunk has the following structure:
+---------+--------+-------------------------------+
| Offset | Length | Contents |
+=========+========+===============================+
| 0 | 4 | Chunk ID |
+---------+--------+-------------------------------+
| 4 | 4 | Size of chunk in big-endian |
| | | byte order, not including the |
| | | header |
+---------+--------+-------------------------------+
| 8 | *n* | Data bytes, where *n* is the |
| | | size given in the preceding |
| | | field |
+---------+--------+-------------------------------+
| 8 + *n* | 0 or 1 | Pad byte needed if *n* is odd |
| | | and chunk alignment is used |
+---------+--------+-------------------------------+
The ID is a 4-byte string which identifies the type of chunk.
The size field (a 32-bit value, encoded using big-endian byte order) gives the
size of the chunk data, not including the 8-byte header.
Usually an IFF-type file consists of one or more chunks. The proposed usage of
the :class:`Chunk` class defined here is to instantiate an instance at the start
of each chunk and read from the instance until it reaches the end, after which a
new instance can be instantiated. At the end of the file, creating a new
instance will fail with an :exc:`EOFError` exception.
.. class:: Chunk(file, align=True, bigendian=True, inclheader=False)
Class which represents a chunk. The *file* argument is expected to be a
file-like object. An instance of this class is specifically allowed. The
only method that is needed is :meth:`~io.IOBase.read`. If the methods
:meth:`~io.IOBase.seek` and :meth:`~io.IOBase.tell` are present and don't
raise an exception, they are also used.
If these methods are present and raise an exception, they are expected to not
have altered the object. If the optional argument *align* is true, chunks
are assumed to be aligned on 2-byte boundaries. If *align* is false, no
alignment is assumed. The default value is true. If the optional argument
*bigendian* is false, the chunk size is assumed to be in little-endian order.
This is needed for WAVE audio files. The default value is true. If the
optional argument *inclheader* is true, the size given in the chunk header
includes the size of the header. The default value is false.
A :class:`Chunk` object supports the following methods:
.. method:: getname()
Returns the name (ID) of the chunk. This is the first 4 bytes of the
chunk.
.. method:: getsize()
Returns the size of the chunk.
.. method:: close()
Close and skip to the end of the chunk. This does not close the
underlying file.
The remaining methods will raise :exc:`OSError` if called after the
:meth:`close` method has been called. Before Python 3.3, they used to
raise :exc:`IOError`, now an alias of :exc:`OSError`.
.. method:: isatty()
Returns ``False``.
.. method:: seek(pos, whence=0)
Set the chunk's current position. The *whence* argument is optional and
defaults to ``0`` (absolute file positioning); other values are ``1``
(seek relative to the current position) and ``2`` (seek relative to the
file's end). There is no return value. If the underlying file does not
allow seek, only forward seeks are allowed.
.. method:: tell()
Return the current position into the chunk.
.. method:: read(size=-1)
Read at most *size* bytes from the chunk (less if the read hits the end of
the chunk before obtaining *size* bytes). If the *size* argument is
negative or omitted, read all data until the end of the chunk. An empty
bytes object is returned when the end of the chunk is encountered
immediately.
.. method:: skip()
Skip to the end of the chunk. All further calls to :meth:`read` for the
chunk will return ``b''``. If you are not interested in the contents of
the chunk, this method should be called so that the file points to the
start of the next chunk.
.. rubric:: Footnotes
.. [#] "EA IFF 85" Standard for Interchange Format Files, Jerry Morrison, Electronic
Arts, January 1985.

View File

@ -10,6 +10,5 @@ backwards compatibility. They have been superseded by other modules.
.. toctree::
chunk.rst
imghdr.rst
optparse.rst

View File

@ -89,7 +89,6 @@ Doc/library/bisect.rst
Doc/library/bz2.rst
Doc/library/calendar.rst
Doc/library/cgi.rst
Doc/library/chunk.rst
Doc/library/cmath.rst
Doc/library/cmd.rst
Doc/library/code.rst

View File

@ -1031,7 +1031,7 @@ Module changes
Lots of improvements and bugfixes were made to Python's extensive standard
library; some of the affected modules include :mod:`readline`,
:mod:`ConfigParser`, :mod:`!cgi`, :mod:`calendar`, :mod:`posix`, :mod:`readline`,
:mod:`xmllib`, :mod:`!aifc`, :mod:`chunk, wave`, :mod:`random`, :mod:`shelve`,
:mod:`xmllib`, :mod:`!aifc`, :mod:`!chunk`, :mod:`wave`, :mod:`random`, :mod:`shelve`,
and :mod:`!nntplib`. Consult the CVS logs for the exact patch-by-patch details.
Brian Gallew contributed OpenSSL support for the :mod:`socket` module. OpenSSL

View File

@ -1731,7 +1731,7 @@ Modules
slated for removal in Python 3.13:
+---------------------+---------------------+---------------------+---------------------+---------------------+
| :mod:`!aifc` | :mod:`chunk` | :mod:`!msilib` | :mod:`!pipes` | :mod:`!telnetlib` |
| :mod:`!aifc` | :mod:`!chunk` | :mod:`!msilib` | :mod:`!pipes` | :mod:`!telnetlib` |
+---------------------+---------------------+---------------------+---------------------+---------------------+
| :mod:`!audioop` | :mod:`!crypt` | :mod:`!nis` | :mod:`!sndhdr` | :mod:`!uu` |
+---------------------+---------------------+---------------------+---------------------+---------------------+

View File

@ -922,7 +922,7 @@ Modules (see :pep:`594`):
* :mod:`!audioop`
* :mod:`!cgi`
* :mod:`!cgitb`
* :mod:`chunk`
* :mod:`!chunk`
* :mod:`!crypt`
* :mod:`imghdr`
* :mod:`!mailcap`

View File

@ -227,6 +227,9 @@ Removed
* :pep:`594`: Remove the :mod:`!audioop` module, deprecated in Python 3.11.
(Contributed by Victor Stinner in :gh:`104773`.)
* :pep:`594`: Remove the :mod:`!chunk` module, deprecated in Python 3.11.
(Contributed by Victor Stinner in :gh:`104773`.)
Porting to Python 3.13
======================

View File

@ -1,173 +0,0 @@
"""Simple class to read IFF chunks.
An IFF chunk (used in formats such as AIFF, TIFF, RMFF (RealMedia File
Format)) has the following structure:
+----------------+
| ID (4 bytes) |
+----------------+
| size (4 bytes) |
+----------------+
| data |
| ... |
+----------------+
The ID is a 4-byte string which identifies the type of chunk.
The size field (a 32-bit value, encoded using big-endian byte order)
gives the size of the whole chunk, including the 8-byte header.
Usually an IFF-type file consists of one or more chunks. The proposed
usage of the Chunk class defined here is to instantiate an instance at
the start of each chunk and read from the instance until it reaches
the end, after which a new instance can be instantiated. At the end
of the file, creating a new instance will fail with an EOFError
exception.
Usage:
while True:
try:
chunk = Chunk(file)
except EOFError:
break
chunktype = chunk.getname()
while True:
data = chunk.read(nbytes)
if not data:
pass
# do something with data
The interface is file-like. The implemented methods are:
read, close, seek, tell, isatty.
Extra methods are: skip() (called by close, skips to the end of the chunk),
getname() (returns the name (ID) of the chunk)
The __init__ method has one required argument, a file-like object
(including a chunk instance), and one optional argument, a flag which
specifies whether or not chunks are aligned on 2-byte boundaries. The
default is 1, i.e. aligned.
"""
import warnings
warnings._deprecated(__name__, remove=(3, 13))
class Chunk:
def __init__(self, file, align=True, bigendian=True, inclheader=False):
import struct
self.closed = False
self.align = align # whether to align to word (2-byte) boundaries
if bigendian:
strflag = '>'
else:
strflag = '<'
self.file = file
self.chunkname = file.read(4)
if len(self.chunkname) < 4:
raise EOFError
try:
self.chunksize = struct.unpack_from(strflag+'L', file.read(4))[0]
except struct.error:
raise EOFError from None
if inclheader:
self.chunksize = self.chunksize - 8 # subtract header
self.size_read = 0
try:
self.offset = self.file.tell()
except (AttributeError, OSError):
self.seekable = False
else:
self.seekable = True
def getname(self):
"""Return the name (ID) of the current chunk."""
return self.chunkname
def getsize(self):
"""Return the size of the current chunk."""
return self.chunksize
def close(self):
if not self.closed:
try:
self.skip()
finally:
self.closed = True
def isatty(self):
if self.closed:
raise ValueError("I/O operation on closed file")
return False
def seek(self, pos, whence=0):
"""Seek to specified position into the chunk.
Default position is 0 (start of chunk).
If the file is not seekable, this will result in an error.
"""
if self.closed:
raise ValueError("I/O operation on closed file")
if not self.seekable:
raise OSError("cannot seek")
if whence == 1:
pos = pos + self.size_read
elif whence == 2:
pos = pos + self.chunksize
if pos < 0 or pos > self.chunksize:
raise RuntimeError
self.file.seek(self.offset + pos, 0)
self.size_read = pos
def tell(self):
if self.closed:
raise ValueError("I/O operation on closed file")
return self.size_read
def read(self, size=-1):
"""Read at most size bytes from the chunk.
If size is omitted or negative, read until the end
of the chunk.
"""
if self.closed:
raise ValueError("I/O operation on closed file")
if self.size_read >= self.chunksize:
return b''
if size < 0:
size = self.chunksize - self.size_read
if size > self.chunksize - self.size_read:
size = self.chunksize - self.size_read
data = self.file.read(size)
self.size_read = self.size_read + len(data)
if self.size_read == self.chunksize and \
self.align and \
(self.chunksize & 1):
dummy = self.file.read(1)
self.size_read = self.size_read + len(dummy)
return data
def skip(self):
"""Skip the rest of the chunk.
If you are not interested in the contents of the chunk,
this method should be called so that the file points to
the start of the next chunk.
"""
if self.closed:
raise ValueError("I/O operation on closed file")
if self.seekable:
try:
n = self.chunksize - self.size_read
# maybe fix alignment
if self.align and (self.chunksize & 1):
n = n + 1
self.file.seek(n, 1)
self.size_read = self.size_read + n
return
except OSError:
pass
while self.size_read < self.chunksize:
n = min(8192, self.chunksize - self.size_read)
dummy = self.read(n)
if not dummy:
raise EOFError

View File

@ -0,0 +1,2 @@
:pep:`594`: Remove the :mod:`!chunk` module, deprecated in Python 3.11.
Patch by Victor Stinner.

View File

@ -103,7 +103,6 @@ static const char* _Py_stdlib_module_names[] = {
"bz2",
"cProfile",
"calendar",
"chunk",
"cmath",
"cmd",
"code",