From c7df1f9f3e9c92051ce55d6815901cffe84217d8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 18 Nov 2019 20:58:16 +0100 Subject: [PATCH 1/3] Mark entity abc --- homeassistant/helpers/entity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 0d2182f88e1f0a..1805c6bd74b0d8 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -1,5 +1,5 @@ """An abstract class for entities.""" - +from abc import ABC import asyncio from datetime import datetime, timedelta import logging @@ -85,7 +85,7 @@ def async_generate_entity_id( return ensure_unique_string(entity_id_format.format(slugify(name)), current_ids) -class Entity: +class Entity(ABC): """An abstract class for Home Assistant entities.""" # SAFE TO OVERWRITE From 0944a3bf96b56c67c2fc952cc32e1ffa4a396fd3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 18 Nov 2019 21:02:59 +0100 Subject: [PATCH 2/3] Use abstractmethod in climate --- homeassistant/components/climate/__init__.py | 5 +-- tests/components/climate/test_init.py | 36 +++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 0c8d6103b12383..2b8854e5a99af1 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -1,4 +1,5 @@ """Provides functionality to interact with climate devices.""" +from abc import abstractmethod from datetime import timedelta import functools as ft import logging @@ -270,20 +271,20 @@ def target_humidity(self) -> Optional[int]: return None @property + @abstractmethod def hvac_mode(self) -> str: """Return hvac operation ie. heat, cool mode. Need to be one of HVAC_MODE_*. """ - raise NotImplementedError() @property + @abstractmethod def hvac_modes(self) -> List[str]: """Return the list of available hvac operation modes. Need to be a subset of HVAC_MODES. """ - raise NotImplementedError() @property def hvac_action(self) -> Optional[str]: diff --git a/tests/components/climate/test_init.py b/tests/components/climate/test_init.py index c9d9f1f6425040..b044753c891053 100644 --- a/tests/components/climate/test_init.py +++ b/tests/components/climate/test_init.py @@ -1,10 +1,16 @@ """The tests for the climate component.""" from unittest.mock import MagicMock +from typing import List import pytest import voluptuous as vol -from homeassistant.components.climate import SET_TEMPERATURE_SCHEMA, ClimateDevice +from homeassistant.components.climate import ( + SET_TEMPERATURE_SCHEMA, + ClimateDevice, + HVAC_MODE_HEAT, + HVAC_MODE_OFF, +) from tests.common import async_mock_service @@ -38,9 +44,29 @@ async def test_set_temp_schema(hass, caplog): assert calls[-1].data == data +class MockClimateDevice(ClimateDevice): + """Mock Climate device to use in tests.""" + + @property + def hvac_mode(self) -> str: + """Return hvac operation ie. heat, cool mode. + + Need to be one of HVAC_MODE_*. + """ + return HVAC_MODE_HEAT + + @property + def hvac_modes(self) -> List[str]: + """Return the list of available hvac operation modes. + + Need to be a subset of HVAC_MODES. + """ + return [HVAC_MODE_OFF, HVAC_MODE_HEAT] + + async def test_sync_turn_on(hass): - """Test if adding turn_on work.""" - climate = ClimateDevice() + """Test if async turn_on calls sync turn_on.""" + climate = MockClimateDevice() climate.hass = hass climate.turn_on = MagicMock() @@ -50,8 +76,8 @@ async def test_sync_turn_on(hass): async def test_sync_turn_off(hass): - """Test if adding turn_on work.""" - climate = ClimateDevice() + """Test if async turn_off calls sync turn_off.""" + climate = MockClimateDevice() climate.hass = hass climate.turn_off = MagicMock() From 955ded4b6e75b1da4aa9a9905864ab660a22a98e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 19 Nov 2019 10:58:16 -0800 Subject: [PATCH 3/3] Lint --- homeassistant/components/heatmiser/climate.py | 23 ++++++++++++++++++- pylintrc | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/heatmiser/climate.py b/homeassistant/components/heatmiser/climate.py index c9bed1e9d34fb9..6693e71878a99f 100644 --- a/homeassistant/components/heatmiser/climate.py +++ b/homeassistant/components/heatmiser/climate.py @@ -1,9 +1,14 @@ """Support for the PRT Heatmiser themostats using the V3 protocol.""" import logging +from typing import List import voluptuous as vol -from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA +from homeassistant.components.climate import ( + ClimateDevice, + PLATFORM_SCHEMA, + HVAC_MODE_HEAT, +) from homeassistant.components.climate.const import SUPPORT_TARGET_TEMPERATURE from homeassistant.const import ( TEMP_CELSIUS, @@ -82,6 +87,22 @@ def temperature_unit(self): """Return the unit of measurement which this thermostat uses.""" return TEMP_CELSIUS + @property + def hvac_mode(self) -> str: + """Return hvac operation ie. heat, cool mode. + + Need to be one of HVAC_MODE_*. + """ + return HVAC_MODE_HEAT + + @property + def hvac_modes(self) -> List[str]: + """Return the list of available hvac operation modes. + + Need to be a subset of HVAC_MODES. + """ + return [HVAC_MODE_HEAT] + @property def current_temperature(self): """Return the current temperature.""" diff --git a/pylintrc b/pylintrc index ff47af6087b8c0..2db05f171a3e89 100644 --- a/pylintrc +++ b/pylintrc @@ -23,6 +23,7 @@ good-names=id,i,j,k,ex,Run,_,fp # inconsistent-return-statements - doesn't handle raise # unnecessary-pass - readability for functions which only contain pass # import-outside-toplevel - TODO +# too-many-ancestors - it's too strict. disable= format, abstract-class-little-used, @@ -36,6 +37,7 @@ disable= not-context-manager, redefined-variable-type, too-few-public-methods, + too-many-ancestors, too-many-arguments, too-many-branches, too-many-instance-attributes,