diff --git a/homeassistant/components/androidtv/media_player.py b/homeassistant/components/androidtv/media_player.py index 563b8f07b2a..f4fbe4a498f 100644 --- a/homeassistant/components/androidtv/media_player.py +++ b/homeassistant/components/androidtv/media_player.py @@ -296,7 +296,6 @@ class ADBDevice(MediaPlayerEntity): self._process_config, ) ) - return @property def media_image_hash(self) -> str | None: diff --git a/homeassistant/components/assist_pipeline/vad.py b/homeassistant/components/assist_pipeline/vad.py index f76de39ccce..a737490f22f 100644 --- a/homeassistant/components/assist_pipeline/vad.py +++ b/homeassistant/components/assist_pipeline/vad.py @@ -137,16 +137,15 @@ class VoiceCommandSegmenter: self._reset_seconds_left -= self._seconds_per_chunk if self._reset_seconds_left <= 0: self._speech_seconds_left = self.speech_seconds + elif not is_speech: + self._reset_seconds_left = self.reset_seconds + self._silence_seconds_left -= self._seconds_per_chunk + if self._silence_seconds_left <= 0: + return False else: - if not is_speech: - self._reset_seconds_left = self.reset_seconds - self._silence_seconds_left -= self._seconds_per_chunk - if self._silence_seconds_left <= 0: - return False - else: - # Reset if enough speech - self._reset_seconds_left -= self._seconds_per_chunk - if self._reset_seconds_left <= 0: - self._silence_seconds_left = self.silence_seconds + # Reset if enough speech + self._reset_seconds_left -= self._seconds_per_chunk + if self._reset_seconds_left <= 0: + self._silence_seconds_left = self.silence_seconds return True diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 7220842db91..e356f641395 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -865,8 +865,6 @@ async def _async_process_config( entities = await _create_automation_entities(hass, updated_automation_configs) await component.async_add_entities(entities) - return - async def _async_process_if( hass: HomeAssistant, name: str, config: dict[str, Any] diff --git a/homeassistant/components/daikin/climate.py b/homeassistant/components/daikin/climate.py index bd0e846ea4d..5ede11c60b6 100644 --- a/homeassistant/components/daikin/climate.py +++ b/homeassistant/components/daikin/climate.py @@ -276,17 +276,16 @@ class DaikinClimate(ClimateEntity): await self._api.device.set_advanced_mode( HA_PRESET_TO_DAIKIN[PRESET_ECO], ATTR_STATE_ON ) - else: - if self.preset_mode == PRESET_AWAY: - await self._api.device.set_holiday(ATTR_STATE_OFF) - elif self.preset_mode == PRESET_BOOST: - await self._api.device.set_advanced_mode( - HA_PRESET_TO_DAIKIN[PRESET_BOOST], ATTR_STATE_OFF - ) - elif self.preset_mode == PRESET_ECO: - await self._api.device.set_advanced_mode( - HA_PRESET_TO_DAIKIN[PRESET_ECO], ATTR_STATE_OFF - ) + elif self.preset_mode == PRESET_AWAY: + await self._api.device.set_holiday(ATTR_STATE_OFF) + elif self.preset_mode == PRESET_BOOST: + await self._api.device.set_advanced_mode( + HA_PRESET_TO_DAIKIN[PRESET_BOOST], ATTR_STATE_OFF + ) + elif self.preset_mode == PRESET_ECO: + await self._api.device.set_advanced_mode( + HA_PRESET_TO_DAIKIN[PRESET_ECO], ATTR_STATE_OFF + ) @property def preset_modes(self): diff --git a/homeassistant/components/devolo_home_control/light.py b/homeassistant/components/devolo_home_control/light.py index 4ccd5a00ab2..93a66e345ec 100644 --- a/homeassistant/components/devolo_home_control/light.py +++ b/homeassistant/components/devolo_home_control/light.py @@ -71,13 +71,12 @@ class DevoloLightDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, LightEntity): self._multi_level_switch_property.set( round(kwargs[ATTR_BRIGHTNESS] / 255 * 100) ) + elif self._binary_switch_property is not None: + # Turn on the light device to the latest known value. The value is known by the device itself. + self._binary_switch_property.set(True) else: - if self._binary_switch_property is not None: - # Turn on the light device to the latest known value. The value is known by the device itself. - self._binary_switch_property.set(True) - else: - # If there is no binary switch attached to the device, turn it on to 100 %. - self._multi_level_switch_property.set(100) + # If there is no binary switch attached to the device, turn it on to 100 %. + self._multi_level_switch_property.set(100) def turn_off(self, **kwargs: Any) -> None: """Turn device off.""" diff --git a/homeassistant/components/doods/image_processing.py b/homeassistant/components/doods/image_processing.py index 8240bb117ea..c94fff1124e 100644 --- a/homeassistant/components/doods/image_processing.py +++ b/homeassistant/components/doods/image_processing.py @@ -350,14 +350,13 @@ class Doods(ImageProcessingEntity): or boxes[3] > self._area[3] ): continue - else: - if ( - boxes[0] > self._area[2] - or boxes[1] > self._area[3] - or boxes[2] < self._area[0] - or boxes[3] < self._area[1] - ): - continue + elif ( + boxes[0] > self._area[2] + or boxes[1] > self._area[3] + or boxes[2] < self._area[0] + or boxes[3] < self._area[1] + ): + continue # Exclude matches outside label specific area definition if self._label_areas.get(label): @@ -369,14 +368,13 @@ class Doods(ImageProcessingEntity): or boxes[3] > self._label_areas[label][3] ): continue - else: - if ( - boxes[0] > self._label_areas[label][2] - or boxes[1] > self._label_areas[label][3] - or boxes[2] < self._label_areas[label][0] - or boxes[3] < self._label_areas[label][1] - ): - continue + elif ( + boxes[0] > self._label_areas[label][2] + or boxes[1] > self._label_areas[label][3] + or boxes[2] < self._label_areas[label][0] + or boxes[3] < self._label_areas[label][1] + ): + continue if label not in matches: matches[label] = [] diff --git a/homeassistant/components/dsmr/sensor.py b/homeassistant/components/dsmr/sensor.py index 524f5c4ffc2..e6d1d035e3b 100644 --- a/homeassistant/components/dsmr/sensor.py +++ b/homeassistant/components/dsmr/sensor.py @@ -459,9 +459,9 @@ async def async_setup_entry( @callback def close_transport(_event: EventType) -> None: """Close the transport on HA shutdown.""" - if not transport: + if not transport: # noqa: B023 return - transport.close() + transport.close() # noqa: B023 stop_listener = hass.bus.async_listen_once( EVENT_HOMEASSISTANT_STOP, close_transport diff --git a/homeassistant/components/fido/sensor.py b/homeassistant/components/fido/sensor.py index 9112351ce06..b7942056a2c 100644 --- a/homeassistant/components/fido/sensor.py +++ b/homeassistant/components/fido/sensor.py @@ -235,11 +235,10 @@ class FidoSensor(SensorEntity): if (sensor_type := self.entity_description.key) == "balance": if self.fido_data.data.get(sensor_type) is not None: self._attr_native_value = round(self.fido_data.data[sensor_type], 2) - else: - if self.fido_data.data.get(self._number, {}).get(sensor_type) is not None: - self._attr_native_value = round( - self.fido_data.data[self._number][sensor_type], 2 - ) + elif self.fido_data.data.get(self._number, {}).get(sensor_type) is not None: + self._attr_native_value = round( + self.fido_data.data[self._number][sensor_type], 2 + ) class FidoData: diff --git a/homeassistant/components/fitbit/sensor.py b/homeassistant/components/fitbit/sensor.py index c53c01c84a7..11946c42173 100644 --- a/homeassistant/components/fitbit/sensor.py +++ b/homeassistant/components/fitbit/sensor.py @@ -442,14 +442,13 @@ class FitbitSensor(SensorEntity): self._attr_native_value = f"{hours}:{minutes:02d} {setting}" else: self._attr_native_value = raw_state + elif self.is_metric: + self._attr_native_value = raw_state else: - if self.is_metric: + try: + self._attr_native_value = int(raw_state) + except TypeError: self._attr_native_value = raw_state - else: - try: - self._attr_native_value = int(raw_state) - except TypeError: - self._attr_native_value = raw_state if resource_type == "activities/heart": self._attr_native_value = ( diff --git a/homeassistant/components/fjaraskupan/light.py b/homeassistant/components/fjaraskupan/light.py index 48d8936b49b..59f69759291 100644 --- a/homeassistant/components/fjaraskupan/light.py +++ b/homeassistant/components/fjaraskupan/light.py @@ -51,9 +51,8 @@ class Light(CoordinatorEntity[Coordinator], LightEntity): async with self.coordinator.async_connect_and_update() as device: if ATTR_BRIGHTNESS in kwargs: await device.send_dim(int(kwargs[ATTR_BRIGHTNESS] * (100.0 / 255.0))) - else: - if not self.is_on: - await device.send_command(COMMAND_LIGHT_ON_OFF) + elif not self.is_on: + await device.send_command(COMMAND_LIGHT_ON_OFF) async def async_turn_off(self, **kwargs: Any) -> None: """Turn the entity off.""" diff --git a/homeassistant/components/generic_hygrostat/humidifier.py b/homeassistant/components/generic_hygrostat/humidifier.py index be36da643e9..01945f9e242 100644 --- a/homeassistant/components/generic_hygrostat/humidifier.py +++ b/homeassistant/components/generic_hygrostat/humidifier.py @@ -435,17 +435,14 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity): elif time is not None: # The time argument is passed only in keep-alive case await self._async_device_turn_on() - else: - if ( - self._device_class == HumidifierDeviceClass.HUMIDIFIER and too_dry - ) or ( - self._device_class == HumidifierDeviceClass.DEHUMIDIFIER and too_wet - ): - _LOGGER.info("Turning on humidifier %s", self._switch_entity_id) - await self._async_device_turn_on() - elif time is not None: - # The time argument is passed only in keep-alive case - await self._async_device_turn_off() + elif ( + self._device_class == HumidifierDeviceClass.HUMIDIFIER and too_dry + ) or (self._device_class == HumidifierDeviceClass.DEHUMIDIFIER and too_wet): + _LOGGER.info("Turning on humidifier %s", self._switch_entity_id) + await self._async_device_turn_on() + elif time is not None: + # The time argument is passed only in keep-alive case + await self._async_device_turn_off() @property def _is_device_active(self): diff --git a/homeassistant/components/generic_thermostat/climate.py b/homeassistant/components/generic_thermostat/climate.py index 22a3f98a9f0..e3eed8866c8 100644 --- a/homeassistant/components/generic_thermostat/climate.py +++ b/homeassistant/components/generic_thermostat/climate.py @@ -494,16 +494,15 @@ class GenericThermostat(ClimateEntity, RestoreEntity): self.heater_entity_id, ) await self._async_heater_turn_on() - else: - if (self.ac_mode and too_hot) or (not self.ac_mode and too_cold): - _LOGGER.info("Turning on heater %s", self.heater_entity_id) - await self._async_heater_turn_on() - elif time is not None: - # The time argument is passed only in keep-alive case - _LOGGER.info( - "Keep-alive - Turning off heater %s", self.heater_entity_id - ) - await self._async_heater_turn_off() + elif (self.ac_mode and too_hot) or (not self.ac_mode and too_cold): + _LOGGER.info("Turning on heater %s", self.heater_entity_id) + await self._async_heater_turn_on() + elif time is not None: + # The time argument is passed only in keep-alive case + _LOGGER.info( + "Keep-alive - Turning off heater %s", self.heater_entity_id + ) + await self._async_heater_turn_off() @property def _is_device_active(self): diff --git a/homeassistant/components/google_assistant/smart_home.py b/homeassistant/components/google_assistant/smart_home.py index 1b1b443baac..b8c57812540 100644 --- a/homeassistant/components/google_assistant/smart_home.py +++ b/homeassistant/components/google_assistant/smart_home.py @@ -278,7 +278,6 @@ async def async_devices_disconnect( """ assert data.context.user_id is not None await data.config.async_disconnect_agent_user(data.context.user_id) - return None @HANDLERS.register("action.devices.IDENTIFY") diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index 02e9518ca5e..6227fc4398a 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -1008,24 +1008,22 @@ class TemperatureSettingTrait(_Trait): ), 1, ) - else: - if (target_temp := attrs.get(ATTR_TEMPERATURE)) is not None: - target_temp = round( - TemperatureConverter.convert( - target_temp, unit, UnitOfTemperature.CELSIUS - ), - 1, - ) - response["thermostatTemperatureSetpointHigh"] = target_temp - response["thermostatTemperatureSetpointLow"] = target_temp - else: - if (target_temp := attrs.get(ATTR_TEMPERATURE)) is not None: - response["thermostatTemperatureSetpoint"] = round( + elif (target_temp := attrs.get(ATTR_TEMPERATURE)) is not None: + target_temp = round( TemperatureConverter.convert( target_temp, unit, UnitOfTemperature.CELSIUS ), 1, ) + response["thermostatTemperatureSetpointHigh"] = target_temp + response["thermostatTemperatureSetpointLow"] = target_temp + elif (target_temp := attrs.get(ATTR_TEMPERATURE)) is not None: + response["thermostatTemperatureSetpoint"] = round( + TemperatureConverter.convert( + target_temp, unit, UnitOfTemperature.CELSIUS + ), + 1, + ) return response diff --git a/homeassistant/components/group/__init__.py b/homeassistant/components/group/__init__.py index 4543bf79d52..9480fa3ce17 100644 --- a/homeassistant/components/group/__init__.py +++ b/homeassistant/components/group/__init__.py @@ -196,9 +196,8 @@ def expand_entity_ids(hass: HomeAssistant, entity_ids: Iterable[Any]) -> list[st if ent_id not in found_ids ) - else: - if entity_id not in found_ids: - found_ids.append(entity_id) + elif entity_id not in found_ids: + found_ids.append(entity_id) except AttributeError: # Raised by split_entity_id if entity_id is not a string diff --git a/homeassistant/components/gtfs/sensor.py b/homeassistant/components/gtfs/sensor.py index b395c73ab3e..6f8daf2918d 100644 --- a/homeassistant/components/gtfs/sensor.py +++ b/homeassistant/components/gtfs/sensor.py @@ -643,15 +643,14 @@ class GTFSDepartureSensor(SensorEntity): # Define the state as a UTC timestamp with ISO 8601 format if not self._departure: self._state = None + elif self._agency: + self._state = self._departure["departure_time"].replace( + tzinfo=dt_util.get_time_zone(self._agency.agency_timezone) + ) else: - if self._agency: - self._state = self._departure["departure_time"].replace( - tzinfo=dt_util.get_time_zone(self._agency.agency_timezone) - ) - else: - self._state = self._departure["departure_time"].replace( - tzinfo=dt_util.UTC - ) + self._state = self._departure["departure_time"].replace( + tzinfo=dt_util.UTC + ) # Assign attributes, icon and name self.update_attributes() diff --git a/homeassistant/components/harmony/remote.py b/homeassistant/components/harmony/remote.py index 1482c8aaa4d..c1e85c86787 100644 --- a/homeassistant/components/harmony/remote.py +++ b/homeassistant/components/harmony/remote.py @@ -216,9 +216,8 @@ class HarmonyRemote(HarmonyEntity, RemoteEntity, RestoreEntity): if not activity or activity == PREVIOUS_ACTIVE_ACTIVITY: if self._last_activity: activity = self._last_activity - else: - if all_activities := self._data.activity_names: - activity = all_activities[0] + elif all_activities := self._data.activity_names: + activity = all_activities[0] if activity: await self._data.async_start_activity(activity) diff --git a/homeassistant/components/hassio/websocket_api.py b/homeassistant/components/hassio/websocket_api.py index 8a9a145f2d6..c8fefe65e1f 100644 --- a/homeassistant/components/hassio/websocket_api.py +++ b/homeassistant/components/hassio/websocket_api.py @@ -41,9 +41,14 @@ SCHEMA_WEBSOCKET_EVENT = vol.Schema( # Endpoints needed for ingress can't require admin because addons can set `panel_admin: false` # pylint: disable=implicit-str-concat +# fmt: off WS_NO_ADMIN_ENDPOINTS = re.compile( - r"^(?:" r"|/ingress/(session|validate_session)" r"|/addons/[^/]+/info" r")$" + r"^(?:" + r"|/ingress/(session|validate_session)" + r"|/addons/[^/]+/info" + r")$" # noqa: ISC001 ) +# fmt: on # pylint: enable=implicit-str-concat _LOGGER: logging.Logger = logging.getLogger(__package__) diff --git a/homeassistant/components/home_connect/sensor.py b/homeassistant/components/home_connect/sensor.py index 38a45ccf709..efd2a9b34dd 100644 --- a/homeassistant/components/home_connect/sensor.py +++ b/homeassistant/components/home_connect/sensor.py @@ -62,28 +62,27 @@ class HomeConnectSensor(HomeConnectEntity, SensorEntity): status = self.device.appliance.status if self._key not in status: self._state = None - else: - if self.device_class == SensorDeviceClass.TIMESTAMP: - if ATTR_VALUE not in status[self._key]: - self._state = None - elif ( - self._state is not None - and self._sign == 1 - and self._state < dt_util.utcnow() - ): - # if the date is supposed to be in the future but we're - # already past it, set state to None. - self._state = None - else: - seconds = self._sign * float(status[self._key][ATTR_VALUE]) - self._state = dt_util.utcnow() + timedelta(seconds=seconds) + elif self.device_class == SensorDeviceClass.TIMESTAMP: + if ATTR_VALUE not in status[self._key]: + self._state = None + elif ( + self._state is not None + and self._sign == 1 + and self._state < dt_util.utcnow() + ): + # if the date is supposed to be in the future but we're + # already past it, set state to None. + self._state = None else: - self._state = status[self._key].get(ATTR_VALUE) - if self._key == BSH_OPERATION_STATE: - # Value comes back as an enum, we only really care about the - # last part, so split it off - # https://developer.home-connect.com/docs/status/operation_state - self._state = self._state.split(".")[-1] + seconds = self._sign * float(status[self._key][ATTR_VALUE]) + self._state = dt_util.utcnow() + timedelta(seconds=seconds) + else: + self._state = status[self._key].get(ATTR_VALUE) + if self._key == BSH_OPERATION_STATE: + # Value comes back as an enum, we only really care about the + # last part, so split it off + # https://developer.home-connect.com/docs/status/operation_state + self._state = self._state.split(".")[-1] _LOGGER.debug("Updated, new state: %s", self._state) @property diff --git a/homeassistant/components/homekit/accessories.py b/homeassistant/components/homekit/accessories.py index a2e3f8487c6..00168ef3898 100644 --- a/homeassistant/components/homekit/accessories.py +++ b/homeassistant/components/homekit/accessories.py @@ -281,7 +281,7 @@ class HomeAccessory(Accessory): # type: ignore[misc] display_name=cleanup_name_for_homekit(name), aid=aid, iid_manager=HomeIIDManager(driver.iid_storage), - *args, + *args, # noqa: B026 **kwargs, ) self.config = config or {} diff --git a/homeassistant/components/homematicip_cloud/generic_entity.py b/homeassistant/components/homematicip_cloud/generic_entity.py index a5296675292..7a6e7c18e13 100644 --- a/homeassistant/components/homematicip_cloud/generic_entity.py +++ b/homeassistant/components/homematicip_cloud/generic_entity.py @@ -164,7 +164,7 @@ class HomematicipGenericEntity(Entity): else: # Remove from entity registry. # Only relevant for entities that do not belong to a device. - if entity_id := self.registry_entry.entity_id: + if entity_id := self.registry_entry.entity_id: # noqa: PLR5501 entity_registry = er.async_get(self.hass) if entity_id in entity_registry.entities: entity_registry.async_remove(entity_id) @@ -185,9 +185,8 @@ class HomematicipGenericEntity(Entity): if hasattr(self._device, "functionalChannels"): if self._is_multi_channel: name = self._device.functionalChannels[self._channel].label - else: - if len(self._device.functionalChannels) > 1: - name = self._device.functionalChannels[1].label + elif len(self._device.functionalChannels) > 1: + name = self._device.functionalChannels[1].label # Use device label, if name is not defined by channel label. if not name: diff --git a/homeassistant/components/hyperion/light.py b/homeassistant/components/hyperion/light.py index ba1dbfbafc2..d44688b3bed 100644 --- a/homeassistant/components/hyperion/light.py +++ b/homeassistant/components/hyperion/light.py @@ -337,15 +337,14 @@ class HyperionBaseLight(LightEntity): ): return # == Set a color - else: - if not await self._client.async_send_set_color( - **{ - const.KEY_PRIORITY: self._get_option(CONF_PRIORITY), - const.KEY_COLOR: rgb_color, - const.KEY_ORIGIN: DEFAULT_ORIGIN, - } - ): - return + elif not await self._client.async_send_set_color( + **{ + const.KEY_PRIORITY: self._get_option(CONF_PRIORITY), + const.KEY_COLOR: rgb_color, + const.KEY_ORIGIN: DEFAULT_ORIGIN, + } + ): + return def _set_internal_state( self, diff --git a/homeassistant/components/icloud/config_flow.py b/homeassistant/components/icloud/config_flow.py index 6cdde2249c8..4be5487f755 100644 --- a/homeassistant/components/icloud/config_flow.py +++ b/homeassistant/components/icloud/config_flow.py @@ -263,13 +263,12 @@ class IcloudFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): self.api.validate_2fa_code, self._verification_code ): raise PyiCloudException("The code you entered is not valid.") - else: - if not await self.hass.async_add_executor_job( - self.api.validate_verification_code, - self._trusted_device, - self._verification_code, - ): - raise PyiCloudException("The code you entered is not valid.") + elif not await self.hass.async_add_executor_job( + self.api.validate_verification_code, + self._trusted_device, + self._verification_code, + ): + raise PyiCloudException("The code you entered is not valid.") except PyiCloudException as error: # Reset to the initial 2FA state to allow the user to retry _LOGGER.error("Failed to verify verification code: %s", error) diff --git a/homeassistant/components/ihc/light.py b/homeassistant/components/ihc/light.py index 089317ca7d7..b469cb54aee 100644 --- a/homeassistant/components/ihc/light.py +++ b/homeassistant/components/ihc/light.py @@ -96,29 +96,26 @@ class IhcLight(IHCDevice, LightEntity): """Turn the light on.""" if ATTR_BRIGHTNESS in kwargs: brightness = kwargs[ATTR_BRIGHTNESS] - else: - if (brightness := self._brightness) == 0: - brightness = 255 + elif (brightness := self._brightness) == 0: + brightness = 255 if self._dimmable: await async_set_int( self.hass, self.ihc_controller, self.ihc_id, int(brightness * 100 / 255) ) + elif self._ihc_on_id: + await async_pulse(self.hass, self.ihc_controller, self._ihc_on_id) else: - if self._ihc_on_id: - await async_pulse(self.hass, self.ihc_controller, self._ihc_on_id) - else: - await async_set_bool(self.hass, self.ihc_controller, self.ihc_id, True) + await async_set_bool(self.hass, self.ihc_controller, self.ihc_id, True) async def async_turn_off(self, **kwargs: Any) -> None: """Turn the light off.""" if self._dimmable: await async_set_int(self.hass, self.ihc_controller, self.ihc_id, 0) + elif self._ihc_off_id: + await async_pulse(self.hass, self.ihc_controller, self._ihc_off_id) else: - if self._ihc_off_id: - await async_pulse(self.hass, self.ihc_controller, self._ihc_off_id) - else: - await async_set_bool(self.hass, self.ihc_controller, self.ihc_id, False) + await async_set_bool(self.hass, self.ihc_controller, self.ihc_id, False) def on_ihc_change(self, ihc_id, value): """Handle IHC notifications.""" diff --git a/homeassistant/components/influxdb/__init__.py b/homeassistant/components/influxdb/__init__.py index 8fde1c2d8be..f879ab37e8f 100644 --- a/homeassistant/components/influxdb/__init__.py +++ b/homeassistant/components/influxdb/__init__.py @@ -145,12 +145,11 @@ def validate_version_specific_config(conf: dict) -> dict: f" {CONF_API_VERSION} is {DEFAULT_API_VERSION}" ) - else: - if CONF_TOKEN in conf: - raise vol.Invalid( - f"{CONF_TOKEN} and {CONF_BUCKET} are only allowed when" - f" {CONF_API_VERSION} is {API_VERSION_2}" - ) + elif CONF_TOKEN in conf: + raise vol.Invalid( + f"{CONF_TOKEN} and {CONF_BUCKET} are only allowed when" + f" {CONF_API_VERSION} is {API_VERSION_2}" + ) return conf diff --git a/homeassistant/components/input_datetime/__init__.py b/homeassistant/components/input_datetime/__init__.py index 769b2d794d0..8762769194f 100644 --- a/homeassistant/components/input_datetime/__init__.py +++ b/homeassistant/components/input_datetime/__init__.py @@ -292,13 +292,12 @@ class InputDatetime(collection.CollectionEntity, RestoreEntity): else: current_datetime = py_datetime.datetime.combine(date, DEFAULT_TIME) + elif (time := dt_util.parse_time(old_state.state)) is None: + current_datetime = dt_util.parse_datetime(default_value) else: - if (time := dt_util.parse_time(old_state.state)) is None: - current_datetime = dt_util.parse_datetime(default_value) - else: - current_datetime = py_datetime.datetime.combine( - py_datetime.date.today(), time - ) + current_datetime = py_datetime.datetime.combine( + py_datetime.date.today(), time + ) self._current_datetime = current_datetime.replace( tzinfo=dt_util.DEFAULT_TIME_ZONE diff --git a/homeassistant/components/isy994/select.py b/homeassistant/components/isy994/select.py index d2b10ef7419..60e2111848d 100644 --- a/homeassistant/components/isy994/select.py +++ b/homeassistant/components/isy994/select.py @@ -76,10 +76,9 @@ async def async_setup_entry( options = RAMP_RATE_OPTIONS elif control == CMD_BACKLIGHT: options = BACKLIGHT_INDEX - else: - if uom := node.aux_properties[control].uom == UOM_INDEX: - if options_dict := UOM_TO_STATES.get(uom): - options = list(options_dict.values()) + elif uom := node.aux_properties[control].uom == UOM_INDEX: + if options_dict := UOM_TO_STATES.get(uom): + options = list(options_dict.values()) description = SelectEntityDescription( key=f"{node.address}_{control}", diff --git a/homeassistant/components/matter/lock.py b/homeassistant/components/matter/lock.py index c529ee12c5f..e7d177e484c 100644 --- a/homeassistant/components/matter/lock.py +++ b/homeassistant/components/matter/lock.py @@ -116,18 +116,18 @@ class DoorLockFeature(IntFlag): Should be replaced by the library provided one once that is released. """ - kPinCredential = 0x1 - kRfidCredential = 0x2 - kFingerCredentials = 0x4 - kLogging = 0x8 - kWeekDayAccessSchedules = 0x10 - kDoorPositionSensor = 0x20 - kFaceCredentials = 0x40 - kCredentialsOverTheAirAccess = 0x80 - kUser = 0x100 - kNotification = 0x200 - kYearDayAccessSchedules = 0x400 - kHolidaySchedules = 0x800 + kPinCredential = 0x1 # noqa: N815 + kRfidCredential = 0x2 # noqa: N815 + kFingerCredentials = 0x4 # noqa: N815 + kLogging = 0x8 # noqa: N815 + kWeekDayAccessSchedules = 0x10 # noqa: N815 + kDoorPositionSensor = 0x20 # noqa: N815 + kFaceCredentials = 0x40 # noqa: N815 + kCredentialsOverTheAirAccess = 0x80 # noqa: N815 + kUser = 0x100 # noqa: N815 + kNotification = 0x200 # noqa: N815 + kYearDayAccessSchedules = 0x400 # noqa: N815 + kHolidaySchedules = 0x800 # noqa: N815 DISCOVERY_SCHEMAS = [ diff --git a/homeassistant/components/media_player/browse_media.py b/homeassistant/components/media_player/browse_media.py index 2b046868f16..1e9be742c53 100644 --- a/homeassistant/components/media_player/browse_media.py +++ b/homeassistant/components/media_player/browse_media.py @@ -42,9 +42,8 @@ def async_process_play_media_url( if parsed.is_absolute(): if not is_hass_url(hass, media_content_id): return media_content_id - else: - if media_content_id[0] != "/": - return media_content_id + elif media_content_id[0] != "/": + return media_content_id if parsed.query: logging.getLogger(__name__).debug( diff --git a/homeassistant/components/meteo_france/sensor.py b/homeassistant/components/meteo_france/sensor.py index ca3284d957c..8c27f2970a3 100644 --- a/homeassistant/components/meteo_france/sensor.py +++ b/homeassistant/components/meteo_france/sensor.py @@ -271,11 +271,10 @@ class MeteoFranceSensor(CoordinatorEntity[DataUpdateCoordinator[_DataT]], Sensor value = data[0][path[1]] # General case + elif len(path) == 3: + value = data[path[1]][path[2]] else: - if len(path) == 3: - value = data[path[1]][path[2]] - else: - value = data[path[1]] + value = data[path[1]] if self.entity_description.key in ("wind_speed", "wind_gust"): # convert API wind speed from m/s to km/h diff --git a/homeassistant/components/netatmo/__init__.py b/homeassistant/components/netatmo/__init__.py index aa8728d548d..e26a32965a3 100644 --- a/homeassistant/components/netatmo/__init__.py +++ b/homeassistant/components/netatmo/__init__.py @@ -234,11 +234,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await register_webhook(None) cloud.async_listen_connection_change(hass, manage_cloudhook) + elif hass.state == CoreState.running: + await register_webhook(None) else: - if hass.state == CoreState.running: - await register_webhook(None) - else: - hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, register_webhook) + hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, register_webhook) hass.services.async_register(DOMAIN, "register_webhook", register_webhook) hass.services.async_register(DOMAIN, "unregister_webhook", unregister_webhook) diff --git a/homeassistant/components/plex/server.py b/homeassistant/components/plex/server.py index 9684c79792a..1c3c944c9c4 100644 --- a/homeassistant/components/plex/server.py +++ b/homeassistant/components/plex/server.py @@ -199,7 +199,8 @@ class PlexServer: if _update_plexdirect_hostname(): config_entry_update_needed = True else: - raise Unauthorized( # pylint: disable=raise-missing-from + # pylint: disable-next=raise-missing-from + raise Unauthorized( # noqa: TRY200 "New certificate cannot be validated" " with provided token" ) diff --git a/homeassistant/components/plex/services.py b/homeassistant/components/plex/services.py index 62576471448..10d005d1043 100644 --- a/homeassistant/components/plex/services.py +++ b/homeassistant/components/plex/services.py @@ -145,7 +145,7 @@ def process_plex_payload( plex_server = get_plex_server(hass, plex_server_id=server_id) else: # Handle legacy payloads without server_id in URL host position - if plex_url.host == "search": + if plex_url.host == "search": # noqa: PLR5501 content = {} else: content = int(plex_url.host) # type: ignore[arg-type] diff --git a/homeassistant/components/ps4/media_player.py b/homeassistant/components/ps4/media_player.py index 23438dd80c4..42bc15cf0ca 100644 --- a/homeassistant/components/ps4/media_player.py +++ b/homeassistant/components/ps4/media_player.py @@ -192,12 +192,10 @@ class PS4Device(MediaPlayerEntity): self.async_get_title_data(title_id, name), "ps4.media_player-get_title_data", ) - else: - if self.state != MediaPlayerState.IDLE: - self.idle() - else: - if self.state != MediaPlayerState.STANDBY: - self.state_standby() + elif self.state != MediaPlayerState.IDLE: + self.idle() + elif self.state != MediaPlayerState.STANDBY: + self.state_standby() elif self._retry > DEFAULT_RETRIES: self.state_unknown() diff --git a/homeassistant/components/python_script/__init__.py b/homeassistant/components/python_script/__init__.py index bbb262ac7db..10751d28c06 100644 --- a/homeassistant/components/python_script/__init__.py +++ b/homeassistant/components/python_script/__init__.py @@ -221,7 +221,7 @@ def execute(hass, filename, source, data=None): try: _LOGGER.info("Executing %s: %s", filename, data) # pylint: disable-next=exec-used - exec(compiled.code, restricted_globals) + exec(compiled.code, restricted_globals) # noqa: S102 except ScriptError as err: logger.error("Error executing script: %s", err) except Exception as err: # pylint: disable=broad-except diff --git a/homeassistant/components/recorder/history/legacy.py b/homeassistant/components/recorder/history/legacy.py index 74b17d9daa7..64ce1aa7d55 100644 --- a/homeassistant/components/recorder/history/legacy.py +++ b/homeassistant/components/recorder/history/legacy.py @@ -434,11 +434,11 @@ def _state_changed_during_period_stmt( ) else: stmt += lambda q: q.order_by(States.entity_id, States.last_updated.desc()) + elif schema_version >= 31: + stmt += lambda q: q.order_by(States.entity_id, States.last_updated_ts) else: - if schema_version >= 31: - stmt += lambda q: q.order_by(States.entity_id, States.last_updated_ts) - else: - stmt += lambda q: q.order_by(States.entity_id, States.last_updated) + stmt += lambda q: q.order_by(States.entity_id, States.last_updated) + if limit: stmt += lambda q: q.limit(limit) return stmt diff --git a/homeassistant/components/recorder/util.py b/homeassistant/components/recorder/util.py index d963901f17b..f3de9824a16 100644 --- a/homeassistant/components/recorder/util.py +++ b/homeassistant/components/recorder/util.py @@ -530,11 +530,10 @@ def setup_connection_for_dialect( version, ) - else: - if not version or version < MIN_VERSION_MYSQL: - _fail_unsupported_version( - version or version_string, "MySQL", MIN_VERSION_MYSQL - ) + elif not version or version < MIN_VERSION_MYSQL: + _fail_unsupported_version( + version or version_string, "MySQL", MIN_VERSION_MYSQL + ) slow_range_in_select = bool( not version diff --git a/homeassistant/components/rest/switch.py b/homeassistant/components/rest/switch.py index 89b6529d483..342808f3250 100644 --- a/homeassistant/components/rest/switch.py +++ b/homeassistant/components/rest/switch.py @@ -232,12 +232,11 @@ class RestSwitch(TemplateEntity, SwitchEntity): self._attr_is_on = False else: self._attr_is_on = None + elif text == self._body_on.template: + self._attr_is_on = True + elif text == self._body_off.template: + self._attr_is_on = False else: - if text == self._body_on.template: - self._attr_is_on = True - elif text == self._body_off.template: - self._attr_is_on = False - else: - self._attr_is_on = None + self._attr_is_on = None return req diff --git a/homeassistant/components/samsungtv/bridge.py b/homeassistant/components/samsungtv/bridge.py index ba09cf9fe3b..0cc4dd556d5 100644 --- a/homeassistant/components/samsungtv/bridge.py +++ b/homeassistant/components/samsungtv/bridge.py @@ -549,7 +549,7 @@ class SamsungTVWSBridge( except (ConnectionFailure, OSError, AsyncioTimeoutError) as err: LOGGER.debug("Failing config: %s, %s error: %s", config, type(err), err) # pylint: disable-next=useless-else-on-loop - else: + else: # noqa: PLW0120 if result: return result diff --git a/homeassistant/components/samsungtv/config_flow.py b/homeassistant/components/samsungtv/config_flow.py index f98e3667b59..124dab73004 100644 --- a/homeassistant/components/samsungtv/config_flow.py +++ b/homeassistant/components/samsungtv/config_flow.py @@ -184,7 +184,6 @@ class SamsungTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): raise AbortFlow(result) assert method is not None self._bridge = SamsungTVBridge.get_bridge(self.hass, method, self._host) - return async def _async_get_device_info_and_method( self, diff --git a/homeassistant/components/satel_integra/binary_sensor.py b/homeassistant/components/satel_integra/binary_sensor.py index 389bde884ef..5d2ce2c193c 100644 --- a/homeassistant/components/satel_integra/binary_sensor.py +++ b/homeassistant/components/satel_integra/binary_sensor.py @@ -80,11 +80,10 @@ class SatelIntegraBinarySensor(BinarySensorEntity): self._state = 1 else: self._state = 0 + elif self._device_number in self._satel.violated_zones: + self._state = 1 else: - if self._device_number in self._satel.violated_zones: - self._state = 1 - else: - self._state = 0 + self._state = 0 self.async_on_remove( async_dispatcher_connect( self.hass, self._react_to_signal, self._devices_updated diff --git a/homeassistant/components/screenlogic/__init__.py b/homeassistant/components/screenlogic/__init__.py index 6662c20ad4f..3370c196c3c 100644 --- a/homeassistant/components/screenlogic/__init__.py +++ b/homeassistant/components/screenlogic/__init__.py @@ -168,4 +168,3 @@ class ScreenlogicDataUpdateCoordinator(DataUpdateCoordinator[None]): if self.gateway.is_connected: await self.gateway.async_disconnect() raise UpdateFailed(ex.msg) from ex - return None diff --git a/homeassistant/components/scsgate/__init__.py b/homeassistant/components/scsgate/__init__.py index 5810f12bca2..af5921e2c3b 100644 --- a/homeassistant/components/scsgate/__init__.py +++ b/homeassistant/components/scsgate/__init__.py @@ -74,7 +74,7 @@ class SCSGate: def handle_message(self, message): """Handle a messages seen on the bus.""" - self._logger.debug(f"Received message {message}") + self._logger.debug("Received message %s", message) if not isinstance(message, StateMessage) and not isinstance( message, ScenarioTriggeredMessage ): @@ -98,9 +98,7 @@ class SCSGate: self._logger.error(msg) else: self._logger.info( - "Ignoring state message for device {} because unknown".format( - message.entity - ) + "Ignoring state message for device %s because unknown", message.entity ) @property diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index daffcb006d1..9f95ea5ac21 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -200,18 +200,13 @@ def async_setup_rpc_attribute_entities( domain = sensor_class.__module__.split(".")[-1] unique_id = f"{coordinator.mac}-{key}-{sensor_id}" async_remove_shelly_entity(hass, domain, unique_id) - else: - if description.use_polling_coordinator: - if not sleep_period: - entities.append( - sensor_class( - polling_coordinator, key, sensor_id, description - ) - ) - else: + elif description.use_polling_coordinator: + if not sleep_period: entities.append( - sensor_class(coordinator, key, sensor_id, description) + sensor_class(polling_coordinator, key, sensor_id, description) ) + else: + entities.append(sensor_class(coordinator, key, sensor_id, description)) if not entities: return diff --git a/homeassistant/components/snips/__init__.py b/homeassistant/components/snips/__init__.py index 3d19de74f91..33500217397 100644 --- a/homeassistant/components/snips/__init__.py +++ b/homeassistant/components/snips/__init__.py @@ -176,7 +176,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: await mqtt.async_publish( hass, "hermes/dialogueManager/startSession", json.dumps(notification) ) - return async def snips_say_action(call: ServiceCall) -> None: """Send a Snips action message.""" @@ -193,7 +192,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: await mqtt.async_publish( hass, "hermes/dialogueManager/startSession", json.dumps(notification) ) - return async def feedback_on(call: ServiceCall) -> None: """Turn feedback sounds on.""" diff --git a/homeassistant/components/solarlog/__init__.py b/homeassistant/components/solarlog/__init__.py index d35da5b8a90..e0ab838922b 100644 --- a/homeassistant/components/solarlog/__init__.py +++ b/homeassistant/components/solarlog/__init__.py @@ -56,7 +56,7 @@ class SolarlogData(update_coordinator.DataUpdateCoordinator): try: data = await self.hass.async_add_executor_job(SolarLog, self.host) except (OSError, Timeout, HTTPError) as err: - raise update_coordinator.UpdateFailed(err) + raise update_coordinator.UpdateFailed(err) from err if data.time.year == 1999: raise update_coordinator.UpdateFailed( diff --git a/homeassistant/components/solarlog/config_flow.py b/homeassistant/components/solarlog/config_flow.py index 4267502e3ca..86fc0607bf3 100644 --- a/homeassistant/components/solarlog/config_flow.py +++ b/homeassistant/components/solarlog/config_flow.py @@ -68,9 +68,8 @@ class SolarLogConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): if self._host_in_configuration_exists(host): self._errors[CONF_HOST] = "already_configured" - else: - if await self._test_connection(host): - return self.async_create_entry(title=name, data={CONF_HOST: host}) + elif await self._test_connection(host): + return self.async_create_entry(title=name, data={CONF_HOST: host}) else: user_input = {} user_input[CONF_NAME] = DEFAULT_NAME diff --git a/homeassistant/components/statsd/__init__.py b/homeassistant/components/statsd/__init__.py index bfc972a17a1..046c01cba32 100644 --- a/homeassistant/components/statsd/__init__.py +++ b/homeassistant/components/statsd/__init__.py @@ -82,9 +82,8 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool: stat = "{}.{}".format(state.entity_id, key.replace(" ", "_")) statsd_client.gauge(stat, value, sample_rate) - else: - if isinstance(_state, (float, int)): - statsd_client.gauge(state.entity_id, _state, sample_rate) + elif isinstance(_state, (float, int)): + statsd_client.gauge(state.entity_id, _state, sample_rate) # Increment the count statsd_client.incr(state.entity_id, rate=sample_rate) diff --git a/homeassistant/components/supla/__init__.py b/homeassistant/components/supla/__init__.py index 541b31eb0a3..0d1308ca5a6 100644 --- a/homeassistant/components/supla/__init__.py +++ b/homeassistant/components/supla/__init__.py @@ -102,7 +102,8 @@ async def discover_devices(hass, hass_config): async with async_timeout.timeout(SCAN_INTERVAL.total_seconds()): channels = { channel["id"]: channel - for channel in await server.get_channels( # pylint: disable=cell-var-from-loop + # pylint: disable-next=cell-var-from-loop + for channel in await server.get_channels( # noqa: B023 include=["iodevice", "state", "connected"] ) } diff --git a/homeassistant/components/synology_dsm/coordinator.py b/homeassistant/components/synology_dsm/coordinator.py index 3b25d93154a..9d0ccfd86d2 100644 --- a/homeassistant/components/synology_dsm/coordinator.py +++ b/homeassistant/components/synology_dsm/coordinator.py @@ -99,7 +99,6 @@ class SynologyDSMCentralUpdateCoordinator(SynologyDSMUpdateCoordinator[None]): await self.api.async_update() except SYNOLOGY_CONNECTION_EXCEPTIONS as err: raise UpdateFailed(f"Error communicating with API: {err}") from err - return None class SynologyDSMCameraUpdateCoordinator( diff --git a/homeassistant/components/venstar/__init__.py b/homeassistant/components/venstar/__init__.py index 3f31c417a02..48760a8bfc0 100644 --- a/homeassistant/components/venstar/__init__.py +++ b/homeassistant/components/venstar/__init__.py @@ -123,8 +123,6 @@ class VenstarDataUpdateCoordinator(update_coordinator.DataUpdateCoordinator[None f"Exception during Venstar runtime update: {ex}" ) from ex - return None - class VenstarEntity(CoordinatorEntity[VenstarDataUpdateCoordinator]): """Representation of a Venstar entity.""" diff --git a/homeassistant/components/websocket_api/connection.py b/homeassistant/components/websocket_api/connection.py index c07661893f7..319188dae21 100644 --- a/homeassistant/components/websocket_api/connection.py +++ b/homeassistant/components/websocket_api/connection.py @@ -178,7 +178,7 @@ class ActiveConnection: return if not (handler_schema := self.handlers.get(type_)): - self.logger.info(f"Received unknown command: {type_}") + self.logger.info("Received unknown command: %s", type_) self.send_message( messages.error_message( cur_id, const.ERR_UNKNOWN_COMMAND, "Unknown command." diff --git a/homeassistant/components/worxlandroid/sensor.py b/homeassistant/components/worxlandroid/sensor.py index d15a33e9e17..834a0b95f42 100644 --- a/homeassistant/components/worxlandroid/sensor.py +++ b/homeassistant/components/worxlandroid/sensor.py @@ -129,9 +129,8 @@ class WorxLandroidSensor(SensorEntity): elif self.sensor == "state": self._state = self.get_state(data) - else: - if self.sensor == "error": - self._state = "no" + elif self.sensor == "error": + self._state = "no" @staticmethod def get_error(obj): diff --git a/homeassistant/components/yeelightsunflower/light.py b/homeassistant/components/yeelightsunflower/light.py index 29a6118fc03..c50c176c157 100644 --- a/homeassistant/components/yeelightsunflower/light.py +++ b/homeassistant/components/yeelightsunflower/light.py @@ -74,17 +74,16 @@ class SunflowerBulb(LightEntity): # when no arguments, just turn light on (full brightness) if not kwargs: self._light.turn_on() - else: - if ATTR_HS_COLOR in kwargs and ATTR_BRIGHTNESS in kwargs: - rgb = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR]) - bright = int(kwargs[ATTR_BRIGHTNESS] / 255 * 100) - self._light.set_all(rgb[0], rgb[1], rgb[2], bright) - elif ATTR_HS_COLOR in kwargs: - rgb = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR]) - self._light.set_rgb_color(rgb[0], rgb[1], rgb[2]) - elif ATTR_BRIGHTNESS in kwargs: - bright = int(kwargs[ATTR_BRIGHTNESS] / 255 * 100) - self._light.set_brightness(bright) + elif ATTR_HS_COLOR in kwargs and ATTR_BRIGHTNESS in kwargs: + rgb = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR]) + bright = int(kwargs[ATTR_BRIGHTNESS] / 255 * 100) + self._light.set_all(rgb[0], rgb[1], rgb[2], bright) + elif ATTR_HS_COLOR in kwargs: + rgb = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR]) + self._light.set_rgb_color(rgb[0], rgb[1], rgb[2]) + elif ATTR_BRIGHTNESS in kwargs: + bright = int(kwargs[ATTR_BRIGHTNESS] / 255 * 100) + self._light.set_brightness(bright) def turn_off(self, **kwargs: Any) -> None: """Instruct the light to turn off.""" diff --git a/homeassistant/components/zabbix/sensor.py b/homeassistant/components/zabbix/sensor.py index a5172d5ef95..2fd2d48faba 100644 --- a/homeassistant/components/zabbix/sensor.py +++ b/homeassistant/components/zabbix/sensor.py @@ -67,17 +67,14 @@ def setup_platform( for hostid in hostids: _LOGGER.debug("Creating Zabbix Sensor: %s", str(hostid)) sensors.append(ZabbixSingleHostTriggerCountSensor(zapi, [hostid], name)) + elif not hostids: + # Single sensor that provides the total count of triggers. + _LOGGER.debug("Creating Zabbix Sensor") + sensors.append(ZabbixTriggerCountSensor(zapi, name)) else: - if not hostids: - # Single sensor that provides the total count of triggers. - _LOGGER.debug("Creating Zabbix Sensor") - sensors.append(ZabbixTriggerCountSensor(zapi, name)) - else: - # Single sensor that sums total issues for all hosts - _LOGGER.debug("Creating Zabbix Sensor group: %s", str(hostids)) - sensors.append( - ZabbixMultipleHostTriggerCountSensor(zapi, hostids, name) - ) + # Single sensor that sums total issues for all hosts + _LOGGER.debug("Creating Zabbix Sensor group: %s", str(hostids)) + sensors.append(ZabbixMultipleHostTriggerCountSensor(zapi, hostids, name)) else: # Single sensor that provides the total count of triggers. diff --git a/homeassistant/components/ziggo_mediabox_xl/media_player.py b/homeassistant/components/ziggo_mediabox_xl/media_player.py index a0f789f1708..20a78c80ac5 100644 --- a/homeassistant/components/ziggo_mediabox_xl/media_player.py +++ b/homeassistant/components/ziggo_mediabox_xl/media_player.py @@ -62,11 +62,10 @@ def setup_platform( # Check if a connection can be established to the device. if mediabox.test_connection(): connection_successful = True + elif manual_config: + _LOGGER.info("Can't connect to %s", host) else: - if manual_config: - _LOGGER.info("Can't connect to %s", host) - else: - _LOGGER.error("Can't connect to %s", host) + _LOGGER.error("Can't connect to %s", host) # When the device is in eco mode it's not connected to the network # so it needs to be added anyway if it's configured manually. if manual_config or connection_successful: diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 2f2f3cdf0a9..4ebf0af3b25 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -724,7 +724,7 @@ def socket_timeout(value: Any | None) -> object: return float_value raise vol.Invalid("Invalid socket timeout value. float > 0.0 required.") except Exception as err: - raise vol.Invalid(f"Invalid socket timeout: {err}") + raise vol.Invalid(f"Invalid socket timeout: {err}") from err # pylint: disable=no-value-for-parameter @@ -761,7 +761,7 @@ def uuid4_hex(value: Any) -> str: try: result = UUID(value, version=4) except (ValueError, AttributeError, TypeError) as error: - raise vol.Invalid("Invalid Version4 UUID", error_message=str(error)) + raise vol.Invalid("Invalid Version4 UUID", error_message=str(error)) from error if result.hex != value.lower(): # UUID() will create a uuid4 if input is invalid @@ -1226,7 +1226,7 @@ def script_action(value: Any) -> dict: try: action = determine_script_action(value) except ValueError as err: - raise vol.Invalid(str(err)) + raise vol.Invalid(str(err)) from err return ACTION_TYPE_SCHEMAS[action](value) diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 45f8f15c9df..675d368873a 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -753,7 +753,7 @@ class EntityPlatform: if already_exists: self.logger.error( - f"Entity id already exists - ignoring: {entity.entity_id}" + "Entity id already exists - ignoring: %s", entity.entity_id ) entity.add_to_platform_abort() return diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index e871c5120cd..0dacb90e318 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -1527,11 +1527,10 @@ class Script: variables = {} variables["context"] = context + elif self._copy_variables_on_run: + variables = cast(dict, copy(run_variables)) else: - if self._copy_variables_on_run: - variables = cast(dict, copy(run_variables)) - else: - variables = cast(dict, run_variables) + variables = cast(dict, run_variables) # Prevent non-allowed recursive calls which will cause deadlocks when we try to # stop (restart) or wait for (queued) our own script run. diff --git a/homeassistant/util/dt.py b/homeassistant/util/dt.py index 2dfc9a6f622..4f49ec44ca7 100644 --- a/homeassistant/util/dt.py +++ b/homeassistant/util/dt.py @@ -81,7 +81,8 @@ def set_default_time_zone(time_zone: dt.tzinfo) -> None: Async friendly. """ - global DEFAULT_TIME_ZONE # pylint: disable=global-statement + # pylint: disable-next=global-statement + global DEFAULT_TIME_ZONE # noqa: PLW0603 assert isinstance(time_zone, dt.tzinfo) diff --git a/pyproject.toml b/pyproject.toml index ff238d97b69..9c67835c544 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -163,19 +163,223 @@ disable = [ "too-few-public-methods", "too-many-ancestors", "too-many-arguments", - "too-many-branches", "too-many-instance-attributes", "too-many-lines", "too-many-locals", "too-many-public-methods", - "too-many-return-statements", - "too-many-statements", "too-many-boolean-expressions", - "unused-argument", "wrong-import-order", "consider-using-f-string", "consider-using-namedtuple-or-dataclass", "consider-using-assignment-expr", + + # Handled by ruff + # Ref: + "await-outside-async", # PLE1142 + "bad-str-strip-call", # PLE1310 + "bad-string-format-type", # PLE1307 + "bidirectional-unicode", # PLE2502 + "continue-in-finally", # PLE0116 + "duplicate-bases", # PLE0241 + "format-needs-mapping", # F502 + "function-redefined", # F811 + "invalid-all-format", # PLE0605 + "invalid-all-object", # PLE0604 + "invalid-character-backspace", # PLE2510 + "invalid-character-esc", # PLE2513 + "invalid-character-nul", # PLE2514 + "invalid-character-sub", # PLE2512 + "invalid-character-zero-width-space", # PLE2515 + "logging-too-few-args", # PLE1206 + "logging-too-many-args", # PLE1205 + "missing-format-string-key", # F524 + "mixed-format-string", # F506 + "no-method-argument", # N805 + "no-self-argument", # N805 + "nonexistent-operator", # B002 + "nonlocal-without-binding", # PLE0117 + "not-in-loop", # F701, F702 + "notimplemented-raised", # F901 + "return-in-init", # PLE0101 + "return-outside-function", # F706 + "syntax-error", # E999 + "too-few-format-args", # F524 + "too-many-format-args", # F522 + "too-many-star-expressions", # F622 + "truncated-format-string", # F501 + "undefined-all-variable", # F822 + "undefined-variable", # F821 + "used-prior-global-declaration", # PLE0118 + "yield-inside-async-function", # PLE1700 + "yield-outside-function", # F704 + "anomalous-backslash-in-string", # W605 + "assert-on-string-literal", # PLW0129 + "assert-on-tuple", # F631 + "bad-format-string", # W1302, F + "bad-format-string-key", # W1300, F + "bare-except", # E722 + "binary-op-exception", # PLW0711 + "cell-var-from-loop", # B023 + # "dangerous-default-value", # B006, ruff catches new occurrences, needs more work + "duplicate-except", # B014 + "duplicate-key", # F601 + "duplicate-string-formatting-argument", # F + "duplicate-value", # F + "eval-used", # PGH001 + "exec-used", # S102 + # "expression-not-assigned", # B018, ruff catches new occurrences, needs more work + "f-string-without-interpolation", # F541 + "forgotten-debug-statement", # T100 + "format-string-without-interpolation", # F + # "global-statement", # PLW0603, ruff catches new occurrences, needs more work + "global-variable-not-assigned", # PLW0602 + "implicit-str-concat", # ISC001 + "import-self", # PLW0406 + "inconsistent-quotes", # Q000 + "invalid-envvar-default", # PLW1508 + "keyword-arg-before-vararg", # B026 + "logging-format-interpolation", # G + "logging-fstring-interpolation", # G + "logging-not-lazy", # G + "misplaced-future", # F404 + "named-expr-without-context", # PLW0131 + "nested-min-max", # PLW3301 + # "pointless-statement", # B018, ruff catches new occurrences, needs more work + "raise-missing-from", # TRY200 + # "redefined-builtin", # A001, ruff is way more stricter, needs work + "try-except-raise", # TRY302 + "unused-argument", # ARG001, we don't use it + "unused-format-string-argument", #F507 + "unused-format-string-key", # F504 + "unused-import", # F401 + "unused-variable", # F841 + "useless-else-on-loop", # PLW0120 + "wildcard-import", # F403 + "bad-classmethod-argument", # N804 + "consider-iterating-dictionary", # SIM118 + "empty-docstring", # D419 + "invalid-name", # N815 + "line-too-long", # E501, disabled globally + "missing-class-docstring", # D101 + "missing-final-newline", # W292 + "missing-function-docstring", # D103 + "missing-module-docstring", # D100 + "multiple-imports", #E401 + "singleton-comparison", # E711, E712 + "superfluous-parens", # UP034 + "ungrouped-imports", # I001 + "unidiomatic-typecheck", # E721 + "unnecessary-direct-lambda-call", # PLC3002 + "unnecessary-lambda-assignment", # PLC3001 + "unneeded-not", # SIM208 + "useless-import-alias", # PLC0414 + "wrong-import-order", # I001 + "wrong-import-position", # E402 + "comparison-of-constants", # PLR0133 + "comparison-with-itself", # PLR0124 + "consider-alternative-union-syntax", # UP007 + "consider-merging-isinstance", # PLR1701 + "consider-using-alias", # UP006 + "consider-using-dict-comprehension", # C402 + "consider-using-generator", # C417 + "consider-using-get", # SIM401 + "consider-using-set-comprehension", # C401 + "consider-using-sys-exit", # PLR1722 + "consider-using-ternary", # SIM108 + "literal-comparison", # F632 + "property-with-parameters", # PLR0206 + "super-with-arguments", # UP008 + "too-many-branches", # PLR0912 + "too-many-return-statements", # PLR0911 + "too-many-statements", # PLR0915 + "trailing-comma-tuple", # COM818 + "unnecessary-comprehension", # C416 + "use-a-generator", # C417 + "use-dict-literal", # C406 + "use-list-literal", # C405 + "useless-object-inheritance", # UP004 + "useless-return", # PLR1711 + + # Handled by mypy + # Ref: + "abstract-class-instantiated", + "arguments-differ", + "assigning-non-slot", + "assignment-from-no-return", + "assignment-from-none", + "bad-exception-cause", + "bad-format-character", + "bad-reversed-sequence", + "bad-super-call", + "bad-thread-instantiation", + "catching-non-exception", + "comparison-with-callable", + "deprecated-class", + "dict-iter-missing-items", + "format-combined-specification", + "global-variable-undefined", + "import-error", + "inconsistent-mro", + "inherit-non-class", + "init-is-generator", + "invalid-class-object", + "invalid-enum-extension", + "invalid-envvar-value", + "invalid-format-returned", + "invalid-hash-returned", + "invalid-metaclass", + "invalid-overridden-method", + "invalid-repr-returned", + "invalid-sequence-index", + "invalid-slice-index", + "invalid-slots-object", + "invalid-slots", + "invalid-star-assignment-target", + "invalid-str-returned", + "invalid-unary-operand-type", + "invalid-unicode-codec", + "isinstance-second-argument-not-valid-type", + "method-hidden", + "misplaced-format-function", + "missing-format-argument-key", + "missing-format-attribute", + "missing-kwoa", + "no-member", + "no-value-for-parameter", + "non-iterator-returned", + "non-str-assignment-to-dunder-name", + "nonlocal-and-global", + "not-a-mapping", + "not-an-iterable", + "not-async-context-manager", + "not-callable", + "not-context-manager", + "overridden-final-method", + "raising-bad-type", + "raising-non-exception", + "redundant-keyword-arg", + "relative-beyond-top-level", + "self-cls-assignment", + "signature-differs", + "star-needs-assignment-target", + "subclassed-final-class", + "super-without-brackets", + "too-many-function-args", + "typevar-double-variance", + "typevar-name-mismatch", + "unbalanced-dict-unpacking", + "unbalanced-tuple-unpacking", + "unexpected-keyword-arg", + "unhashable-member", + "unpacking-non-sequence", + "unsubscriptable-object", + "unsupported-assignment-operation", + "unsupported-binary-operation", + "unsupported-delete-operation", + "unsupported-membership-test", + "used-before-assignment", + "using-final-decorator-in-unsupported-version", + "wrong-exception-operation", ] enable = [ #"useless-suppression", # temporarily every now and then to clean them up @@ -230,16 +434,33 @@ filterwarnings = ["error::sqlalchemy.exc.SAWarning"] target-version = "py310" select = [ + "B002", # Python does not support the unary prefix increment "B007", # Loop control variable {name} not used within loop body "B014", # Exception handler with duplicate exception + "B023", # Function definition does not bind loop variable {name} + "B026", # Star-arg unpacking after a keyword argument is strongly discouraged "C", # complexity + "COM818", # Trailing comma on bare tuple prohibited "D", # docstrings "E", # pycodestyle "F", # pyflakes/autoflake + "G", # flake8-logging-format "I", # isort "ICN001", # import concentions; {name} should be imported as {asname} + "ISC001", # Implicitly concatenated string literals on one line + "N804", # First argument of a class method should be named cls + "N805", # First argument of a method should be named self + "N815", # Variable {name} in class scope should not be mixedCase + "PGH001", # No builtin eval() allowed "PGH004", # Use specific rule codes when using noqa "PLC0414", # Useless import alias. Import alias does not rename original package. + "PLC", # pylint + "PLE", # pylint + "PLR", # pylint + "PLW", # pylint + "Q000", # Double quotes found but single quotes preferred + "RUF006", # Store a reference to the return value of asyncio.create_task + "S102", # Use of exec detected "S103", # bad-file-permissions "S108", # hardcoded-temp-file "S306", # suspicious-mktemp-usage @@ -261,12 +482,15 @@ select = [ "SIM117", # Merge with-statements that use the same scope "SIM118", # Use {key} in {dict} instead of {key} in {dict}.keys() "SIM201", # Use {left} != {right} instead of not {left} == {right} + "SIM208", # Use {expr} instead of not (not {expr}) "SIM212", # Use {a} if {a} else {b} instead of {b} if not {a} else {a} "SIM300", # Yoda conditions. Use 'age == 42' instead of '42 == age'. "SIM401", # Use get from dict with default instead of an if block + "T100", # Trace found: {name} used "T20", # flake8-print "TRY004", # Prefer TypeError exception for invalid type - "RUF006", # Store a reference to the return value of asyncio.create_task + "TRY200", # Use raise from to specify exception cause + "TRY302", # Remove exception handler; error is immediately re-raised "UP", # pyupgrade "W", # pycodestyle ] @@ -279,10 +503,20 @@ ignore = [ "D407", # Section name underlining "E501", # line too long "E731", # do not assign a lambda expression, use a def + "PLC1901", # Lots of false positives + # False positives https://github.com/astral-sh/ruff/issues/5386 + "PLC0208", # Use a sequence type instead of a `set` when iterating over values + "PLR0911", # Too many return statements ({returns} > {max_returns}) + "PLR0912", # Too many branches ({branches} > {max_branches}) + "PLR0913", # Too many arguments to function call ({c_args} > {max_args}) + "PLR0915", # Too many statements ({statements} > {max_statements}) + "PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable + "PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target "UP006", # keep type annotation style as is "UP007", # keep type annotation style as is # Ignored due to performance: https://github.com/charliermarsh/ruff/issues/2923 "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)` + ] [tool.ruff.flake8-import-conventions.extend-aliases] diff --git a/script/hassfest/manifest.py b/script/hassfest/manifest.py index 89a3d70afc7..9a7caec925b 100644 --- a/script/hassfest/manifest.py +++ b/script/hassfest/manifest.py @@ -161,8 +161,8 @@ def verify_version(value: str) -> str: AwesomeVersionStrategy.PEP440, ], ) - except AwesomeVersionException: - raise vol.Invalid(f"'{value}' is not a valid version.") + except AwesomeVersionException as err: + raise vol.Invalid(f"'{value}' is not a valid version.") from err return value diff --git a/script/hassfest/serializer.py b/script/hassfest/serializer.py index 0dd3d35bb15..499ee9d51d9 100644 --- a/script/hassfest/serializer.py +++ b/script/hassfest/serializer.py @@ -91,7 +91,7 @@ def format_python_namespace( return f": {annotation}" if annotation else "" code = "\n\n".join( - f"{key}{_get_annotation(key)}" f" = {to_string(value)}" + f"{key}{_get_annotation(key)} = {to_string(value)}" for key, value in sorted(content.items()) ) if annotations: diff --git a/script/scaffold/gather_info.py b/script/scaffold/gather_info.py index 85a94459d06..47106e7f956 100644 --- a/script/scaffold/gather_info.py +++ b/script/scaffold/gather_info.py @@ -162,8 +162,8 @@ def _gather_info(fields) -> dict: if "default" in info: msg += f" [{info['default']}]" value = input(f"{msg}\n> ") - except (KeyboardInterrupt, EOFError): - raise ExitApp("Interrupted!", 1) + except (KeyboardInterrupt, EOFError) as err: + raise ExitApp("Interrupted!", 1) from err value = value.strip() diff --git a/tests/components/emulated_hue/test_hue_api.py b/tests/components/emulated_hue/test_hue_api.py index ac94467bd59..acfb11ced0a 100644 --- a/tests/components/emulated_hue/test_hue_api.py +++ b/tests/components/emulated_hue/test_hue_api.py @@ -120,7 +120,7 @@ async def _async_setup_emulated_hue(hass: HomeAssistant, conf: ConfigType) -> No hass, emulated_hue.DOMAIN, {emulated_hue.DOMAIN: conf}, - ), + ) await hass.async_block_till_done() diff --git a/tests/components/google_assistant/test_smart_home.py b/tests/components/google_assistant/test_smart_home.py index 31f493db20c..849f9e38a68 100644 --- a/tests/components/google_assistant/test_smart_home.py +++ b/tests/components/google_assistant/test_smart_home.py @@ -680,7 +680,7 @@ async def test_execute_times_out( async def slow_turn_on(*args, **kwargs): # Make DemoLigt.async_turn_on hang waiting for the turn_on_wait event - await turn_on_wait.wait(), + await turn_on_wait.wait() with patch.object( hass.services, "async_call", wraps=hass.services.async_call diff --git a/tests/components/google_wifi/test_sensor.py b/tests/components/google_wifi/test_sensor.py index 868631e9c27..3eceac64904 100644 --- a/tests/components/google_wifi/test_sensor.py +++ b/tests/components/google_wifi/test_sensor.py @@ -30,7 +30,7 @@ MOCK_DATA_NEXT = ( '"ipAddress":false}}' ) -MOCK_DATA_MISSING = '{"software": {},' '"system": {},' '"wan": {}}' +MOCK_DATA_MISSING = '{"software": {},"system": {},"wan": {}}' async def test_setup_minimum( diff --git a/tests/components/homekit/test_diagnostics.py b/tests/components/homekit/test_diagnostics.py index 69e2aa2c8e2..2f18c7a5a89 100644 --- a/tests/components/homekit/test_diagnostics.py +++ b/tests/components/homekit/test_diagnostics.py @@ -190,7 +190,7 @@ async def test_config_entry_accessory( "iid": 3, "perms": ["pr"], "type": "20", - "value": "Home Assistant " "Light", + "value": "Home Assistant Light", }, { "format": "string", @@ -475,7 +475,7 @@ async def test_config_entry_with_trigger_accessory( "iid": 10, "perms": ["pr"], "type": "23", - "value": "Ceiling Lights " "Changed States", + "value": "Ceiling Lights Changed States", }, { "format": "uint8", @@ -521,7 +521,7 @@ async def test_config_entry_with_trigger_accessory( "iid": 16, "perms": ["pr"], "type": "23", - "value": "Ceiling Lights " "Turned Off", + "value": "Ceiling Lights Turned Off", }, { "format": "uint8", @@ -567,7 +567,7 @@ async def test_config_entry_with_trigger_accessory( "iid": 22, "perms": ["pr"], "type": "23", - "value": "Ceiling Lights " "Turned On", + "value": "Ceiling Lights Turned On", }, { "format": "uint8", diff --git a/tests/components/homekit_controller/test_diagnostics.py b/tests/components/homekit_controller/test_diagnostics.py index 3978f46a72e..7fd5b11d5d6 100644 --- a/tests/components/homekit_controller/test_diagnostics.py +++ b/tests/components/homekit_controller/test_diagnostics.py @@ -519,9 +519,7 @@ async def test_device( "original_icon": None, "original_name": "Koogeek-LS1-20833F Identify", "state": { - "attributes": { - "friendly_name": "Koogeek-LS1-20833F " "Identify" - }, + "attributes": {"friendly_name": "Koogeek-LS1-20833F Identify"}, "entity_id": "button.koogeek_ls1_20833f_identify", "last_changed": ANY, "last_updated": ANY, diff --git a/tests/components/imap/const.py b/tests/components/imap/const.py index 5dcce782a41..e7fca106ff7 100644 --- a/tests/components/imap/const.py +++ b/tests/components/imap/const.py @@ -41,7 +41,7 @@ TEST_INVALID_DATE3 = ( TEST_MESSAGE_HEADERS1 + DATE_HEADER_INVALID3 + TEST_MESSAGE_HEADERS2 ) -TEST_CONTENT_TEXT_BARE = b"\r\n" b"Test body\r\n" b"\r\n" +TEST_CONTENT_TEXT_BARE = b"\r\nTest body\r\n\r\n" TEST_CONTENT_BINARY = ( b"Content-Type: application/binary\r\n" diff --git a/tests/components/knx/conftest.py b/tests/components/knx/conftest.py index 084a3a37c27..a06206fd982 100644 --- a/tests/components/knx/conftest.py +++ b/tests/components/knx/conftest.py @@ -140,11 +140,11 @@ class KNXTestKit: await self.hass.async_block_till_done() try: telegram = self._outgoing_telegrams.get_nowait() - except asyncio.QueueEmpty: + except asyncio.QueueEmpty as err: raise AssertionError( f"No Telegram found. Expected: {apci_type.__name__} -" f" {group_address} - {payload}" - ) + ) from err assert isinstance( telegram.payload, apci_type diff --git a/tests/components/logbook/test_init.py b/tests/components/logbook/test_init.py index c961d40574d..2a93e6e1d4c 100644 --- a/tests/components/logbook/test_init.py +++ b/tests/components/logbook/test_init.py @@ -2639,7 +2639,7 @@ async def test_get_events_with_device_ids( @ha.callback def async_describe_events( - hass: HomeAssistant, + hass: HomeAssistant, # noqa: N805 async_describe_event: Callable[ [str, str, Callable[[Event], dict[str, str]]], None ], diff --git a/tests/components/logbook/test_websocket_api.py b/tests/components/logbook/test_websocket_api.py index 9e991795083..c68cbedc44a 100644 --- a/tests/components/logbook/test_websocket_api.py +++ b/tests/components/logbook/test_websocket_api.py @@ -68,7 +68,7 @@ async def _async_mock_logbook_platform_with_broken_describe( @core.callback def async_describe_events( - hass: HomeAssistant, + hass: HomeAssistant, # noqa: N805 async_describe_event: Callable[ [str, str, Callable[[Event], dict[str, str]]], None ], @@ -91,7 +91,7 @@ async def _async_mock_logbook_platform(hass: HomeAssistant) -> None: @core.callback def async_describe_events( - hass: HomeAssistant, + hass: HomeAssistant, # noqa: N805 async_describe_event: Callable[ [str, str, Callable[[Event], dict[str, str]]], None ], diff --git a/tests/components/moat/__init__.py b/tests/components/moat/__init__.py index 358d338993f..e0af0229cba 100644 --- a/tests/components/moat/__init__.py +++ b/tests/components/moat/__init__.py @@ -19,7 +19,7 @@ MOAT_S2_SERVICE_INFO = BluetoothServiceInfo( service_data={ "00005000-0000-1000-8000-00805f9b34fb": b"\xdfy\xe3\xa6\x12\xb3\xf5\x0b", "00001000-0000-1000-8000-00805f9b34fb": ( - b"\xdfy\xe3\xa6\x12\xb3\x11S\xdbb\xfcbpq" b"\xf5\x0b\xff\xff" + b"\xdfy\xe3\xa6\x12\xb3\x11S\xdbb\xfcbpq\xf5\x0b\xff\xff" ), }, service_uuids=[ diff --git a/tests/components/motioneye/test_camera.py b/tests/components/motioneye/test_camera.py index 8cc64b8ff00..6972bee35d0 100644 --- a/tests/components/motioneye/test_camera.py +++ b/tests/components/motioneye/test_camera.py @@ -358,7 +358,7 @@ async def test_camera_option_stream_url_template( }, options={ CONF_STREAM_URL_TEMPLATE: ( - f"http://127.0.0.1:{stream_server.port}/" "{{ name }}/{{ id }}" + f"http://127.0.0.1:{stream_server.port}/{{{{ name }}}}/{{{{ id }}}}" ) }, ) diff --git a/tests/components/mqtt/test_binary_sensor.py b/tests/components/mqtt/test_binary_sensor.py index c98de3628b8..921f46703c2 100644 --- a/tests/components/mqtt/test_binary_sensor.py +++ b/tests/components/mqtt/test_binary_sensor.py @@ -984,8 +984,8 @@ async def test_discovery_broken( caplog: pytest.LogCaptureFixture, ) -> None: """Test handling of bad discovery message.""" - data1 = '{ "name": "Beer",' ' "off_delay": -1 }' - data2 = '{ "name": "Milk",' ' "state_topic": "test_topic" }' + data1 = '{ "name": "Beer", "off_delay": -1 }' + data2 = '{ "name": "Milk", "state_topic": "test_topic" }' await help_test_discovery_broken( hass, mqtt_mock_entry, diff --git a/tests/components/mqtt/test_legacy_vacuum.py b/tests/components/mqtt/test_legacy_vacuum.py index bf10a692b7c..0297f4216c4 100644 --- a/tests/components/mqtt/test_legacy_vacuum.py +++ b/tests/components/mqtt/test_legacy_vacuum.py @@ -769,8 +769,8 @@ async def test_discovery_broken( caplog: pytest.LogCaptureFixture, ) -> None: """Test handling of bad discovery message.""" - data1 = '{ "name": "Beer",' ' "command_topic": "test_topic#" }' - data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }' + data1 = '{ "name": "Beer", "command_topic": "test_topic#" }' + data2 = '{ "name": "Milk", "command_topic": "test_topic" }' await help_test_discovery_broken( hass, mqtt_mock_entry, caplog, vacuum.DOMAIN, data1, data2 ) diff --git a/tests/components/mqtt/test_light.py b/tests/components/mqtt/test_light.py index 884ff3bd2fd..ee4f170e8e6 100644 --- a/tests/components/mqtt/test_light.py +++ b/tests/components/mqtt/test_light.py @@ -2416,9 +2416,7 @@ async def test_discovery_ignores_extra_keys( """Test discovery ignores extra keys that are not blocked.""" await mqtt_mock_entry() # inserted `platform` key should be ignored - data = ( - '{ "name": "Beer",' ' "platform": "mqtt",' ' "command_topic": "test_topic"}' - ) + data = '{ "name": "Beer", "platform": "mqtt", "command_topic": "test_topic"}' async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data) await hass.async_block_till_done() state = hass.states.get("light.beer") diff --git a/tests/components/mqtt/test_light_template.py b/tests/components/mqtt/test_light_template.py index ba8414e252a..4727caca2cc 100644 --- a/tests/components/mqtt/test_light_template.py +++ b/tests/components/mqtt/test_light_template.py @@ -161,9 +161,9 @@ async def test_setup_fails( "command_topic": "test_light_rgb/set", "command_on_template": "on", "command_off_template": "off", - "red_template": '{{ value.split(",")[4].' 'split("-")[0] }}', - "green_template": '{{ value.split(",")[4].' 'split("-")[1] }}', - "blue_template": '{{ value.split(",")[4].' 'split("-")[2] }}', + "red_template": '{{ value.split(",")[4].split("-")[0] }}', + "green_template": '{{ value.split(",")[4].split("-")[1] }}', + "blue_template": '{{ value.split(",")[4].split("-")[2] }}', } } } @@ -416,9 +416,9 @@ async def test_state_brightness_color_effect_temp_change_via_topic( "optimistic": True, "state_template": '{{ value.split(",")[0] }}', "color_temp_template": '{{ value.split(",")[2] }}', - "red_template": '{{ value.split(",")[3].' 'split("-")[0] }}', - "green_template": '{{ value.split(",")[3].' 'split("-")[1] }}', - "blue_template": '{{ value.split(",")[3].' 'split("-")[2] }}', + "red_template": '{{ value.split(",")[3].split("-")[0] }}', + "green_template": '{{ value.split(",")[3].split("-")[1] }}', + "blue_template": '{{ value.split(",")[3].split("-")[2] }}', "effect_template": '{{ value.split(",")[4] }}', "qos": 2, } diff --git a/tests/components/mqtt/test_lock.py b/tests/components/mqtt/test_lock.py index 3c878a85f9e..2b77a573bad 100644 --- a/tests/components/mqtt/test_lock.py +++ b/tests/components/mqtt/test_lock.py @@ -796,7 +796,7 @@ async def test_discovery_removal_lock( caplog: pytest.LogCaptureFixture, ) -> None: """Test removal of discovered lock.""" - data = '{ "name": "test",' ' "command_topic": "test_topic" }' + data = '{ "name": "test", "command_topic": "test_topic" }' await help_test_discovery_removal(hass, mqtt_mock_entry, caplog, lock.DOMAIN, data) @@ -855,7 +855,7 @@ async def test_discovery_broken( ) -> None: """Test handling of bad discovery message.""" data1 = '{ "name": "Beer" }' - data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }' + data2 = '{ "name": "Milk", "command_topic": "test_topic" }' await help_test_discovery_broken( hass, mqtt_mock_entry, caplog, lock.DOMAIN, data1, data2 ) diff --git a/tests/components/mqtt/test_scene.py b/tests/components/mqtt/test_scene.py index 9c4b5b53be9..4da60d44bb7 100644 --- a/tests/components/mqtt/test_scene.py +++ b/tests/components/mqtt/test_scene.py @@ -180,7 +180,7 @@ async def test_discovery_removal_scene( caplog: pytest.LogCaptureFixture, ) -> None: """Test removal of discovered scene.""" - data = '{ "name": "test",' ' "command_topic": "test_topic" }' + data = '{ "name": "test", "command_topic": "test_topic" }' await help_test_discovery_removal(hass, mqtt_mock_entry, caplog, scene.DOMAIN, data) @@ -213,7 +213,7 @@ async def test_discovery_update_unchanged_scene( caplog: pytest.LogCaptureFixture, ) -> None: """Test update of discovered scene.""" - data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }' + data1 = '{ "name": "Beer", "command_topic": "test_topic" }' with patch( "homeassistant.components.mqtt.scene.MqttScene.discovery_update" ) as discovery_update: @@ -235,7 +235,7 @@ async def test_discovery_broken( ) -> None: """Test handling of bad discovery message.""" data1 = '{ "name": "Beer" }' - data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }' + data2 = '{ "name": "Milk", "command_topic": "test_topic" }' await help_test_discovery_broken( hass, mqtt_mock_entry, caplog, scene.DOMAIN, data1, data2 ) diff --git a/tests/components/onvif/test_diagnostics.py b/tests/components/onvif/test_diagnostics.py index eb7d058a755..f87a5f0eff6 100644 --- a/tests/components/onvif/test_diagnostics.py +++ b/tests/components/onvif/test_diagnostics.py @@ -82,12 +82,12 @@ async def test_diagnostics( }, "events": { "pullpoint_manager_state": { - "__type": "", - "repr": "", + "__type": "", + "repr": "", }, "webhook_manager_state": { "__type": "", - "repr": "", + "repr": "", }, }, } diff --git a/tests/components/tomato/test_device_tracker.py b/tests/components/tomato/test_device_tracker.py index c23ee28ac7c..7c187c7b4bb 100644 --- a/tests/components/tomato/test_device_tracker.py +++ b/tests/components/tomato/test_device_tracker.py @@ -381,7 +381,7 @@ def test_bad_connection(hass: HomeAssistant, mock_exception_logger) -> None: "POST", "http://tomato-router:80/update.cgi", exc=requests.exceptions.ConnectionError, - ), + ) tomato.get_scanner(hass, config) assert mock_exception_logger.call_count == 1 assert mock_exception_logger.mock_calls[0] == mock.call( @@ -409,7 +409,7 @@ def test_router_timeout(hass: HomeAssistant, mock_exception_logger) -> None: "POST", "http://tomato-router:80/update.cgi", exc=requests.exceptions.Timeout, - ), + ) tomato.get_scanner(hass, config) assert mock_exception_logger.call_count == 1 assert mock_exception_logger.mock_calls[0] == mock.call( diff --git a/tests/components/xiaomi_ble/test_binary_sensor.py b/tests/components/xiaomi_ble/test_binary_sensor.py index 235be5c6cd8..424f6e22b26 100644 --- a/tests/components/xiaomi_ble/test_binary_sensor.py +++ b/tests/components/xiaomi_ble/test_binary_sensor.py @@ -247,7 +247,7 @@ async def test_smoke(hass: HomeAssistant) -> None: hass, make_advertisement( "54:EF:44:E3:9C:BC", - b"XY\x97\tf\xbc\x9c\xe3D\xefT\x01" b"\x08\x12\x05\x00\x00\x00q^\xbe\x90", + b"XY\x97\tf\xbc\x9c\xe3D\xefT\x01\x08\x12\x05\x00\x00\x00q^\xbe\x90", ), ) await hass.async_block_till_done() diff --git a/tests/components/zha/test_select.py b/tests/components/zha/test_select.py index 4a9d54c9063..d2d1b79c92f 100644 --- a/tests/components/zha/test_select.py +++ b/tests/components/zha/test_select.py @@ -116,7 +116,6 @@ def core_rs(hass_storage): } ], } - return return _storage diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index e29447a8688..519481569a5 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -1388,7 +1388,7 @@ def test_whitespace() -> None: for value in ( None, - "" "T", + "T", "negative", "lock", "tr ue", diff --git a/tests/helpers/test_ratelimit.py b/tests/helpers/test_ratelimit.py index e7fa639261b..39e83953c45 100644 --- a/tests/helpers/test_ratelimit.py +++ b/tests/helpers/test_ratelimit.py @@ -16,7 +16,6 @@ async def test_hit(hass: HomeAssistant) -> None: def _refresh(): nonlocal refresh_called refresh_called = True - return rate_limiter = ratelimit.KeyedRateLimit(hass) rate_limiter.async_triggered("key1", dt_util.utcnow()) @@ -53,7 +52,6 @@ async def test_miss(hass: HomeAssistant) -> None: def _refresh(): nonlocal refresh_called refresh_called = True - return rate_limiter = ratelimit.KeyedRateLimit(hass) assert ( @@ -85,7 +83,6 @@ async def test_no_limit(hass: HomeAssistant) -> None: def _refresh(): nonlocal refresh_called refresh_called = True - return rate_limiter = ratelimit.KeyedRateLimit(hass) rate_limiter.async_triggered("key1", dt_util.utcnow()) diff --git a/tests/ruff.toml b/tests/ruff.toml index 73246163d2f..05971ce9a08 100644 --- a/tests/ruff.toml +++ b/tests/ruff.toml @@ -12,6 +12,14 @@ extend-select = [ "PT022", # No teardown in fixture, replace useless yield with return ] +extend-ignore = [ + "PLC", # pylint + "PLE", # pylint + "PLR", # pylint + "PLW", # pylint + "N815", # Variable {name} in class scope should not be mixedCase +] + [isort] known-first-party = [ "homeassistant",