Skip to content

Commit 3869a83

Browse files
authored
gh-47061: Deprecate chunk (GH-91419)
1 parent 8be8949 commit 3869a83

File tree

5 files changed

+124
-4
lines changed

5 files changed

+124
-4
lines changed

Doc/whatsnew/3.11.rst

+1
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ Deprecated
850850
* :mod:`audioop`
851851
* :mod:`cgi`
852852
* :mod:`cgitb`
853+
* :mod:`chunk`
853854

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

Lib/aifc.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ def _write_float(f, x):
255255
_write_ulong(f, himant)
256256
_write_ulong(f, lomant)
257257

258-
from chunk import Chunk
258+
with warnings.catch_warnings():
259+
warnings.simplefilter("ignore", DeprecationWarning)
260+
from chunk import Chunk
259261
from collections import namedtuple
260262

261263
_aifc_params = namedtuple('_aifc_params',

Lib/chunk.py

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
default is 1, i.e. aligned.
4949
"""
5050

51+
import warnings
52+
53+
warnings._deprecated(__name__, remove=(3, 13))
54+
5155
class Chunk:
5256
def __init__(self, file, align=True, bigendian=True, inclheader=False):
5357
import struct

Lib/wave.py

+115-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@
7171
is destroyed.
7272
"""
7373

74-
from chunk import Chunk
7574
from collections import namedtuple
7675
import builtins
7776
import struct
@@ -100,6 +99,119 @@ def _byteswap(data, width):
10099
return bytes(swapped_data)
101100

102101

102+
class _Chunk:
103+
def __init__(self, file, align=True, bigendian=True, inclheader=False):
104+
import struct
105+
self.closed = False
106+
self.align = align # whether to align to word (2-byte) boundaries
107+
if bigendian:
108+
strflag = '>'
109+
else:
110+
strflag = '<'
111+
self.file = file
112+
self.chunkname = file.read(4)
113+
if len(self.chunkname) < 4:
114+
raise EOFError
115+
try:
116+
self.chunksize = struct.unpack_from(strflag+'L', file.read(4))[0]
117+
except struct.error:
118+
raise EOFError from None
119+
if inclheader:
120+
self.chunksize = self.chunksize - 8 # subtract header
121+
self.size_read = 0
122+
try:
123+
self.offset = self.file.tell()
124+
except (AttributeError, OSError):
125+
self.seekable = False
126+
else:
127+
self.seekable = True
128+
129+
def getname(self):
130+
"""Return the name (ID) of the current chunk."""
131+
return self.chunkname
132+
133+
def close(self):
134+
if not self.closed:
135+
try:
136+
self.skip()
137+
finally:
138+
self.closed = True
139+
140+
def seek(self, pos, whence=0):
141+
"""Seek to specified position into the chunk.
142+
Default position is 0 (start of chunk).
143+
If the file is not seekable, this will result in an error.
144+
"""
145+
146+
if self.closed:
147+
raise ValueError("I/O operation on closed file")
148+
if not self.seekable:
149+
raise OSError("cannot seek")
150+
if whence == 1:
151+
pos = pos + self.size_read
152+
elif whence == 2:
153+
pos = pos + self.chunksize
154+
if pos < 0 or pos > self.chunksize:
155+
raise RuntimeError
156+
self.file.seek(self.offset + pos, 0)
157+
self.size_read = pos
158+
159+
def tell(self):
160+
if self.closed:
161+
raise ValueError("I/O operation on closed file")
162+
return self.size_read
163+
164+
def read(self, size=-1):
165+
"""Read at most size bytes from the chunk.
166+
If size is omitted or negative, read until the end
167+
of the chunk.
168+
"""
169+
170+
if self.closed:
171+
raise ValueError("I/O operation on closed file")
172+
if self.size_read >= self.chunksize:
173+
return b''
174+
if size < 0:
175+
size = self.chunksize - self.size_read
176+
if size > self.chunksize - self.size_read:
177+
size = self.chunksize - self.size_read
178+
data = self.file.read(size)
179+
self.size_read = self.size_read + len(data)
180+
if self.size_read == self.chunksize and \
181+
self.align and \
182+
(self.chunksize & 1):
183+
dummy = self.file.read(1)
184+
self.size_read = self.size_read + len(dummy)
185+
return data
186+
187+
def skip(self):
188+
"""Skip the rest of the chunk.
189+
If you are not interested in the contents of the chunk,
190+
this method should be called so that the file points to
191+
the start of the next chunk.
192+
"""
193+
194+
if self.closed:
195+
raise ValueError("I/O operation on closed file")
196+
if self.seekable:
197+
try:
198+
n = self.chunksize - self.size_read
199+
# maybe fix alignment
200+
if self.align and (self.chunksize & 1):
201+
n = n + 1
202+
self.file.seek(n, 1)
203+
self.size_read = self.size_read + n
204+
return
205+
except OSError:
206+
pass
207+
while self.size_read < self.chunksize:
208+
n = min(8192, self.chunksize - self.size_read)
209+
dummy = self.read(n)
210+
if not dummy:
211+
raise EOFError
212+
213+
214+
103215
class Wave_read:
104216
"""Variables used in this class:
105217
@@ -134,7 +246,7 @@ class Wave_read:
134246
def initfp(self, file):
135247
self._convert = None
136248
self._soundpos = 0
137-
self._file = Chunk(file, bigendian = 0)
249+
self._file = _Chunk(file, bigendian = 0)
138250
if self._file.getname() != b'RIFF':
139251
raise Error('file does not start with RIFF id')
140252
if self._file.read(4) != b'WAVE':
@@ -144,7 +256,7 @@ def initfp(self, file):
144256
while 1:
145257
self._data_seek_needed = 1
146258
try:
147-
chunk = Chunk(self._file, bigendian = 0)
259+
chunk = _Chunk(self._file, bigendian = 0)
148260
except EOFError:
149261
break
150262
chunkname = chunk.getname()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Deprecate the chunk module.

0 commit comments

Comments
 (0)