From 677995a05a604efb44730164e1c1e57d4a7d79c4 Mon Sep 17 00:00:00 2001 From: Andrew Sayre <6730289+andrewsayre@users.noreply.github.com> Date: Sun, 25 Aug 2019 13:57:43 -0500 Subject: [PATCH] Update pyheos to 0.6.0 (#26191) --- homeassistant/components/heos/__init__.py | 26 ++++-------- homeassistant/components/heos/config_flow.py | 6 +-- homeassistant/components/heos/manifest.json | 4 +- homeassistant/components/heos/media_player.py | 10 +---- homeassistant/components/heos/services.py | 9 ++--- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/heos/test_config_flow.py | 23 +++++------ tests/components/heos/test_init.py | 40 +++++++++---------- tests/components/heos/test_media_player.py | 28 ++++++------- tests/components/heos/test_services.py | 8 ++-- 11 files changed, 66 insertions(+), 92 deletions(-) diff --git a/homeassistant/components/heos/__init__.py b/homeassistant/components/heos/__init__.py index a5450253be0..20ed7930a4f 100644 --- a/homeassistant/components/heos/__init__.py +++ b/homeassistant/components/heos/__init__.py @@ -4,7 +4,7 @@ from datetime import timedelta import logging from typing import Dict -from pyheos import CommandError, Heos, const as heos_const +from pyheos import Heos, HeosError, const as heos_const import voluptuous as vol from homeassistant.components.media_player.const import DOMAIN as MEDIA_PLAYER_DOMAIN @@ -68,7 +68,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry): try: await controller.connect(auto_reconnect=True) # Auto reconnect only operates if initial connection was successful. - except (asyncio.TimeoutError, ConnectionError, CommandError) as error: + except HeosError as error: await controller.disconnect() _LOGGER.debug("Unable to connect to controller %s: %s", host, error) raise ConfigEntryNotReady @@ -93,13 +93,9 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry): host, ) inputs = await controller.get_input_sources() - except (asyncio.TimeoutError, ConnectionError, CommandError) as error: + except HeosError as error: await controller.disconnect() - _LOGGER.debug( - "Unable to retrieve players and sources: %s", - error, - exc_info=isinstance(error, CommandError), - ) + _LOGGER.debug("Unable to retrieve players and sources: %s", error) raise ConfigEntryNotReady controller_manager = ControllerManager(hass, controller) @@ -187,7 +183,7 @@ class ControllerManager: # Retrieve latest players and refresh status data = await self.controller.load_players() self.update_ids(data[heos_const.DATA_MAPPED_IDS]) - except (CommandError, asyncio.TimeoutError, ConnectionError) as ex: + except HeosError as ex: _LOGGER.error("Unable to refresh players: %s", ex) # Update players self._hass.helpers.dispatcher.async_dispatcher_send(SIGNAL_HEOS_UPDATED) @@ -312,21 +308,15 @@ class SourceManager: favorites = await controller.get_favorites() inputs = await controller.get_input_sources() return favorites, inputs - except (asyncio.TimeoutError, ConnectionError, CommandError) as error: + except HeosError as error: if retry_attempts < self.max_retry_attempts: retry_attempts += 1 _LOGGER.debug( - "Error retrieving sources and will " "retry: %s", - error, - exc_info=isinstance(error, CommandError), + "Error retrieving sources and will " "retry: %s", error ) await asyncio.sleep(self.retry_delay) else: - _LOGGER.error( - "Unable to update sources: %s", - error, - exc_info=isinstance(error, CommandError), - ) + _LOGGER.error("Unable to update sources: %s", error) return async def update_sources(event, data=None): diff --git a/homeassistant/components/heos/config_flow.py b/homeassistant/components/heos/config_flow.py index 7c7f57a91d7..1d56478ba3a 100644 --- a/homeassistant/components/heos/config_flow.py +++ b/homeassistant/components/heos/config_flow.py @@ -1,7 +1,5 @@ """Config flow to configure Heos.""" -import asyncio - -from pyheos import Heos +from pyheos import Heos, HeosError import voluptuous as vol from homeassistant import config_entries @@ -59,7 +57,7 @@ class HeosFlowHandler(config_entries.ConfigFlow): await heos.connect() self.hass.data.pop(DATA_DISCOVERED_HOSTS) return await self.async_step_import({CONF_HOST: host}) - except (asyncio.TimeoutError, ConnectionError): + except HeosError: errors[CONF_HOST] = "connection_failure" finally: await heos.disconnect() diff --git a/homeassistant/components/heos/manifest.json b/homeassistant/components/heos/manifest.json index 09833bb729b..eb9ef258a3c 100644 --- a/homeassistant/components/heos/manifest.json +++ b/homeassistant/components/heos/manifest.json @@ -4,7 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/components/heos", "requirements": [ - "pyheos==0.5.2" + "pyheos==0.6.0" ], "ssdp": { "st": [ @@ -15,4 +15,4 @@ "codeowners": [ "@andrewsayre" ] -} +} \ No newline at end of file diff --git a/homeassistant/components/heos/media_player.py b/homeassistant/components/heos/media_player.py index a4094a0c216..40f6113a80d 100644 --- a/homeassistant/components/heos/media_player.py +++ b/homeassistant/components/heos/media_player.py @@ -1,11 +1,10 @@ """Denon HEOS Media Player.""" -import asyncio from functools import reduce, wraps import logging from operator import ior from typing import Sequence -from pyheos import CommandError, const as heos_const +from pyheos import HeosError, const as heos_const from homeassistant.components.media_player import MediaPlayerDevice from homeassistant.components.media_player.const import ( @@ -83,12 +82,7 @@ def log_command_error(command: str): async def wrapper(*args, **kwargs): try: await func(*args, **kwargs) - except ( - CommandError, - asyncio.TimeoutError, - ConnectionError, - ValueError, - ) as ex: + except (HeosError, ValueError) as ex: _LOGGER.error("Unable to %s: %s", command, ex) return wrapper diff --git a/homeassistant/components/heos/services.py b/homeassistant/components/heos/services.py index 8f3521399e2..ee5df1b483b 100644 --- a/homeassistant/components/heos/services.py +++ b/homeassistant/components/heos/services.py @@ -1,9 +1,8 @@ """Services for the HEOS integration.""" -import asyncio import functools import logging -from pyheos import CommandError, Heos, const +from pyheos import CommandFailedError, Heos, HeosError, const import voluptuous as vol from homeassistant.helpers import config_validation as cv @@ -57,9 +56,9 @@ async def _sign_in_handler(controller, service): password = service.data[ATTR_PASSWORD] try: await controller.sign_in(username, password) - except CommandError as err: + except CommandFailedError as err: _LOGGER.error("Sign in failed: %s", err) - except (asyncio.TimeoutError, ConnectionError) as err: + except HeosError as err: _LOGGER.error("Unable to sign in: %s", err) @@ -70,5 +69,5 @@ async def _sign_out_handler(controller, service): return try: await controller.sign_out() - except (asyncio.TimeoutError, ConnectionError, CommandError) as err: + except HeosError as err: _LOGGER.error("Unable to sign out: %s", err) diff --git a/requirements_all.txt b/requirements_all.txt index 70483d1f2e2..b467859343f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1186,7 +1186,7 @@ pygtt==1.1.2 pyhaversion==3.0.2 # homeassistant.components.heos -pyheos==0.5.2 +pyheos==0.6.0 # homeassistant.components.hikvision pyhik==0.2.3 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 50f49296247..96b82caf968 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -277,7 +277,7 @@ pydeconz==62 pydispatcher==2.0.5 # homeassistant.components.heos -pyheos==0.5.2 +pyheos==0.6.0 # homeassistant.components.homematic pyhomematic==0.1.60 diff --git a/tests/components/heos/test_config_flow.py b/tests/components/heos/test_config_flow.py index 0d834ccc770..df021fea55d 100644 --- a/tests/components/heos/test_config_flow.py +++ b/tests/components/heos/test_config_flow.py @@ -1,5 +1,5 @@ """Tests for the Heos config flow module.""" -import asyncio +from pyheos import HeosError from homeassistant import data_entry_flow from homeassistant.components.heos.config_flow import HeosFlowHandler @@ -31,18 +31,15 @@ async def test_cannot_connect_shows_error_form(hass, controller): """Test form is shown with error when cannot connect.""" flow = HeosFlowHandler() flow.hass = hass - - errors = [ConnectionError, asyncio.TimeoutError] - for error in errors: - controller.connect.side_effect = error - result = await flow.async_step_user({CONF_HOST: "127.0.0.1"}) - assert result["type"] == data_entry_flow.RESULT_TYPE_FORM - assert result["step_id"] == "user" - assert result["errors"][CONF_HOST] == "connection_failure" - assert controller.connect.call_count == 1 - assert controller.disconnect.call_count == 1 - controller.connect.reset_mock() - controller.disconnect.reset_mock() + controller.connect.side_effect = HeosError() + result = await flow.async_step_user({CONF_HOST: "127.0.0.1"}) + assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result["step_id"] == "user" + assert result["errors"][CONF_HOST] == "connection_failure" + assert controller.connect.call_count == 1 + assert controller.disconnect.call_count == 1 + controller.connect.reset_mock() + controller.disconnect.reset_mock() async def test_create_entry_when_host_valid(hass, controller): diff --git a/tests/components/heos/test_init.py b/tests/components/heos/test_init.py index 728e65b81f5..7b2645cb8ec 100644 --- a/tests/components/heos/test_init.py +++ b/tests/components/heos/test_init.py @@ -2,7 +2,7 @@ import asyncio from asynctest import Mock, patch -from pyheos import CommandError, const +from pyheos import CommandFailedError, HeosError, const import pytest from homeassistant.components.heos import ( @@ -117,31 +117,27 @@ async def test_async_setup_entry_not_signed_in_loads_platforms( async def test_async_setup_entry_connect_failure(hass, config_entry, controller): """Connection failure raises ConfigEntryNotReady.""" config_entry.add_to_hass(hass) - errors = [ConnectionError, asyncio.TimeoutError] - for error in errors: - controller.connect.side_effect = error - with pytest.raises(ConfigEntryNotReady): - await async_setup_entry(hass, config_entry) - await hass.async_block_till_done() - assert controller.connect.call_count == 1 - assert controller.disconnect.call_count == 1 - controller.connect.reset_mock() - controller.disconnect.reset_mock() + controller.connect.side_effect = HeosError() + with pytest.raises(ConfigEntryNotReady): + await async_setup_entry(hass, config_entry) + await hass.async_block_till_done() + assert controller.connect.call_count == 1 + assert controller.disconnect.call_count == 1 + controller.connect.reset_mock() + controller.disconnect.reset_mock() async def test_async_setup_entry_player_failure(hass, config_entry, controller): """Failure to retrieve players/sources raises ConfigEntryNotReady.""" config_entry.add_to_hass(hass) - errors = [ConnectionError, asyncio.TimeoutError] - for error in errors: - controller.get_players.side_effect = error - with pytest.raises(ConfigEntryNotReady): - await async_setup_entry(hass, config_entry) - await hass.async_block_till_done() - assert controller.connect.call_count == 1 - assert controller.disconnect.call_count == 1 - controller.connect.reset_mock() - controller.disconnect.reset_mock() + controller.get_players.side_effect = HeosError() + with pytest.raises(ConfigEntryNotReady): + await async_setup_entry(hass, config_entry) + await hass.async_block_till_done() + assert controller.connect.call_count == 1 + assert controller.disconnect.call_count == 1 + controller.connect.reset_mock() + controller.disconnect.reset_mock() async def test_unload_entry(hass, config_entry, controller): @@ -167,7 +163,7 @@ async def test_update_sources_retry(hass, config_entry, config, controller, capl source_manager = hass.data[DOMAIN][DATA_SOURCE_MANAGER] source_manager.retry_delay = 0 source_manager.max_retry_attempts = 1 - controller.get_favorites.side_effect = CommandError("Test", "test", 0) + controller.get_favorites.side_effect = CommandFailedError("Test", "test", 0) controller.dispatcher.send( const.SIGNAL_CONTROLLER_EVENT, const.EVENT_SOURCES_CHANGED, {} ) diff --git a/tests/components/heos/test_media_player.py b/tests/components/heos/test_media_player.py index de062757803..0f9bf2d8b3e 100644 --- a/tests/components/heos/test_media_player.py +++ b/tests/components/heos/test_media_player.py @@ -1,7 +1,7 @@ """Tests for the Heos Media Player platform.""" import asyncio -from pyheos import CommandError, const +from pyheos import CommandFailedError, const from homeassistant.components.heos import media_player from homeassistant.components.heos.const import ( @@ -179,7 +179,7 @@ async def test_updates_from_connection_event( event.clear() player.reset_mock() controller.load_players.reset_mock() - controller.load_players.side_effect = CommandError(None, "Failure", 1) + controller.load_players.side_effect = CommandFailedError(None, "Failure", 1) player.available = True player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED) await event.wait() @@ -313,7 +313,7 @@ async def test_clear_playlist(hass, config_entry, config, controller, caplog): ) assert player.clear_queue.call_count == 1 player.clear_queue.reset_mock() - player.clear_queue.side_effect = CommandError(None, "Failure", 1) + player.clear_queue.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to clear playlist: Failure (1)" in caplog.text @@ -331,7 +331,7 @@ async def test_pause(hass, config_entry, config, controller, caplog): ) assert player.pause.call_count == 1 player.pause.reset_mock() - player.pause.side_effect = CommandError(None, "Failure", 1) + player.pause.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to pause: Failure (1)" in caplog.text @@ -349,7 +349,7 @@ async def test_play(hass, config_entry, config, controller, caplog): ) assert player.play.call_count == 1 player.play.reset_mock() - player.play.side_effect = CommandError(None, "Failure", 1) + player.play.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to play: Failure (1)" in caplog.text @@ -367,7 +367,7 @@ async def test_previous_track(hass, config_entry, config, controller, caplog): ) assert player.play_previous.call_count == 1 player.play_previous.reset_mock() - player.play_previous.side_effect = CommandError(None, "Failure", 1) + player.play_previous.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to move to previous track: Failure (1)" in caplog.text @@ -385,7 +385,7 @@ async def test_next_track(hass, config_entry, config, controller, caplog): ) assert player.play_next.call_count == 1 player.play_next.reset_mock() - player.play_next.side_effect = CommandError(None, "Failure", 1) + player.play_next.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to move to next track: Failure (1)" in caplog.text @@ -403,7 +403,7 @@ async def test_stop(hass, config_entry, config, controller, caplog): ) assert player.stop.call_count == 1 player.stop.reset_mock() - player.stop.side_effect = CommandError(None, "Failure", 1) + player.stop.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to stop: Failure (1)" in caplog.text @@ -421,7 +421,7 @@ async def test_volume_mute(hass, config_entry, config, controller, caplog): ) assert player.set_mute.call_count == 1 player.set_mute.reset_mock() - player.set_mute.side_effect = CommandError(None, "Failure", 1) + player.set_mute.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to set mute: Failure (1)" in caplog.text @@ -439,7 +439,7 @@ async def test_shuffle_set(hass, config_entry, config, controller, caplog): ) player.set_play_mode.assert_called_once_with(player.repeat, True) player.set_play_mode.reset_mock() - player.set_play_mode.side_effect = CommandError(None, "Failure", 1) + player.set_play_mode.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to set shuffle: Failure (1)" in caplog.text @@ -457,7 +457,7 @@ async def test_volume_set(hass, config_entry, config, controller, caplog): ) player.set_volume.assert_called_once_with(100) player.set_volume.reset_mock() - player.set_volume.side_effect = CommandError(None, "Failure", 1) + player.set_volume.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to set volume level: Failure (1)" in caplog.text @@ -516,7 +516,7 @@ async def test_select_radio_favorite_command_error( player = controller.players[1] # Test set radio preset favorite = favorites[2] - player.play_favorite.side_effect = CommandError(None, "Failure", 1) + player.play_favorite.side_effect = CommandFailedError(None, "Failure", 1) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_SELECT_SOURCE, @@ -575,7 +575,7 @@ async def test_select_input_command_error( await setup_platform(hass, config_entry, config) player = controller.players[1] input_source = input_sources[0] - player.play_input_source.side_effect = CommandError(None, "Failure", 1) + player.play_input_source.side_effect = CommandFailedError(None, "Failure", 1) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_SELECT_SOURCE, @@ -615,7 +615,7 @@ async def test_play_media_url(hass, config_entry, config, controller, caplog): ) player.play_url.assert_called_once_with(url) player.play_url.reset_mock() - player.play_url.side_effect = CommandError(None, "Failure", 1) + player.play_url.side_effect = CommandFailedError(None, "Failure", 1) assert "Unable to play media: Failure (1)" in caplog.text diff --git a/tests/components/heos/test_services.py b/tests/components/heos/test_services.py index 0e1cbc8ea2e..5a835cf7303 100644 --- a/tests/components/heos/test_services.py +++ b/tests/components/heos/test_services.py @@ -1,5 +1,5 @@ """Tests for the services module.""" -from pyheos import CommandError, const +from pyheos import CommandFailedError, HeosError, const from homeassistant.components.heos.const import ( ATTR_PASSWORD, @@ -51,7 +51,7 @@ async def test_sign_in_not_connected(hass, config_entry, controller, caplog): async def test_sign_in_failed(hass, config_entry, controller, caplog): """Test sign-in service logs error when not connected.""" await setup_component(hass, config_entry) - controller.sign_in.side_effect = CommandError("", "Invalid credentials", 6) + controller.sign_in.side_effect = CommandFailedError("", "Invalid credentials", 6) await hass.services.async_call( DOMAIN, @@ -67,7 +67,7 @@ async def test_sign_in_failed(hass, config_entry, controller, caplog): async def test_sign_in_unknown_error(hass, config_entry, controller, caplog): """Test sign-in service logs error for failure.""" await setup_component(hass, config_entry) - controller.sign_in.side_effect = ConnectionError + controller.sign_in.side_effect = HeosError() await hass.services.async_call( DOMAIN, @@ -103,7 +103,7 @@ async def test_sign_out_not_connected(hass, config_entry, controller, caplog): async def test_sign_out_unknown_error(hass, config_entry, controller, caplog): """Test the sign-out service.""" await setup_component(hass, config_entry) - controller.sign_out.side_effect = ConnectionError + controller.sign_out.side_effect = HeosError() await hass.services.async_call(DOMAIN, SERVICE_SIGN_OUT, {}, blocking=True)