From 1e908af3354e20e18dfdcf30bc8aee6ab53ab1ee Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 23 Oct 2010 17:31:52 +0000 Subject: [PATCH] #6518: enable context manager protocol for ossaudiodev types. --- Doc/library/ossaudiodev.rst | 9 +++++++++ Lib/test/test_ossaudiodev.py | 10 ++++++---- Misc/NEWS | 2 ++ Modules/ossaudiodev.c | 25 +++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index 3128b0aa79e..3b5a7e4212d 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -159,6 +159,11 @@ and (read-only) attributes: is only useful in non-blocking mode. Has no return value, since the amount of data written is always equal to the amount of data supplied. +.. versionchanged:: 3.2 + Audio device objects also support the context manager protocol, i.e. they can + be used in a :keyword:`with` statement. + + The following methods each map to exactly one :func:`ioctl` system call. The correspondence is obvious: for example, :meth:`setfmt` corresponds to the ``SNDCTL_DSP_SETFMT`` ioctl, and :meth:`sync` to ``SNDCTL_DSP_SYNC`` (this can @@ -346,6 +351,10 @@ The mixer object provides two file-like methods: Returns the file handle number of the open mixer device file. +.. versionchanged:: 3.2 + Mixer objects also support the context manager protocol. + + The remaining methods are specific to audio mixing: diff --git a/Lib/test/test_ossaudiodev.py b/Lib/test/test_ossaudiodev.py index 5dea640d892..9cb89d69a6d 100644 --- a/Lib/test/test_ossaudiodev.py +++ b/Lib/test/test_ossaudiodev.py @@ -162,11 +162,13 @@ class OSSAudioDevTests(unittest.TestCase): def test_mixer_methods(self): # Issue #8139: ossaudiodev didn't initialize its types properly, # therefore some methods were unavailable. - mixer = ossaudiodev.openmixer() - try: + with ossaudiodev.openmixer() as mixer: self.assertGreaterEqual(mixer.fileno(), 0) - finally: - mixer.close() + + def test_with(self): + with ossaudiodev.open('w') as dsp: + pass + self.assertTrue(dsp.closed) def test_main(): diff --git a/Misc/NEWS b/Misc/NEWS index 71a4509ce62..1f3a754e5c6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -126,6 +126,8 @@ Library Extensions ---------- +- Issue #6518: Support context manager protcol for ossaudiodev types. + - Issue #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY. - Issue #9054: Fix a crash occurring when using the pyexpat module diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index 5c990eff850..2c9d797472a 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -469,6 +469,23 @@ oss_close(oss_audio_t *self, PyObject *unused) return Py_None; } +static PyObject * +oss_self(PyObject *self) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +oss_exit(PyObject *self, PyObject *unused) +{ + PyObject *ret = PyObject_CallMethod(self, "close", NULL); + if (!ret) + return NULL; + Py_DECREF(ret); + Py_RETURN_NONE; +} + static PyObject * oss_fileno(oss_audio_t *self, PyObject *unused) { @@ -782,6 +799,10 @@ static PyMethodDef oss_methods[] = { /* Aliases for backwards compatibility */ { "flush", (PyCFunction)oss_sync, METH_VARARGS }, + /* Support for the context manager protocol */ + { "__enter__", oss_self, METH_NOARGS }, + { "__exit__", oss_exit, METH_VARARGS }, + { NULL, NULL} /* sentinel */ }; @@ -790,6 +811,10 @@ static PyMethodDef oss_mixer_methods[] = { { "close", (PyCFunction)oss_mixer_close, METH_NOARGS }, { "fileno", (PyCFunction)oss_mixer_fileno, METH_NOARGS }, + /* Support for the context manager protocol */ + { "__enter__", oss_self, METH_NOARGS }, + { "__exit__", oss_exit, METH_VARARGS }, + /* Simple ioctl wrappers */ { "controls", (PyCFunction)oss_mixer_controls, METH_VARARGS }, { "stereocontrols", (PyCFunction)oss_mixer_stereocontrols, METH_VARARGS},