Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Lib/test/test_winsound.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Ridiculously simple test of the winsound module for Windows.

import functools
import pathlib
import time
import unittest

Expand Down Expand Up @@ -84,6 +85,13 @@ def test_keyword_args(self):
safe_MessageBeep(type=winsound.MB_OK)


# A class for testing winsound when the given path resolves
# to bytes rather than str.
class BytesPath(pathlib.WindowsPath):
def __fspath__(self):
return bytes(super().__fspath__(), 'UTF-8')


class PlaySoundTest(unittest.TestCase):

def test_errors(self):
Expand Down Expand Up @@ -116,6 +124,20 @@ def test_snd_filename(self):
fn = support.findfile('pluck-pcm8.wav', subdir='audiodata')
safe_PlaySound(fn, winsound.SND_FILENAME | winsound.SND_NODEFAULT)

def test_snd_filepath(self):
fn = support.findfile('pluck-pcm8.wav', subdir='audiodata')
path = pathlib.Path(fn)
safe_PlaySound(path, winsound.SND_FILENAME | winsound.SND_NODEFAULT)

def test_snd_filepath_as_bytes(self):
fn = support.findfile('pluck-pcm8.wav', subdir='audiodata')
self.assertRaises(
TypeError,
winsound.PlaySound,
BytesPath(fn),
winsound.SND_FILENAME | winsound.SND_NODEFAULT
)

def test_aliases(self):
aliases = [
"SystemAsterisk",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Accept os.PathLike for the argument to winsound.PlaySound
22 changes: 15 additions & 7 deletions PC/winsound.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,25 @@ winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags)
return NULL;
}
wsound = (wchar_t *)view.buf;
} else if (PyBytes_Check(sound)) {
PyErr_Format(PyExc_TypeError,
"'sound' must be str, os.PathLike, or None, not '%s'",
Py_TYPE(sound)->tp_name);
return NULL;
} else {
if (!PyUnicode_Check(sound)) {
PyObject *obj = PyOS_FSPath(sound);
// Either <obj> is unicode/bytes/NULL, or a helpful message
// has been surfaced to the user about how they gave a non-path.
if (obj == NULL) return NULL;
if (PyBytes_Check(obj)) {
PyErr_Format(PyExc_TypeError,
"'sound' must be str or None, not '%s'",
Py_TYPE(sound)->tp_name);
return NULL;
}
wsound = PyUnicode_AsWideCharString(sound, NULL);
if (wsound == NULL) {
"'sound' must resolve to str, not bytes");
Py_DECREF(obj);
return NULL;
}
wsound = PyUnicode_AsWideCharString(obj, NULL);
Py_DECREF(obj);
if (wsound == NULL) return NULL;
}


Expand Down