diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index 7abfac97e53..13d7b7cc115 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -692,6 +692,14 @@ Added the 64-bit integer type :data:`REG_QWORD `. (Contributed by Clement Rouault in :issue:`23026`.) +winsound +-------- + +Allowed keyword arguments to be passed to :func:`Beep `, +:func:`MessageBeep `, and :func:`PlaySound +` (:issue:`27982`). + + zipfile ------- diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index 1cfef779d67..179e069a1cc 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -51,6 +51,10 @@ class BeepTest(unittest.TestCase): for i in range(100, 2000, 100): safe_Beep(i, 75) + def test_keyword_args(self): + safe_Beep(duration=75, frequency=2000) + + class MessageBeepTest(unittest.TestCase): def tearDown(self): @@ -76,6 +80,9 @@ class MessageBeepTest(unittest.TestCase): def test_question(self): safe_MessageBeep(winsound.MB_ICONQUESTION) + def test_keyword_args(self): + safe_MessageBeep(type=winsound.MB_OK) + class PlaySoundTest(unittest.TestCase): @@ -92,6 +99,9 @@ class PlaySoundTest(unittest.TestCase): winsound.SND_MEMORY) self.assertRaises(TypeError, winsound.PlaySound, 1, 0) + def test_keyword_args(self): + safe_PlaySound(flags=winsound.SND_ALIAS, sound="SystemExit") + def test_snd_memory(self): with open(support.findfile('pluck-pcm8.wav', subdir='audiodata'), 'rb') as f: diff --git a/Misc/NEWS b/Misc/NEWS index eee58d388e2..69780285a0d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -215,6 +215,9 @@ Build Windows ------- +- Issue #27982: The functions of the winsound module now accept keyword + arguments. + - Issue #20366: Build full text search support into SQLite on Windows. - Issue #27756: Adds new icons for Python files and processes on Windows. diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h index a4c393856f5..766479ada2d 100644 --- a/PC/clinic/winsound.c.h +++ b/PC/clinic/winsound.c.h @@ -3,7 +3,7 @@ preserve [clinic start generated code]*/ PyDoc_STRVAR(winsound_PlaySound__doc__, -"PlaySound($module, sound, flags, /)\n" +"PlaySound($module, /, sound, flags)\n" "--\n" "\n" "A wrapper around the Windows PlaySound API.\n" @@ -14,19 +14,21 @@ PyDoc_STRVAR(winsound_PlaySound__doc__, " Flag values, ored together. See module documentation."); #define WINSOUND_PLAYSOUND_METHODDEF \ - {"PlaySound", (PyCFunction)winsound_PlaySound, METH_VARARGS, winsound_PlaySound__doc__}, + {"PlaySound", (PyCFunction)winsound_PlaySound, METH_VARARGS|METH_KEYWORDS, winsound_PlaySound__doc__}, static PyObject * winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags); static PyObject * -winsound_PlaySound(PyObject *module, PyObject *args) +winsound_PlaySound(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"sound", "flags", NULL}; + static _PyArg_Parser _parser = {"Oi:PlaySound", _keywords, 0}; PyObject *sound; int flags; - if (!PyArg_ParseTuple(args, "Oi:PlaySound", + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, &sound, &flags)) { goto exit; } @@ -37,7 +39,7 @@ exit: } PyDoc_STRVAR(winsound_Beep__doc__, -"Beep($module, frequency, duration, /)\n" +"Beep($module, /, frequency, duration)\n" "--\n" "\n" "A wrapper around the Windows Beep API.\n" @@ -49,19 +51,21 @@ PyDoc_STRVAR(winsound_Beep__doc__, " How long the sound should play, in milliseconds."); #define WINSOUND_BEEP_METHODDEF \ - {"Beep", (PyCFunction)winsound_Beep, METH_VARARGS, winsound_Beep__doc__}, + {"Beep", (PyCFunction)winsound_Beep, METH_VARARGS|METH_KEYWORDS, winsound_Beep__doc__}, static PyObject * winsound_Beep_impl(PyObject *module, int frequency, int duration); static PyObject * -winsound_Beep(PyObject *module, PyObject *args) +winsound_Beep(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"frequency", "duration", NULL}; + static _PyArg_Parser _parser = {"ii:Beep", _keywords, 0}; int frequency; int duration; - if (!PyArg_ParseTuple(args, "ii:Beep", + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, &frequency, &duration)) { goto exit; } @@ -72,7 +76,7 @@ exit: } PyDoc_STRVAR(winsound_MessageBeep__doc__, -"MessageBeep($module, x=MB_OK, /)\n" +"MessageBeep($module, /, type=MB_OK)\n" "--\n" "\n" "Call Windows MessageBeep(x).\n" @@ -80,24 +84,26 @@ PyDoc_STRVAR(winsound_MessageBeep__doc__, "x defaults to MB_OK."); #define WINSOUND_MESSAGEBEEP_METHODDEF \ - {"MessageBeep", (PyCFunction)winsound_MessageBeep, METH_VARARGS, winsound_MessageBeep__doc__}, + {"MessageBeep", (PyCFunction)winsound_MessageBeep, METH_VARARGS|METH_KEYWORDS, winsound_MessageBeep__doc__}, static PyObject * -winsound_MessageBeep_impl(PyObject *module, int x); +winsound_MessageBeep_impl(PyObject *module, int type); static PyObject * -winsound_MessageBeep(PyObject *module, PyObject *args) +winsound_MessageBeep(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - int x = MB_OK; + static const char * const _keywords[] = {"type", NULL}; + static _PyArg_Parser _parser = {"|i:MessageBeep", _keywords, 0}; + int type = MB_OK; - if (!PyArg_ParseTuple(args, "|i:MessageBeep", - &x)) { + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &type)) { goto exit; } - return_value = winsound_MessageBeep_impl(module, x); + return_value = winsound_MessageBeep_impl(module, type); exit: return return_value; } -/*[clinic end generated code: output=b999334e2e444ad2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=40b3d3ef2faefb15 input=a9049054013a1b77]*/ diff --git a/PC/winsound.c b/PC/winsound.c index 7e06b7bd92b..7feebcbcf43 100644 --- a/PC/winsound.c +++ b/PC/winsound.c @@ -52,7 +52,7 @@ PyDoc_STRVAR(sound_module_doc, "SND_NOWAIT - Return immediately if the sound driver is busy\n" // Without any errors "\n" "Beep(frequency, duration) - Make a beep through the PC speaker.\n" -"MessageBeep(x) - Call Windows MessageBeep."); +"MessageBeep(type) - Call Windows MessageBeep."); /*[clinic input] module winsound @@ -68,14 +68,13 @@ winsound.PlaySound The sound to play; a filename, data, or None. flags: int Flag values, ored together. See module documentation. - / A wrapper around the Windows PlaySound API. [clinic start generated code]*/ static PyObject * winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags) -/*[clinic end generated code: output=49a0fd16a372ebeb input=7bdf637f10201d37]*/ +/*[clinic end generated code: output=49a0fd16a372ebeb input=c63e1f2d848da2f2]*/ { int ok; wchar_t *wsound; @@ -132,14 +131,13 @@ winsound.Beep Must be in the range 37 through 32,767. duration: int How long the sound should play, in milliseconds. - / A wrapper around the Windows Beep API. [clinic start generated code]*/ static PyObject * winsound_Beep_impl(PyObject *module, int frequency, int duration) -/*[clinic end generated code: output=f32382e52ee9b2fb input=628a99d2ddf73798]*/ +/*[clinic end generated code: output=f32382e52ee9b2fb input=40e360cfa00a5cf0]*/ { BOOL ok; @@ -163,8 +161,7 @@ winsound_Beep_impl(PyObject *module, int frequency, int duration) /*[clinic input] winsound.MessageBeep - x: int(c_default="MB_OK") = MB_OK - / + type: int(c_default="MB_OK") = MB_OK Call Windows MessageBeep(x). @@ -172,13 +169,13 @@ x defaults to MB_OK. [clinic start generated code]*/ static PyObject * -winsound_MessageBeep_impl(PyObject *module, int x) -/*[clinic end generated code: output=1ad89e4d8d30a957 input=a776c8a85c9853f6]*/ +winsound_MessageBeep_impl(PyObject *module, int type) +/*[clinic end generated code: output=120875455121121f input=db185f741ae21401]*/ { BOOL ok; Py_BEGIN_ALLOW_THREADS - ok = MessageBeep(x); + ok = MessageBeep(type); Py_END_ALLOW_THREADS if (!ok) {