]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91061: also accept pathlib.Path for winsound.PlaySound (#91489)
authorMori Bellamy <mori@invoked.net>
Mon, 23 May 2022 01:54:24 +0000 (18:54 -0700)
committerGitHub <noreply@github.com>
Mon, 23 May 2022 01:54:24 +0000 (18:54 -0700)
Fixes #91061

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Lib/test/test_winsound.py
Misc/NEWS.d/next/Windows/2022-04-12-18-35-20.gh-issue-91061.x40hSK.rst [new file with mode: 0644]
PC/winsound.c

index 3c3359b9004fd2feb102228dfd4904ccd55b5da7..a59d0d24f5db4863cc8f5df195d5c21cf00b76f0 100644 (file)
@@ -1,6 +1,7 @@
 # Ridiculously simple test of the winsound module for Windows.
 
 import functools
+import pathlib
 import time
 import unittest
 
@@ -84,6 +85,13 @@ class MessageBeepTest(unittest.TestCase):
         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):
@@ -116,6 +124,20 @@ class PlaySoundTest(unittest.TestCase):
         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",
diff --git a/Misc/NEWS.d/next/Windows/2022-04-12-18-35-20.gh-issue-91061.x40hSK.rst b/Misc/NEWS.d/next/Windows/2022-04-12-18-35-20.gh-issue-91061.x40hSK.rst
new file mode 100644 (file)
index 0000000..aadc303
--- /dev/null
@@ -0,0 +1 @@
+Accept os.PathLike for the argument to winsound.PlaySound
index fd04e1e55b5fc8343b2ce4cb562010ea19eb8823..65025ddc5e1f518626722a7e4a9eaafbe085d954 100644 (file)
@@ -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;
     }