[Python-checkins] gh-47061: Deprecate `chunk` (GH-91419)

brettcannon webhook-mailer at python.org
Mon Apr 11 18:02:45 EDT 2022


https://github.com/python/cpython/commit/3869a839d5f14a91978c6158a03c68fac5e938dd
commit: 3869a839d5f14a91978c6158a03c68fac5e938dd
branch: main
author: Brett Cannon <brett at python.org>
committer: brettcannon <brett at python.org>
date: 2022-04-11T15:02:41-07:00
summary:

gh-47061: Deprecate `chunk` (GH-91419)

files:
A Misc/NEWS.d/next/Library/2022-04-10-11-11-33.gh-issue-91217.K82AuH.rst
M Doc/whatsnew/3.11.rst
M Lib/aifc.py
M Lib/chunk.py
M Lib/wave.py

diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index df0b0a7fbebec..cc358b4ffdb2a 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -850,6 +850,7 @@ Deprecated
   * :mod:`audioop`
   * :mod:`cgi`
   * :mod:`cgitb`
+  * :mod:`chunk`
 
   (Contributed by Brett Cannon in :issue:`47061`.)
 
diff --git a/Lib/aifc.py b/Lib/aifc.py
index 314cfd230d6cb..5254987e22bc1 100644
--- a/Lib/aifc.py
+++ b/Lib/aifc.py
@@ -255,7 +255,9 @@ def _write_float(f, x):
     _write_ulong(f, himant)
     _write_ulong(f, lomant)
 
-from chunk import Chunk
+with warnings.catch_warnings():
+    warnings.simplefilter("ignore", DeprecationWarning)
+    from chunk import Chunk
 from collections import namedtuple
 
 _aifc_params = namedtuple('_aifc_params',
diff --git a/Lib/chunk.py b/Lib/chunk.py
index 870c39fe7f503..618781efd11e7 100644
--- a/Lib/chunk.py
+++ b/Lib/chunk.py
@@ -48,6 +48,10 @@
 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
diff --git a/Lib/wave.py b/Lib/wave.py
index 47a233df0a3ab..9a4557487b6e6 100644
--- a/Lib/wave.py
+++ b/Lib/wave.py
@@ -71,7 +71,6 @@
 is destroyed.
 """
 
-from chunk import Chunk
 from collections import namedtuple
 import builtins
 import struct
@@ -100,6 +99,119 @@ def _byteswap(data, width):
     return bytes(swapped_data)
 
 
+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 close(self):
+        if not self.closed:
+            try:
+                self.skip()
+            finally:
+                self.closed = True
+
+    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
+
+
+
 class Wave_read:
     """Variables used in this class:
 
@@ -134,7 +246,7 @@ class Wave_read:
     def initfp(self, file):
         self._convert = None
         self._soundpos = 0
-        self._file = Chunk(file, bigendian = 0)
+        self._file = _Chunk(file, bigendian = 0)
         if self._file.getname() != b'RIFF':
             raise Error('file does not start with RIFF id')
         if self._file.read(4) != b'WAVE':
@@ -144,7 +256,7 @@ def initfp(self, file):
         while 1:
             self._data_seek_needed = 1
             try:
-                chunk = Chunk(self._file, bigendian = 0)
+                chunk = _Chunk(self._file, bigendian = 0)
             except EOFError:
                 break
             chunkname = chunk.getname()
diff --git a/Misc/NEWS.d/next/Library/2022-04-10-11-11-33.gh-issue-91217.K82AuH.rst b/Misc/NEWS.d/next/Library/2022-04-10-11-11-33.gh-issue-91217.K82AuH.rst
new file mode 100644
index 0000000000000..0181bbcce9cd8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-04-10-11-11-33.gh-issue-91217.K82AuH.rst
@@ -0,0 +1 @@
+Deprecate the chunk module.



More information about the Python-checkins mailing list