From 3929273b416c45f5bf21f6e58ac7865bae3d173b Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:51:27 +0100 Subject: [PATCH] Allow float for int argument type [pylint plugin] (#114105) --- .../components/xiaomi_miio/humidifier.py | 8 ++--- homeassistant/util/percentage.py | 2 +- pylint/plugins/hass_enforce_type_hints.py | 9 +++++ tests/pylint/test_enforce_type_hints.py | 33 +++++++++++++++++++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/xiaomi_miio/humidifier.py b/homeassistant/components/xiaomi_miio/humidifier.py index 83eb84f62ce..8367b063102 100644 --- a/homeassistant/components/xiaomi_miio/humidifier.py +++ b/homeassistant/components/xiaomi_miio/humidifier.py @@ -159,7 +159,7 @@ class XiaomiGenericHumidifier(XiaomiCoordinatedMiioEntity, HumidifierEntity): self._state = False self.async_write_ha_state() - def translate_humidity(self, humidity): + def translate_humidity(self, humidity: float) -> float | None: """Translate the target humidity to the first valid step.""" return ( math.ceil(percentage_to_ranged_value((1, self._humidity_steps), humidity)) @@ -240,7 +240,7 @@ class XiaomiAirHumidifier(XiaomiGenericHumidifier, HumidifierEntity): else None ) - async def async_set_humidity(self, humidity: int) -> None: + async def async_set_humidity(self, humidity: float) -> None: """Set the target humidity of the humidifier and set the mode to auto.""" target_humidity = self.translate_humidity(humidity) if not target_humidity: @@ -318,7 +318,7 @@ class XiaomiAirHumidifierMiot(XiaomiAirHumidifier): ) return None - async def async_set_humidity(self, humidity: int) -> None: + async def async_set_humidity(self, humidity: float) -> None: """Set the target humidity of the humidifier and set the mode to auto.""" target_humidity = self.translate_humidity(humidity) if not target_humidity: @@ -393,7 +393,7 @@ class XiaomiAirHumidifierMjjsq(XiaomiAirHumidifier): return self._target_humidity return None - async def async_set_humidity(self, humidity: int) -> None: + async def async_set_humidity(self, humidity: float) -> None: """Set the target humidity of the humidifier and set the mode to Humidity.""" target_humidity = self.translate_humidity(humidity) if not target_humidity: diff --git a/homeassistant/util/percentage.py b/homeassistant/util/percentage.py index 5f2a1193d96..e01af5400f4 100644 --- a/homeassistant/util/percentage.py +++ b/homeassistant/util/percentage.py @@ -81,7 +81,7 @@ def ranged_value_to_percentage( def percentage_to_ranged_value( - low_high_range: tuple[float, float], percentage: int + low_high_range: tuple[float, float], percentage: float ) -> float: """Given a range of low and high values convert a percentage to a single value. diff --git a/pylint/plugins/hass_enforce_type_hints.py b/pylint/plugins/hass_enforce_type_hints.py index 4799a3a56fa..7d48fa4b2e3 100644 --- a/pylint/plugins/hass_enforce_type_hints.py +++ b/pylint/plugins/hass_enforce_type_hints.py @@ -2968,6 +2968,15 @@ def _is_valid_type( ): return True + # Special case for int in argument type + if ( + expected_type == "int" + and not in_return + and isinstance(node, nodes.Name) + and node.name in ("float", "int") + ): + return True + # Name occurs when a namespace is not used, eg. "HomeAssistant" if isinstance(node, nodes.Name) and node.name == expected_type: return True diff --git a/tests/pylint/test_enforce_type_hints.py b/tests/pylint/test_enforce_type_hints.py index d3b7efae19b..78eb682200a 100644 --- a/tests/pylint/test_enforce_type_hints.py +++ b/tests/pylint/test_enforce_type_hints.py @@ -989,6 +989,39 @@ def test_media_player_entity( type_hint_checker.visit_classdef(class_node) +def test_humidifier_entity( + linter: UnittestLinter, type_hint_checker: BaseChecker +) -> None: + """Ensure valid hints are accepted for humidifier entity.""" + # Set bypass option + type_hint_checker.linter.config.ignore_missing_annotations = False + + # Ensure that `float` and `int` are valid for `int` argument type + class_node = astroid.extract_node( + """ + class Entity(): + pass + + class HumidifierEntity(Entity): + pass + + class MyHumidifier( #@ + HumidifierEntity + ): + def set_humidity(self, humidity: int) -> None: + pass + + def async_set_humidity(self, humidity: float) -> None: + pass + """, + "homeassistant.components.pylint_test.humidifier", + ) + type_hint_checker.visit_module(class_node.parent) + + with assert_no_messages(linter): + type_hint_checker.visit_classdef(class_node) + + def test_number_entity(linter: UnittestLinter, type_hint_checker: BaseChecker) -> None: """Ensure valid hints are accepted for number entity.""" # Set bypass option