Move overlapping pylint rules to ruff, disable mypy overlap (#94359)

pull/95393/head
Franck Nijhof 2023-06-27 17:42:46 +02:00 committed by GitHub
parent 7c676c0a7d
commit 3e85a29b86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 537 additions and 357 deletions

View File

@ -296,7 +296,6 @@ class ADBDevice(MediaPlayerEntity):
self._process_config,
)
)
return
@property
def media_image_hash(self) -> str | None:

View File

@ -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

View File

@ -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]

View File

@ -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):

View File

@ -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."""

View File

@ -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] = []

View File

@ -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

View File

@ -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:

View File

@ -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 = (

View File

@ -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."""

View File

@ -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):

View File

@ -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):

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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__)

View File

@ -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

View File

@ -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 {}

View File

@ -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:

View File

@ -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,

View File

@ -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)

View File

@ -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."""

View File

@ -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

View File

@ -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

View File

@ -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}",

View File

@ -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 = [

View File

@ -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(

View File

@ -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

View File

@ -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)

View File

@ -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"
)

View File

@ -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]

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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."""

View File

@ -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(

View File

@ -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

View File

@ -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)

View File

@ -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"]
)
}

View File

@ -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(

View File

@ -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."""

View File

@ -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."

View File

@ -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):

View File

@ -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."""

View File

@ -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.

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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: <https://github.com/astral-sh/ruff/issues/970>
"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: <https://github.com/antonagestam/pylint-mypy-overlap>
"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]

View File

@ -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

View File

@ -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:

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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(

View File

@ -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",

View File

@ -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,

View File

@ -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"

View File

@ -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

View File

@ -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
],

View File

@ -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
],

View File

@ -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=[

View File

@ -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 }}}}"
)
},
)

View File

@ -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,

View File

@ -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
)

View File

@ -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")

View File

@ -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,
}

View File

@ -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
)

View File

@ -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
)

View File

@ -82,12 +82,12 @@ async def test_diagnostics(
},
"events": {
"pullpoint_manager_state": {
"__type": "<enum " "'PullPointManagerState'>",
"repr": "<PullPointManagerState.PAUSED: " "2>",
"__type": "<enum 'PullPointManagerState'>",
"repr": "<PullPointManagerState.PAUSED: 2>",
},
"webhook_manager_state": {
"__type": "<enum 'WebHookManagerState'>",
"repr": "<WebHookManagerState.STARTED: " "1>",
"repr": "<WebHookManagerState.STARTED: 1>",
},
},
}

View File

@ -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(

View File

@ -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()

View File

@ -116,7 +116,6 @@ def core_rs(hass_storage):
}
],
}
return
return _storage

View File

@ -1388,7 +1388,7 @@ def test_whitespace() -> None:
for value in (
None,
"" "T",
"T",
"negative",
"lock",
"tr ue",

View File

@ -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())

View File

@ -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",