Enable RUF021 (#135832)

pull/135835/head
Joost Lekkerkerker 2025-01-17 10:20:45 +01:00 committed by GitHub
parent 85b4be2f16
commit b4f4b06f29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
52 changed files with 166 additions and 218 deletions

View File

@ -474,25 +474,30 @@ class ClimateCapabilities(AlexaEntity):
# If we support two modes, one being off, we allow turning on too. # If we support two modes, one being off, we allow turning on too.
supported_features = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) supported_features = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if ( if (
self.entity.domain == climate.DOMAIN (
and climate.HVACMode.OFF self.entity.domain == climate.DOMAIN
in (self.entity.attributes.get(climate.ATTR_HVAC_MODES) or []) and climate.HVACMode.OFF
or self.entity.domain == climate.DOMAIN in (self.entity.attributes.get(climate.ATTR_HVAC_MODES) or [])
and ( )
supported_features or (
& ( self.entity.domain == climate.DOMAIN
climate.ClimateEntityFeature.TURN_ON and (
| climate.ClimateEntityFeature.TURN_OFF supported_features
& (
climate.ClimateEntityFeature.TURN_ON
| climate.ClimateEntityFeature.TURN_OFF
)
) )
) )
or self.entity.domain == water_heater.DOMAIN or (
and (supported_features & water_heater.WaterHeaterEntityFeature.ON_OFF) self.entity.domain == water_heater.DOMAIN
and (supported_features & water_heater.WaterHeaterEntityFeature.ON_OFF)
)
): ):
yield AlexaPowerController(self.entity) yield AlexaPowerController(self.entity)
if ( if self.entity.domain == climate.DOMAIN or (
self.entity.domain == climate.DOMAIN self.entity.domain == water_heater.DOMAIN
or self.entity.domain == water_heater.DOMAIN
and ( and (
supported_features supported_features
& water_heater.WaterHeaterEntityFeature.OPERATION_MODE & water_heater.WaterHeaterEntityFeature.OPERATION_MODE

View File

@ -317,9 +317,8 @@ async def async_enable_proactive_mode(
if should_doorbell: if should_doorbell:
old_state = data["old_state"] old_state = data["old_state"]
if ( if new_state.domain == event.DOMAIN or (
new_state.domain == event.DOMAIN new_state.state == STATE_ON
or new_state.state == STATE_ON
and (old_state is None or old_state.state != STATE_ON) and (old_state is None or old_state.state != STATE_ON)
): ):
await async_send_doorbell_event_message( await async_send_doorbell_event_message(

View File

@ -115,11 +115,8 @@ class BondEntity(Entity):
def _async_update_if_bpup_not_alive(self, now: datetime) -> None: def _async_update_if_bpup_not_alive(self, now: datetime) -> None:
"""Fetch via the API if BPUP is not alive.""" """Fetch via the API if BPUP is not alive."""
self._async_schedule_bpup_alive_or_poll() self._async_schedule_bpup_alive_or_poll()
if ( if self.hass.is_stopping or (
self.hass.is_stopping self._bpup_subs.alive and self._initialized and self.available
or self._bpup_subs.alive
and self._initialized
and self.available
): ):
return return
if self._update_lock.locked(): if self._update_lock.locked():

View File

@ -26,7 +26,7 @@ def async_describe_events(
"""Describe bthome logbook event.""" """Describe bthome logbook event."""
data = event.data data = event.data
device = dev_reg.async_get(data["device_id"]) device = dev_reg.async_get(data["device_id"])
name = device and device.name or f"BTHome {data['address']}" name = (device and device.name) or f"BTHome {data['address']}"
if properties := data["event_properties"]: if properties := data["event_properties"]:
message = f"{data['event_class']} {data['event_type']}: {properties}" message = f"{data['event_class']} {data['event_type']}: {properties}"
else: else:

View File

@ -186,12 +186,12 @@ class CalDavUpdateCoordinator(DataUpdateCoordinator[CalendarEvent | None]):
pattern = re.compile(search) pattern = re.compile(search)
return ( return (
hasattr(vevent, "summary") (hasattr(vevent, "summary") and pattern.match(vevent.summary.value))
and pattern.match(vevent.summary.value) or (hasattr(vevent, "location") and pattern.match(vevent.location.value))
or hasattr(vevent, "location") or (
and pattern.match(vevent.location.value) hasattr(vevent, "description")
or hasattr(vevent, "description") and pattern.match(vevent.description.value)
and pattern.match(vevent.description.value) )
) )
@staticmethod @staticmethod

View File

@ -101,7 +101,8 @@ async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> Non
if ( if (
"xe" in entity.unique_id "xe" in entity.unique_id
and currency not in config_entry.options.get(CONF_EXCHANGE_RATES, []) and currency not in config_entry.options.get(CONF_EXCHANGE_RATES, [])
or "wallet" in entity.unique_id ) or (
"wallet" in entity.unique_id
and currency not in config_entry.options.get(CONF_CURRENCIES, []) and currency not in config_entry.options.get(CONF_CURRENCIES, [])
): ):
registry.async_remove(entity.entity_id) registry.async_remove(entity.entity_id)

View File

@ -279,9 +279,8 @@ def websocket_update_entity(
result: dict[str, Any] = {"entity_entry": entity_entry.extended_dict} result: dict[str, Any] = {"entity_entry": entity_entry.extended_dict}
if "disabled_by" in changes and changes["disabled_by"] is None: if "disabled_by" in changes and changes["disabled_by"] is None:
# Enabling an entity requires a config entry reload, or HA restart # Enabling an entity requires a config entry reload, or HA restart
if ( if not (config_entry_id := entity_entry.config_entry_id) or (
not (config_entry_id := entity_entry.config_entry_id) (config_entry := hass.config_entries.async_get_entry(config_entry_id))
or (config_entry := hass.config_entries.async_get_entry(config_entry_id))
and not config_entry.supports_unload and not config_entry.supports_unload
): ):
result["require_restart"] = True result["require_restart"] = True

View File

@ -362,12 +362,11 @@ class EnergyCostSensor(SensorEntity):
return return
if ( if (
( state_class != SensorStateClass.TOTAL_INCREASING
state_class != SensorStateClass.TOTAL_INCREASING and energy_state.attributes.get(ATTR_LAST_RESET)
and energy_state.attributes.get(ATTR_LAST_RESET) != self._last_energy_sensor_state.attributes.get(ATTR_LAST_RESET)
!= self._last_energy_sensor_state.attributes.get(ATTR_LAST_RESET) ) or (
) state_class == SensorStateClass.TOTAL_INCREASING
or state_class == SensorStateClass.TOTAL_INCREASING
and reset_detected( and reset_detected(
self.hass, self.hass,
cast(str, self._config[self._adapter.stat_energy_key]), cast(str, self._config[self._adapter.stat_energy_key]),

View File

@ -83,13 +83,8 @@ async def async_attach_trigger(
) )
to_match = condition.zone(hass, zone_state, to_state) if to_state else False to_match = condition.zone(hass, zone_state, to_state) if to_state else False
if ( if (trigger_event == EVENT_ENTER and not from_match and to_match) or (
trigger_event == EVENT_ENTER trigger_event == EVENT_LEAVE and from_match and not to_match
and not from_match
and to_match
or trigger_event == EVENT_LEAVE
and from_match
and not to_match
): ):
hass.async_run_hass_job( hass.async_run_hass_job(
job, job,

View File

@ -375,6 +375,8 @@ class GlancesSensor(CoordinatorEntity[GlancesDataUpdateCoordinator], SensorEntit
self._data_valid = self._attr_native_value is not None and ( self._data_valid = self._attr_native_value is not None and (
not self._numeric_state_expected not self._numeric_state_expected
or isinstance(self._attr_native_value, (int, float)) or isinstance(self._attr_native_value, (int, float))
or isinstance(self._attr_native_value, str) or (
and self._attr_native_value.isnumeric() isinstance(self._attr_native_value, str)
and self._attr_native_value.isnumeric()
)
) )

View File

@ -49,10 +49,8 @@ class AsyncConfigEntryAuth:
"OAuth session is not valid, reauth required" "OAuth session is not valid, reauth required"
) from ex ) from ex
raise ConfigEntryNotReady from ex raise ConfigEntryNotReady from ex
if ( if isinstance(ex, RefreshError) or (
isinstance(ex, RefreshError) hasattr(ex, "status") and ex.status == 400
or hasattr(ex, "status")
and ex.status == 400
): ):
self.oauth_session.config_entry.async_start_reauth( self.oauth_session.config_entry.async_start_reauth(
self.oauth_session.hass self.oauth_session.hass

View File

@ -440,10 +440,8 @@ class Group(Entity):
if not self._on_off: if not self._on_off:
return return
if ( if tr_state is None or (
tr_state is None self._assumed_state and not tr_state.attributes.get(ATTR_ASSUMED_STATE)
or self._assumed_state
and not tr_state.attributes.get(ATTR_ASSUMED_STATE)
): ):
self._assumed_state = self.mode(self._assumed.values()) self._assumed_state = self.mode(self._assumed.values())

View File

@ -111,10 +111,12 @@ class HistoryPeriodView(HomeAssistantView):
# end_time. If it's false, we know there are no states in the # end_time. If it's false, we know there are no states in the
# database up until end_time. # database up until end_time.
(end_time and not has_states_before(hass, end_time)) (end_time and not has_states_before(hass, end_time))
or not include_start_time_state or (
and entity_ids not include_start_time_state
and not entities_may_have_state_changes_after( and entity_ids
hass, entity_ids, start_time, no_attributes and not entities_may_have_state_changes_after(
hass, entity_ids, start_time, no_attributes
)
) )
): ):
return self.json([]) return self.json([])

View File

@ -146,10 +146,12 @@ async def ws_get_history_during_period(
# end_time. If it's false, we know there are no states in the # end_time. If it's false, we know there are no states in the
# database up until end_time. # database up until end_time.
(end_time and not has_states_before(hass, end_time)) (end_time and not has_states_before(hass, end_time))
or not include_start_time_state or (
and entity_ids not include_start_time_state
and not entities_may_have_state_changes_after( and entity_ids
hass, entity_ids, start_time, no_attributes and not entities_may_have_state_changes_after(
hass, entity_ids, start_time, no_attributes
)
) )
): ):
connection.send_result(msg["id"], {}) connection.send_result(msg["id"], {})

View File

@ -409,11 +409,8 @@ class WindowCoveringBasic(OpeningDeviceBase, HomeAccessory):
"""Move cover to value if call came from HomeKit.""" """Move cover to value if call came from HomeKit."""
_LOGGER.debug("%s: Set position to %d", self.entity_id, value) _LOGGER.debug("%s: Set position to %d", self.entity_id, value)
if ( if (self._supports_stop and value > 70) or (
self._supports_stop not self._supports_stop and value >= 50
and value > 70
or not self._supports_stop
and value >= 50
): ):
service, position = (SERVICE_OPEN_COVER, 100) service, position = (SERVICE_OPEN_COVER, 100)
elif value < 30 or not self._supports_stop: elif value < 30 or not self._supports_stop:

View File

@ -643,7 +643,8 @@ def state_needs_accessory_mode(state: State) -> bool:
state.domain == MEDIA_PLAYER_DOMAIN state.domain == MEDIA_PLAYER_DOMAIN
and state.attributes.get(ATTR_DEVICE_CLASS) and state.attributes.get(ATTR_DEVICE_CLASS)
in (MediaPlayerDeviceClass.TV, MediaPlayerDeviceClass.RECEIVER) in (MediaPlayerDeviceClass.TV, MediaPlayerDeviceClass.RECEIVER)
or state.domain == REMOTE_DOMAIN ) or (
state.domain == REMOTE_DOMAIN
and state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) and state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
& RemoteEntityFeature.ACTIVITY & RemoteEntityFeature.ACTIVITY
) )

View File

@ -160,10 +160,8 @@ class LidarrSensor(LidarrEntity[T], SensorEntity):
def queue_str(item: LidarrQueueItem) -> str: def queue_str(item: LidarrQueueItem) -> str:
"""Return string description of queue item.""" """Return string description of queue item."""
if ( if (item.sizeleft > 0 and item.timeleft == "00:00:00") or not hasattr(
item.sizeleft > 0 item, "trackedDownloadState"
and item.timeleft == "00:00:00"
or not hasattr(item, "trackedDownloadState")
): ):
return "stopped" return "stopped"
return item.trackedDownloadState return item.trackedDownloadState

View File

@ -126,9 +126,7 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
HTTPStatus.UNAUTHORIZED, HTTPStatus.UNAUTHORIZED,
HTTPStatus.FORBIDDEN, HTTPStatus.FORBIDDEN,
) )
or isinstance(err, AttributeError) ) or (isinstance(err, AttributeError) and err.name == "get"):
and err.name == "get"
):
errors["base"] = "invalid_auth" errors["base"] = "invalid_auth"
else: else:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
@ -165,9 +163,7 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
HTTPStatus.UNAUTHORIZED, HTTPStatus.UNAUTHORIZED,
HTTPStatus.FORBIDDEN, HTTPStatus.FORBIDDEN,
) )
or isinstance(err, AttributeError) ) or (isinstance(err, AttributeError) and err.name == "get"):
and err.name == "get"
):
errors["base"] = "invalid_auth" errors["base"] = "invalid_auth"
else: else:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"

View File

@ -768,11 +768,8 @@ async def async_get_broker_settings(
validated_user_input.update(user_input) validated_user_input.update(user_input)
client_certificate_id: str | None = user_input.get(CONF_CLIENT_CERT) client_certificate_id: str | None = user_input.get(CONF_CLIENT_CERT)
client_key_id: str | None = user_input.get(CONF_CLIENT_KEY) client_key_id: str | None = user_input.get(CONF_CLIENT_KEY)
if ( if (client_certificate_id and not client_key_id) or (
client_certificate_id not client_certificate_id and client_key_id
and not client_key_id
or not client_certificate_id
and client_key_id
): ):
errors["base"] = "invalid_inclusion" errors["base"] = "invalid_inclusion"
return False return False
@ -782,14 +779,20 @@ async def async_get_broker_settings(
# Return to form for file upload CA cert or client cert and key # Return to form for file upload CA cert or client cert and key
if ( if (
not client_certificate (
and user_input.get(SET_CLIENT_CERT) not client_certificate
and not client_certificate_id and user_input.get(SET_CLIENT_CERT)
or not certificate and not client_certificate_id
and user_input.get(SET_CA_CERT, "off") == "custom" )
and not certificate_id or (
or user_input.get(CONF_TRANSPORT) == TRANSPORT_WEBSOCKETS not certificate
and CONF_WS_PATH not in user_input and user_input.get(SET_CA_CERT, "off") == "custom"
and not certificate_id
)
or (
user_input.get(CONF_TRANSPORT) == TRANSPORT_WEBSOCKETS
and CONF_WS_PATH not in user_input
)
): ):
return False return False

View File

@ -26,10 +26,8 @@ def find_matching_platform(
if len(device_point.enum_values) > 0 and device_point.writable: if len(device_point.enum_values) > 0 and device_point.writable:
return Platform.SELECT return Platform.SELECT
if ( if (description and description.native_unit_of_measurement == "DM") or (
description device_point.raw["maxValue"] and device_point.raw["minValue"]
and description.native_unit_of_measurement == "DM"
or (device_point.raw["maxValue"] and device_point.raw["minValue"])
): ):
if device_point.writable: if device_point.writable:
return Platform.NUMBER return Platform.NUMBER

View File

@ -257,7 +257,6 @@ async def async_remove_config_entry_device(
return not any( return not any(
identifier identifier
for identifier in device_entry.identifiers for identifier in device_entry.identifiers
if identifier[0] == DOMAIN if (identifier[0] == DOMAIN and identifier[1] in modules)
and identifier[1] in modules
or identifier[1] in rooms or identifier[1] in rooms
) )

View File

@ -80,7 +80,7 @@ class OctoprintDataUpdateCoordinator(DataUpdateCoordinator):
"""Device info.""" """Device info."""
unique_id = cast(str, self.config_entry.unique_id) unique_id = cast(str, self.config_entry.unique_id)
configuration_url = URL.build( configuration_url = URL.build(
scheme=self.config_entry.data[CONF_SSL] and "https" or "http", scheme=(self.config_entry.data[CONF_SSL] and "https") or "http",
host=self.config_entry.data[CONF_HOST], host=self.config_entry.data[CONF_HOST],
port=self.config_entry.data[CONF_PORT], port=self.config_entry.data[CONF_PORT],
path=self.config_entry.data[CONF_PATH], path=self.config_entry.data[CONF_PATH],

View File

@ -534,8 +534,7 @@ class OverkizStateSensor(OverkizDescriptiveEntity, SensorEntity):
# This is probably incorrect and should be fixed in a follow up PR. # This is probably incorrect and should be fixed in a follow up PR.
# To ensure measurement sensors do not get an `unknown` state on # To ensure measurement sensors do not get an `unknown` state on
# a falsy value (e.g. 0 or 0.0) we also check the state_class. # a falsy value (e.g. 0 or 0.0) we also check the state_class.
or self.state_class != SensorStateClass.MEASUREMENT or (self.state_class != SensorStateClass.MEASUREMENT and not state.value)
and not state.value
): ):
return None return None

View File

@ -64,10 +64,8 @@ class DomesticHotWaterProduction(OverkizEntity, WaterHeaterEntity):
for param, mode in OVERKIZ_TO_OPERATION_MODE.items(): for param, mode in OVERKIZ_TO_OPERATION_MODE.items():
# Filter only for mode allowed by this device # Filter only for mode allowed by this device
# or allow all if no mode definition found # or allow all if no mode definition found
if ( if not state_mode_definition or (
not state_mode_definition state_mode_definition.values and param in state_mode_definition.values
or state_mode_definition.values
and param in state_mode_definition.values
): ):
self.operation_mode_to_overkiz[mode] = param self.operation_mode_to_overkiz[mode] = param
self._attr_operation_list.append(param) self._attr_operation_list.append(param)

View File

@ -239,20 +239,13 @@ def execute(
if name.startswith("async_"): if name.startswith("async_"):
raise ScriptError("Not allowed to access async methods") raise ScriptError("Not allowed to access async methods")
if ( if (
obj is hass (obj is hass and name not in ALLOWED_HASS)
and name not in ALLOWED_HASS or (obj is hass.bus and name not in ALLOWED_EVENTBUS)
or obj is hass.bus or (obj is hass.states and name not in ALLOWED_STATEMACHINE)
and name not in ALLOWED_EVENTBUS or (obj is hass.services and name not in ALLOWED_SERVICEREGISTRY)
or obj is hass.states or (obj is dt_util and name not in ALLOWED_DT_UTIL)
and name not in ALLOWED_STATEMACHINE or (obj is datetime and name not in ALLOWED_DATETIME)
or obj is hass.services or (isinstance(obj, TimeWrapper) and name not in ALLOWED_TIME)
and name not in ALLOWED_SERVICEREGISTRY
or obj is dt_util
and name not in ALLOWED_DT_UTIL
or obj is datetime
and name not in ALLOWED_DATETIME
or isinstance(obj, TimeWrapper)
and name not in ALLOWED_TIME
): ):
raise ScriptError(f"Not allowed to access {obj.__class__.__name__}.{name}") raise ScriptError(f"Not allowed to access {obj.__class__.__name__}.{name}")

View File

@ -35,8 +35,7 @@ def supported(event: rfxtrxmod.RFXtrxEvent) -> bool:
isinstance(event.device, rfxtrxmod.LightingDevice) isinstance(event.device, rfxtrxmod.LightingDevice)
and not event.device.known_to_be_dimmable and not event.device.known_to_be_dimmable
and not event.device.known_to_be_rollershutter and not event.device.known_to_be_rollershutter
or isinstance(event.device, rfxtrxmod.RfyDevice) ) or isinstance(event.device, rfxtrxmod.RfyDevice)
)
async def async_setup_entry( async def async_setup_entry(

View File

@ -271,11 +271,9 @@ class RMVDepartureData:
if not dest_found: if not dest_found:
continue continue
if ( if (self._lines and journey["number"] not in self._lines) or journey[
self._lines "minutes"
and journey["number"] not in self._lines ] < self._time_offset:
or journey["minutes"] < self._time_offset
):
continue continue
for attr in ("direction", "departure_time", "product", "minutes"): for attr in ("direction", "departure_time", "product", "minutes"):

View File

@ -120,9 +120,8 @@ def async_setup_block_entry(
relay_blocks = [] relay_blocks = []
assert coordinator.device.blocks assert coordinator.device.blocks
for block in coordinator.device.blocks: for block in coordinator.device.blocks:
if ( if block.type != "relay" or (
block.type != "relay" block.channel is not None
or block.channel is not None
and is_block_channel_type_light( and is_block_channel_type_light(
coordinator.device.settings, int(block.channel) coordinator.device.settings, int(block.channel)
) )

View File

@ -68,10 +68,8 @@ def process_turn_on_params(
isinstance(siren.available_tones, dict) isinstance(siren.available_tones, dict)
and tone in siren.available_tones.values() and tone in siren.available_tones.values()
) )
if ( if not siren.available_tones or (
not siren.available_tones tone not in siren.available_tones and not is_tone_dict_value
or tone not in siren.available_tones
and not is_tone_dict_value
): ):
raise ValueError( raise ValueError(
f"Invalid tone specified for entity {siren.entity_id}: {tone}, " f"Invalid tone specified for entity {siren.entity_id}: {tone}, "

View File

@ -172,7 +172,7 @@ class SnmpScanner(DeviceScanner):
_LOGGER.error( _LOGGER.error(
"SNMP error: %s at %s", "SNMP error: %s at %s",
errstatus.prettyPrint(), errstatus.prettyPrint(),
errindex and res[int(errindex) - 1][0] or "?", (errindex and res[int(errindex) - 1][0]) or "?",
) )
return None return None

View File

@ -264,7 +264,7 @@ class SnmpSwitch(SwitchEntity):
_LOGGER.error( _LOGGER.error(
"SNMP error: %s at %s", "SNMP error: %s at %s",
errstatus.prettyPrint(), errstatus.prettyPrint(),
errindex and restable[-1][int(errindex) - 1] or "?", (errindex and restable[-1][int(errindex) - 1]) or "?",
) )
else: else:
for resrow in restable: for resrow in restable:

View File

@ -105,9 +105,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: SqueezeboxConfigEntry) -
lms.name = ( lms.name = (
(STATUS_QUERY_LIBRARYNAME in status and status[STATUS_QUERY_LIBRARYNAME]) (STATUS_QUERY_LIBRARYNAME in status and status[STATUS_QUERY_LIBRARYNAME])
and status[STATUS_QUERY_LIBRARYNAME] and status[STATUS_QUERY_LIBRARYNAME]
or host ) or host
) version = (STATUS_QUERY_VERSION in status and status[STATUS_QUERY_VERSION]) or None
version = STATUS_QUERY_VERSION in status and status[STATUS_QUERY_VERSION] or None
# mac can be missing # mac can be missing
mac_connect = ( mac_connect = (
{(CONNECTION_NETWORK_MAC, format_mac(status[STATUS_QUERY_MAC]))} {(CONNECTION_NETWORK_MAC, format_mac(status[STATUS_QUERY_MAC]))}

View File

@ -273,7 +273,7 @@ async def async_build_source_set(hass: HomeAssistant) -> set[IPv4Address | IPv6A
for source_ip in await network.async_get_enabled_source_ips(hass) for source_ip in await network.async_get_enabled_source_ips(hass)
if not source_ip.is_loopback if not source_ip.is_loopback
and not source_ip.is_global and not source_ip.is_global
and (source_ip.version == 6 and source_ip.scope_id or source_ip.version == 4) and ((source_ip.version == 6 and source_ip.scope_id) or source_ip.version == 4)
} }

View File

@ -1052,10 +1052,8 @@ class TextToSpeechUrlView(HomeAssistantView):
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON specified", HTTPStatus.BAD_REQUEST) return self.json_message("Invalid JSON specified", HTTPStatus.BAD_REQUEST)
if ( if (not data.get("engine_id") and not data.get(ATTR_PLATFORM)) or not data.get(
not data.get("engine_id") ATTR_MESSAGE
and not data.get(ATTR_PLATFORM)
or not data.get(ATTR_MESSAGE)
): ):
return self.json_message( return self.json_message(
"Must specify platform and message", HTTPStatus.BAD_REQUEST "Must specify platform and message", HTTPStatus.BAD_REQUEST

View File

@ -89,9 +89,8 @@ class TuyaVacuumEntity(TuyaEntity, StateVacuumEntity):
if self.find_dpcode(DPCode.PAUSE, prefer_function=True): if self.find_dpcode(DPCode.PAUSE, prefer_function=True):
self._attr_supported_features |= VacuumEntityFeature.PAUSE self._attr_supported_features |= VacuumEntityFeature.PAUSE
if ( if self.find_dpcode(DPCode.SWITCH_CHARGE, prefer_function=True) or (
self.find_dpcode(DPCode.SWITCH_CHARGE, prefer_function=True) (
or (
enum_type := self.find_dpcode( enum_type := self.find_dpcode(
DPCode.MODE, dptype=DPType.ENUM, prefer_function=True DPCode.MODE, dptype=DPType.ENUM, prefer_function=True
) )

View File

@ -69,8 +69,7 @@ async def async_reconnect_client(hass: HomeAssistant, data: Mapping[str, Any]) -
for config_entry in hass.config_entries.async_entries(UNIFI_DOMAIN): for config_entry in hass.config_entries.async_entries(UNIFI_DOMAIN):
if config_entry.state is not ConfigEntryState.LOADED or ( if config_entry.state is not ConfigEntryState.LOADED or (
(hub := config_entry.runtime_data) ((hub := config_entry.runtime_data) and not hub.available)
and not hub.available
or (client := hub.api.clients.get(mac)) is None or (client := hub.api.clients.get(mac)) is None
or client.is_wired or client.is_wired
): ):
@ -87,10 +86,8 @@ async def async_remove_clients(hass: HomeAssistant, data: Mapping[str, Any]) ->
- Neither IP, hostname nor name is configured. - Neither IP, hostname nor name is configured.
""" """
for config_entry in hass.config_entries.async_entries(UNIFI_DOMAIN): for config_entry in hass.config_entries.async_entries(UNIFI_DOMAIN):
if ( if config_entry.state is not ConfigEntryState.LOADED or (
config_entry.state is not ConfigEntryState.LOADED (hub := config_entry.runtime_data) and not hub.available
or (hub := config_entry.runtime_data)
and not hub.available
): ):
continue continue

View File

@ -291,9 +291,8 @@ class WasherDryerTimeClass(RestoreSensor):
seconds=int(self._wd.get_attribute("Cavity_TimeStatusEstTimeRemaining")) seconds=int(self._wd.get_attribute("Cavity_TimeStatusEstTimeRemaining"))
) )
if ( if self._attr_native_value is None or (
self._attr_native_value is None isinstance(self._attr_native_value, datetime)
or isinstance(self._attr_native_value, datetime)
and abs(new_timestamp - self._attr_native_value) > timedelta(seconds=60) and abs(new_timestamp - self._attr_native_value) > timedelta(seconds=60)
): ):
self._attr_native_value = new_timestamp self._attr_native_value = new_timestamp

View File

@ -85,11 +85,8 @@ async def async_attach_trigger(
from_s = zone_event.data["old_state"] from_s = zone_event.data["old_state"]
to_s = zone_event.data["new_state"] to_s = zone_event.data["new_state"]
if ( if (from_s and not location.has_location(from_s)) or (
from_s to_s and not location.has_location(to_s)
and not location.has_location(from_s)
or to_s
and not location.has_location(to_s)
): ):
return return
@ -107,13 +104,8 @@ async def async_attach_trigger(
from_match = condition.zone(hass, zone_state, from_s) if from_s else False from_match = condition.zone(hass, zone_state, from_s) if from_s else False
to_match = condition.zone(hass, zone_state, to_s) if to_s else False to_match = condition.zone(hass, zone_state, to_s) if to_s else False
if ( if (event == EVENT_ENTER and not from_match and to_match) or (
event == EVENT_ENTER event == EVENT_LEAVE and from_match and not to_match
and not from_match
and to_match
or event == EVENT_LEAVE
and from_match
and not to_match
): ):
description = f"{entity} {_EVENT_DESCRIPTION[event]} {zone_state.attributes[ATTR_FRIENDLY_NAME]}" description = f"{entity} {_EVENT_DESCRIPTION[event]} {zone_state.attributes[ATTR_FRIENDLY_NAME]}"
hass.async_run_hass_job( hass.async_run_hass_job(

View File

@ -458,7 +458,7 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
if warm_white and cool_white: if warm_white and cool_white:
self._supports_color_temp = True self._supports_color_temp = True
# only one white channel (warm white or cool white) = rgbw support # only one white channel (warm white or cool white) = rgbw support
elif red and green and blue and warm_white or cool_white: elif (red and green and blue and warm_white) or cool_white:
self._supports_rgbw = True self._supports_rgbw = True
@callback @callback

View File

@ -884,10 +884,8 @@ def time(
condition_trace_update_result(weekday=weekday, now_weekday=now_weekday) condition_trace_update_result(weekday=weekday, now_weekday=now_weekday)
if ( if (
isinstance(weekday, str) isinstance(weekday, str) and weekday != now_weekday
and weekday != now_weekday ) or now_weekday not in weekday:
or now_weekday not in weekday
):
return False return False
return True return True

View File

@ -951,8 +951,7 @@ def async_track_template(
if ( if (
not isinstance(last_result, TemplateError) not isinstance(last_result, TemplateError)
and result_as_boolean(last_result) and result_as_boolean(last_result)
or not result_as_boolean(result) ) or not result_as_boolean(result):
):
return return
hass.async_run_hass_job( hass.async_run_hass_job(

View File

@ -756,10 +756,8 @@ class _ScriptRun:
) )
running_script = ( running_script = (
params[CONF_DOMAIN] == "automation" params[CONF_DOMAIN] == "automation" and params[CONF_SERVICE] == "trigger"
and params[CONF_SERVICE] == "trigger" ) or params[CONF_DOMAIN] in ("python_script", "script")
or params[CONF_DOMAIN] in ("python_script", "script")
)
trace_set_result(params=params, running_script=running_script) trace_set_result(params=params, running_script=running_script)
response_data = await self._async_run_long_action( response_data = await self._async_run_long_action(
self._hass.async_create_task_internal( self._hass.async_create_task_internal(

View File

@ -601,7 +601,7 @@ class Template:
or filter depending on hass or the state machine. or filter depending on hass or the state machine.
""" """
if self.is_static: if self.is_static:
if not parse_result or self.hass and self.hass.config.legacy_templates: if not parse_result or (self.hass and self.hass.config.legacy_templates):
return self.template return self.template
return self._parse_result(self.template) return self._parse_result(self.template)
assert self.hass is not None, "hass variable not set on template" assert self.hass is not None, "hass variable not set on template"
@ -630,7 +630,7 @@ class Template:
self._renders += 1 self._renders += 1
if self.is_static: if self.is_static:
if not parse_result or self.hass and self.hass.config.legacy_templates: if not parse_result or (self.hass and self.hass.config.legacy_templates):
return self.template return self.template
return self._parse_result(self.template) return self._parse_result(self.template)
@ -651,7 +651,7 @@ class Template:
render_result = render_result.strip() render_result = render_result.strip()
if not parse_result or self.hass and self.hass.config.legacy_templates: if not parse_result or (self.hass and self.hass.config.legacy_templates):
return render_result return render_result
return self._parse_result(render_result) return self._parse_result(render_result)
@ -826,7 +826,7 @@ class Template:
) )
return value if error_value is _SENTINEL else error_value return value if error_value is _SENTINEL else error_value
if not parse_result or self.hass and self.hass.config.legacy_templates: if not parse_result or (self.hass and self.hass.config.legacy_templates):
return render_result return render_result
return self._parse_result(render_result) return self._parse_result(render_result)
@ -1873,7 +1873,8 @@ def is_state(hass: HomeAssistant, entity_id: str, state: str | list[str]) -> boo
"""Test if a state is a specific value.""" """Test if a state is a specific value."""
state_obj = _get_state(hass, entity_id) state_obj = _get_state(hass, entity_id)
return state_obj is not None and ( return state_obj is not None and (
state_obj.state == state or isinstance(state, list) and state_obj.state in state state_obj.state == state
or (isinstance(state, list) and state_obj.state in state)
) )

View File

@ -359,7 +359,7 @@ class DataUpdateCoordinator(BaseDataUpdateCoordinatorProtocol, Generic[_DataT]):
self._async_unsub_refresh() self._async_unsub_refresh()
self._debounced_refresh.async_cancel() self._debounced_refresh.async_cancel()
if self._shutdown_requested or scheduled and self.hass.is_stopping: if self._shutdown_requested or (scheduled and self.hass.is_stopping):
return return
if log_timing := self.logger.isEnabledFor(logging.DEBUG): if log_timing := self.logger.isEnabledFor(logging.DEBUG):

View File

@ -55,10 +55,14 @@ class TypeHintMatch:
"""Confirm if function should be checked.""" """Confirm if function should be checked."""
return ( return (
self.function_name == node.name self.function_name == node.name
or self.has_async_counterpart or (
and node.name == f"async_{self.function_name}" self.has_async_counterpart
or self.function_name.endswith("*") and node.name == f"async_{self.function_name}"
and node.name.startswith(self.function_name[:-1]) )
or (
self.function_name.endswith("*")
and node.name.startswith(self.function_name[:-1])
)
) )
@ -2998,8 +3002,8 @@ def _is_valid_type(
isinstance(node, nodes.Subscript) isinstance(node, nodes.Subscript)
and isinstance(node.value, nodes.Name) and isinstance(node.value, nodes.Name)
and node.value.name in _KNOWN_GENERIC_TYPES and node.value.name in _KNOWN_GENERIC_TYPES
or isinstance(node, nodes.Name) ) or (
and node.name.endswith(_KNOWN_GENERIC_TYPES_TUPLE) isinstance(node, nodes.Name) and node.name.endswith(_KNOWN_GENERIC_TYPES_TUPLE)
): ):
return True return True

View File

@ -268,9 +268,8 @@ class HassImportsFormatChecker(BaseChecker):
self, current_package: str, node: nodes.ImportFrom self, current_package: str, node: nodes.ImportFrom
) -> None: ) -> None:
"""Check for improper 'from ._ import _' invocations.""" """Check for improper 'from ._ import _' invocations."""
if ( if node.level <= 1 or (
node.level <= 1 not current_package.startswith("homeassistant.components.")
or not current_package.startswith("homeassistant.components.")
and not current_package.startswith("tests.components.") and not current_package.startswith("tests.components.")
): ):
return return

View File

@ -763,6 +763,7 @@ select = [
"RUF018", # Avoid assignment expressions in assert statements "RUF018", # Avoid assignment expressions in assert statements
"RUF019", # Unnecessary key check before dictionary access "RUF019", # Unnecessary key check before dictionary access
"RUF020", # {never_like} | T is equivalent to T "RUF020", # {never_like} | T is equivalent to T
"RUF021", # Parenthesize a and b expressions when chaining and and or together, to make the precedence clear
"RUF022", # Sort __all__ "RUF022", # Sort __all__
"RUF024", # Do not pass mutable objects as values to dict.fromkeys "RUF024", # Do not pass mutable objects as values to dict.fromkeys
"RUF026", # default_factory is a positional-only argument to defaultdict "RUF026", # default_factory is a positional-only argument to defaultdict

View File

@ -70,8 +70,10 @@ def run():
# If we want to only add references to own integrations # If we want to only add references to own integrations
# but not include entity integrations # but not include entity integrations
if ( if (
args.limit_reference (
and (key_integration != key_to_reference_integration and not is_common) args.limit_reference
and (key_integration != key_to_reference_integration and not is_common)
)
# Do not create self-references in entity integrations # Do not create self-references in entity integrations
or key_integration in Platform.__members__.values() or key_integration in Platform.__members__.values()
): ):

View File

@ -316,7 +316,7 @@ async def test_sync_notifications(agents) -> None:
config, "async_sync_notification", return_value=HTTPStatus.NO_CONTENT config, "async_sync_notification", return_value=HTTPStatus.NO_CONTENT
) as mock: ) as mock:
await config.async_sync_notification_all("1234", {}) await config.async_sync_notification_all("1234", {})
assert not agents or bool(mock.mock_calls) and agents assert not agents or (bool(mock.mock_calls) and agents)
@pytest.mark.parametrize( @pytest.mark.parametrize(

View File

@ -171,11 +171,8 @@ async def test_receiving_message_successfully(
assert data["subject"] == "Test subject" assert data["subject"] == "Test subject"
assert data["uid"] == "1" assert data["uid"] == "1"
assert "Test body" in data["text"] assert "Test body" in data["text"]
assert ( assert (valid_date and isinstance(data["date"], datetime)) or (
valid_date not valid_date and data["date"] is None
and isinstance(data["date"], datetime)
or not valid_date
and data["date"] is None
) )
@ -581,11 +578,8 @@ async def test_reset_last_message(
assert data["subject"] == "Test subject" assert data["subject"] == "Test subject"
assert data["text"] assert data["text"]
assert data["initial"] assert data["initial"]
assert ( assert (valid_date and isinstance(data["date"], datetime)) or (
valid_date not valid_date and data["date"] is None
and isinstance(data["date"], datetime)
or not valid_date
and data["date"] is None
) )
# Simulate an update where no messages are found (needed for pushed coordinator) # Simulate an update where no messages are found (needed for pushed coordinator)

View File

@ -42,9 +42,8 @@ class CommandTestParameters:
Commands that are named with 'Subset' are expected not to be read from Room A. Commands that are named with 'Subset' are expected not to be read from Room A.
""" """
if ( if self.expected_event_data_extra is None or (
self.expected_event_data_extra is None "Subset" in self.expected_event_data_extra["command"]
or "Subset" in self.expected_event_data_extra["command"]
and self.room_id not in SUBSET_ROOMS and self.room_id not in SUBSET_ROOMS
): ):
return None return None

View File

@ -25,10 +25,8 @@ def setup_owproxy_mock_devices(owproxy: MagicMock, device_ids: list[str]) -> Non
if (side_effect := dir_side_effect.get(path)) is None: if (side_effect := dir_side_effect.get(path)) is None:
raise NotImplementedError(f"Unexpected _dir call: {path}") raise NotImplementedError(f"Unexpected _dir call: {path}")
result = side_effect.pop(0) result = side_effect.pop(0)
if ( if isinstance(result, Exception) or (
isinstance(result, Exception) isinstance(result, type) and issubclass(result, Exception)
or isinstance(result, type)
and issubclass(result, Exception)
): ):
raise result raise result
return result return result
@ -39,10 +37,8 @@ def setup_owproxy_mock_devices(owproxy: MagicMock, device_ids: list[str]) -> Non
if len(side_effect) == 0: if len(side_effect) == 0:
raise ProtocolError(f"Missing injected value for: {path}") raise ProtocolError(f"Missing injected value for: {path}")
result = side_effect.pop(0) result = side_effect.pop(0)
if ( if isinstance(result, Exception) or (
isinstance(result, Exception) isinstance(result, type) and issubclass(result, Exception)
or isinstance(result, type)
and issubclass(result, Exception)
): ):
raise result raise result
return result return result