Skip to content

Commit

Permalink
gh-47061: Deprecate chunk (GH-91419)
Browse files Browse the repository at this point in the history
  • Loading branch information
brettcannon committed Apr 11, 2022
1 parent 8be8949 commit 3869a83
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 4 deletions.
1 change: 1 addition & 0 deletions Doc/whatsnew/3.11.rst
Expand Up @@ -850,6 +850,7 @@ Deprecated
* :mod:`audioop`
* :mod:`cgi`
* :mod:`cgitb`
* :mod:`chunk`

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

Expand Down
4 changes: 3 additions & 1 deletion Lib/aifc.py
Expand Up @@ -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',
Expand Down
4 changes: 4 additions & 0 deletions Lib/chunk.py
Expand Up @@ -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
Expand Down
118 changes: 115 additions & 3 deletions Lib/wave.py
Expand Up @@ -71,7 +71,6 @@
is destroyed.
"""

from chunk import Chunk
from collections import namedtuple
import builtins
import struct
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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':
Expand All @@ -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()
Expand Down
@@ -0,0 +1 @@
Deprecate the chunk module.

0 comments on commit 3869a83

Please sign in to comment.