diff --git a/arcade/sound.py b/arcade/sound.py index c4dc0a38a1..bb52638580 100644 --- a/arcade/sound.py +++ b/arcade/sound.py @@ -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( @@ -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: @@ -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() diff --git a/tests/unit/test_sound.py b/tests/unit/test_sound.py index dd5147e75a..7d4783f2cd 100644 --- a/tests/unit/test_sound.py +++ b/tests/unit/test_sound.py @@ -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") @@ -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")