diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index c1cd215c3ff..44a0a24ff5f 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -51,7 +51,8 @@ Module :mod:`aifc` defines the following function: used for writing, the file object should be seekable, unless you know ahead of time how many samples you are going to write in total and use :meth:`writeframesraw` and :meth:`setnframes`. - Objects returned by :func:`.open` also supports the :keyword:`with` statement. + The :func:`.open` function may be used in a :keyword:`with` statement. When + the :keyword:`with` block completes, the :meth:`~aifc.close` method is called. .. versionchanged:: 3.4 Support for the :keyword:`with` statement was added. diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index 2e64d00305d..c52af89774c 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -39,6 +39,11 @@ The :mod:`wave` module defines the following function and exception: :meth:`close` method is called; it is the caller's responsibility to close the file object. + The :func:`.open` function may be used in a :keyword:`with` statement. When + the :keyword:`with` block completes, the :meth:`Wave_read.close() + ` or :meth:`Wave_write.close() + ` method is called. + .. function:: openfp(file, mode) diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 17cec3f2ad6..2575170f442 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -239,8 +239,11 @@ wave The :meth:`~wave.getparams` method now returns a namedtuple rather than a plain tuple. (Contributed by Claudiu Popa in :issue:`17487`.) +:meth:`wave.open` now supports the context manager protocol. (Contributed +by Claudiu Popa in :issue:`17616`.) + stat ---- +---- The stat module is now backed by a C implementation in :mod:`_stat`. A C implementation is required as most of the values aren't standardized and diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index 581d9739d54..e9ee15ca9ac 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -1,7 +1,5 @@ -from test.support import TESTFN, run_unittest -import os +from test.support import TESTFN, unlink import wave -import struct import unittest nchannels = 2 @@ -17,10 +15,7 @@ class TestWave(unittest.TestCase): def tearDown(self): if self.f is not None: self.f.close() - try: - os.remove(TESTFN) - except OSError: - pass + unlink(TESTFN) def test_it(self, test_rounding=False): self.f = wave.open(TESTFN, 'wb') @@ -74,9 +69,23 @@ class TestWave(unittest.TestCase): self.assertEqual(params.comptype, self.f.getcomptype()) self.assertEqual(params.compname, self.f.getcompname()) + def test_context_manager(self): + self.f = wave.open(TESTFN, 'wb') + self.f.setnchannels(nchannels) + self.f.setsampwidth(sampwidth) + self.f.setframerate(framerate) + self.f.close() + + with wave.open(TESTFN) as f: + self.assertFalse(f.getfp().closed) + self.assertIs(f.getfp(), None) + + with open(TESTFN, 'wb') as testfile: + with self.assertRaises(wave.Error): + with wave.open(testfile, 'wb'): + pass + self.assertEqual(testfile.closed, False) -def test_main(): - run_unittest(TestWave) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/wave.py b/Lib/wave.py index ea410c12d78..695a4be8384 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -167,6 +167,13 @@ class Wave_read: def __del__(self): self.close() + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + # # User visible methods. # @@ -323,6 +330,12 @@ class Wave_write: def __del__(self): self.close() + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + # # User visible methods. # diff --git a/Misc/NEWS b/Misc/NEWS index d44a0433be8..a4aabbeba4b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -173,6 +173,8 @@ Core and Builtins Library ------- +- Issue #17616: wave.open now supports the context manager protocol. + - Issue #18599: Fix name attribute of _sha1.sha1() object. It now returns 'SHA1' instead of 'SHA'.