Skip to content

Fix exception types in arcade.sound #1926

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
26 changes: 11 additions & 15 deletions arcade/sound.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def load_sound(path: Union[str, Path], streaming: bool = False) -> Optional[Soun
except Exception as ex:
raise FileNotFoundError(
f'Unable to load sound file: "{file_name}". Exception: {ex}'
)
) from ex


def play_sound(
Expand All @@ -206,12 +206,13 @@ def play_sound(
if sound is None:
print("Unable to play sound, no data passed in.")
return None
elif isinstance(sound, str):
msg = (
"Error, passed in a string as a sound. "
"Make sure to use load_sound first, and use that result in play_sound."
)
raise Exception(msg)

elif not isinstance(sound, Sound):
raise TypeError(
f"Error, got {sound!r} instead of an arcade.Sound."
if not isinstance(sound, (str, Path, bytes)) else\
" Make sure to use load_sound first, then play the result with play_sound.")

try:
return sound.play(volume, pan, looping, speed)
except Exception as ex:
Expand All @@ -225,16 +226,11 @@ def stop_sound(player: media.Player):

:param player: Player returned from :func:`play_sound`.
"""
if isinstance(player, Sound):
raise ValueError(
"stop_sound takes the media player object returned from the play() command, "
"not the loaded Sound object."
)

if not isinstance(player, media.Player):
raise ValueError(
"stop_sound takes a media player object returned from the play() command."
)
raise TypeError(
"stop_sound takes a media player object returned from the play_sound() command, not a "
"loaded Sound object." if isinstance(player, Sound) else f"{player!r}")

player.pause()
player.delete()
Expand Down
38 changes: 37 additions & 1 deletion tests/unit/test_sound.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from pathlib import Path

import pytest

import arcade

frame_count = 0
player = None


def test_sound(window):
def test_sound_normal_load_and_playback(window):
global frame_count, player

laser_wav = arcade.load_sound(":resources:sounds/laser1.wav")
Expand Down Expand Up @@ -89,3 +93,35 @@ def on_draw():
window.on_draw = on_draw
window.test(140)
player = None


def test_sound_play_sound_type_errors(window):
# Non-pathlike raises and provides full loading guidance.
with pytest.raises(TypeError) as ctx:
arcade.play_sound(object())
assert ctx.value.args[0].endswith("arcade.Sound.")

#Pathlike raises and provides full loading guidance.
with pytest.raises(TypeError) as ctx:
arcade.play_sound("file.wav")
assert ctx.value.args[0].endswidth("play_sound.")

with pytest.raises(TypeError) as ctx:
arcade.play_sound(b"file.wav")
assert ctx.value.args[0].endswidth("play_sound.")

with pytest.raises(TypeError) as ctx:
arcade.play_sound(Path("file.wav"))
assert ctx.value.args[0].endswidth("play_sound.")


def test_sound_stop_sound_type_errors(window):
sound = arcade.load_sound(":resources:sounds/laser1.wav")

# Sound raises specific type error
with pytest.raises(TypeError) as ctx:
arcade.stop_sound(sound)
assert ctx.value.args[0].endswith("not the loaded Sound object.")

with pytest.raises(TypeError) as ctx:
arcade.play_sound("file.wav")