merge
This commit is contained in:
commit
e1d5e543e4
|
@ -374,6 +374,8 @@ 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`.)
|
plain tuple. (Contributed by Claudiu Popa in :issue:`18901`.)
|
||||||
|
|
||||||
|
:meth:`sunau.open` now supports the context manager protocol (:issue:`18878`).
|
||||||
|
|
||||||
|
|
||||||
urllib
|
urllib
|
||||||
------
|
------
|
||||||
|
|
31
Lib/sunau.py
31
Lib/sunau.py
|
@ -168,6 +168,12 @@ class Au_read:
|
||||||
if self._file:
|
if self._file:
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.close()
|
||||||
|
|
||||||
def initfp(self, file):
|
def initfp(self, file):
|
||||||
self._file = file
|
self._file = file
|
||||||
self._soundpos = 0
|
self._soundpos = 0
|
||||||
|
@ -303,6 +309,12 @@ class Au_write:
|
||||||
self.close()
|
self.close()
|
||||||
self._file = None
|
self._file = None
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.close()
|
||||||
|
|
||||||
def initfp(self, file):
|
def initfp(self, file):
|
||||||
self._file = file
|
self._file = file
|
||||||
self._framerate = 0
|
self._framerate = 0
|
||||||
|
@ -410,14 +422,17 @@ class Au_write:
|
||||||
self._patchheader()
|
self._patchheader()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self._ensure_header_written()
|
if self._file:
|
||||||
if self._nframeswritten != self._nframes or \
|
try:
|
||||||
self._datalength != self._datawritten:
|
self._ensure_header_written()
|
||||||
self._patchheader()
|
if self._nframeswritten != self._nframes or \
|
||||||
self._file.flush()
|
self._datalength != self._datawritten:
|
||||||
if self._opened and self._file:
|
self._patchheader()
|
||||||
self._file.close()
|
self._file.flush()
|
||||||
self._file = None
|
finally:
|
||||||
|
if self._opened and self._file:
|
||||||
|
self._file.close()
|
||||||
|
self._file = None
|
||||||
|
|
||||||
#
|
#
|
||||||
# private methods
|
# private methods
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from test.support import run_unittest, TESTFN
|
from test.support import TESTFN, unlink
|
||||||
import unittest
|
import unittest
|
||||||
import pickle
|
import pickle
|
||||||
import os
|
import os
|
||||||
|
@ -18,10 +18,7 @@ class SunAUTest(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
if self.f is not None:
|
if self.f is not None:
|
||||||
self.f.close()
|
self.f.close()
|
||||||
try:
|
unlink(TESTFN)
|
||||||
os.remove(TESTFN)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_lin(self):
|
def test_lin(self):
|
||||||
self.f = sunau.open(TESTFN, 'w')
|
self.f = sunau.open(TESTFN, 'w')
|
||||||
|
@ -84,9 +81,49 @@ class SunAUTest(unittest.TestCase):
|
||||||
dump = pickle.dumps(params)
|
dump = pickle.dumps(params)
|
||||||
self.assertEqual(pickle.loads(dump), params)
|
self.assertEqual(pickle.loads(dump), params)
|
||||||
|
|
||||||
|
def test_write_context_manager_calls_close(self):
|
||||||
|
# Close checks for a minimum header and will raise an error
|
||||||
|
# if it is not set, so this proves that close is called.
|
||||||
|
with self.assertRaises(sunau.Error):
|
||||||
|
with sunau.open(TESTFN, 'wb') as f:
|
||||||
|
pass
|
||||||
|
with self.assertRaises(sunau.Error):
|
||||||
|
with open(TESTFN, 'wb') as testfile:
|
||||||
|
with sunau.open(testfile):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_context_manager_with_open_file(self):
|
||||||
|
with open(TESTFN, 'wb') as testfile:
|
||||||
|
with sunau.open(testfile) as f:
|
||||||
|
f.setnchannels(nchannels)
|
||||||
|
f.setsampwidth(sampwidth)
|
||||||
|
f.setframerate(framerate)
|
||||||
|
self.assertFalse(testfile.closed)
|
||||||
|
with open(TESTFN, 'rb') as testfile:
|
||||||
|
with sunau.open(testfile) as f:
|
||||||
|
self.assertFalse(f.getfp().closed)
|
||||||
|
params = f.getparams()
|
||||||
|
self.assertEqual(params[0], nchannels)
|
||||||
|
self.assertEqual(params[1], sampwidth)
|
||||||
|
self.assertEqual(params[2], framerate)
|
||||||
|
self.assertIsNone(f.getfp())
|
||||||
|
self.assertFalse(testfile.closed)
|
||||||
|
|
||||||
|
def test_context_manager_with_filename(self):
|
||||||
|
# If the file doesn't get closed, this test won't fail, but it will
|
||||||
|
# produce a resource leak warning.
|
||||||
|
with sunau.open(TESTFN, 'wb') as f:
|
||||||
|
f.setnchannels(nchannels)
|
||||||
|
f.setsampwidth(sampwidth)
|
||||||
|
f.setframerate(framerate)
|
||||||
|
with sunau.open(TESTFN) as f:
|
||||||
|
self.assertFalse(f.getfp().closed)
|
||||||
|
params = f.getparams()
|
||||||
|
self.assertEqual(params[0], nchannels)
|
||||||
|
self.assertEqual(params[1], sampwidth)
|
||||||
|
self.assertEqual(params[2], framerate)
|
||||||
|
self.assertIsNone(f.getfp())
|
||||||
|
|
||||||
def test_main():
|
|
||||||
run_unittest(SunAUTest)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -54,6 +54,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #18878: sunau.open now supports the context manager protocol. Based on
|
||||||
|
patches by Claudiu Popa and R. David Murray.
|
||||||
|
|
||||||
- Issue #18909: Fix _tkinter.tkapp.interpaddr() on Windows 64-bit, don't cast
|
- Issue #18909: Fix _tkinter.tkapp.interpaddr() on Windows 64-bit, don't cast
|
||||||
64-bit pointer to long (32 bits).
|
64-bit pointer to long (32 bits).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue