Improve loops and lists (#113269)

* Enable PERF

* Enable PERF rule

* Enable PERF rule

* Don't enable flag yet
This commit is contained in:
Joost Lekkerkerker 2024-03-14 10:22:20 +01:00 committed by GitHub
parent 8a98fb7cfd
commit 05172d8e4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 125 additions and 172 deletions

View File

@ -58,10 +58,7 @@ def _merge_policies(sources: list[CategoryType]) -> CategoryType:
continue
seen.add(key)
key_sources = []
for src in sources:
if isinstance(src, dict):
key_sources.append(src.get(key))
key_sources = [src.get(key) for src in sources if isinstance(src, dict)]
policy[key] = _merge_policies(key_sources)

View File

@ -98,16 +98,16 @@ async def async_setup_entry(
_LOGGER.error("No devices found")
return
tasks = []
for heater in data_connection.get_devices():
tasks.append(asyncio.create_task(heater.update_device_info()))
tasks = [
asyncio.create_task(heater.update_device_info())
for heater in data_connection.get_devices()
]
await asyncio.wait(tasks)
devs = []
for heater in data_connection.get_devices():
devs.append(AmbiclimateEntity(heater, store))
async_add_entities(devs, True)
async_add_entities(
(AmbiclimateEntity(heater, store) for heater in data_connection.get_devices()),
True,
)
async def send_comfort_feedback(service: ServiceCall) -> None:
"""Send comfort feedback."""

View File

@ -230,15 +230,14 @@ class AWSSQS(AWSNotify):
async with self.session.create_client(
self.service, **self.aws_config
) as client:
tasks = []
for target in kwargs.get(ATTR_TARGET, []):
tasks.append(
client.send_message(
QueueUrl=target,
MessageBody=json_body,
MessageAttributes=message_attributes,
)
tasks = [
client.send_message(
QueueUrl=target,
MessageBody=json_body,
MessageAttributes=message_attributes,
)
for target in kwargs.get(ATTR_TARGET, [])
]
if tasks:
await asyncio.gather(*tasks)

View File

@ -46,13 +46,13 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Ecovacs vacuums."""
vacuums: list[EcovacsVacuum | EcovacsLegacyVacuum] = []
controller: EcovacsController = hass.data[DOMAIN][config_entry.entry_id]
vacuums: list[EcovacsVacuum | EcovacsLegacyVacuum] = [
EcovacsVacuum(device) for device in controller.devices(VacuumCapabilities)
]
for device in controller.legacy_devices:
await hass.async_add_executor_job(device.connect_and_wait_until_ready)
vacuums.append(EcovacsLegacyVacuum(device))
for device in controller.devices(VacuumCapabilities):
vacuums.append(EcovacsVacuum(device))
_LOGGER.debug("Adding Ecovacs Vacuums to Home Assistant: %s", vacuums)
async_add_entities(vacuums)

View File

@ -223,29 +223,29 @@ async def async_setup_entry(
"""Set up the Glances sensors."""
coordinator: GlancesDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
entities = []
entities: list[GlancesSensor] = []
for sensor_type, sensors in coordinator.data.items():
if sensor_type in ["fs", "sensors", "raid"]:
for sensor_label, params in sensors.items():
for param in params:
if sensor_description := SENSOR_TYPES.get((sensor_type, param)):
entities.append(
GlancesSensor(
coordinator,
sensor_description,
sensor_label,
)
)
entities.extend(
GlancesSensor(
coordinator,
sensor_description,
sensor_label,
)
for sensor_label, params in sensors.items()
for param in params
if (sensor_description := SENSOR_TYPES.get((sensor_type, param)))
)
else:
for sensor in sensors:
if sensor_description := SENSOR_TYPES.get((sensor_type, sensor)):
entities.append(
GlancesSensor(
coordinator,
sensor_description,
)
)
entities.extend(
GlancesSensor(
coordinator,
sensor_description,
)
for sensor in sensors
if (sensor_description := SENSOR_TYPES.get((sensor_type, sensor)))
)
async_add_entities(entities)

View File

@ -66,8 +66,8 @@ class BroadcastNotificationService(BaseNotificationService):
if not targets:
commands.append(broadcast_commands(language_code)[0].format(message))
else:
for target in targets:
commands.append(
broadcast_commands(language_code)[1].format(message, target)
)
commands.extend(
broadcast_commands(language_code)[1].format(message, target)
for target in targets
)
await async_send_text_commands(self.hass, commands)

View File

@ -72,16 +72,14 @@ def setup_platform(
easyfire.run_thread()
sensors = []
for sensor in easyfire.get_sensors():
if (sensor.sensor_type != kwb.PROP_SENSOR_RAW) or (
sensor.sensor_type == kwb.PROP_SENSOR_RAW and raw
):
sensors.append(KWBSensor(easyfire, sensor, client_name))
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, lambda event: easyfire.stop_thread())
add_entities(sensors)
add_entities(
KWBSensor(easyfire, sensor, client_name)
for sensor in easyfire.get_sensors()
if (sensor.sensor_type != kwb.PROP_SENSOR_RAW)
or (sensor.sensor_type == kwb.PROP_SENSOR_RAW and raw)
)
class KWBSensor(SensorEntity):

View File

@ -134,21 +134,6 @@ async def async_setup_entry(
"""Set up the Honeywell Lyric sensor platform based on a config entry."""
coordinator: DataUpdateCoordinator[Lyric] = hass.data[DOMAIN][entry.entry_id]
entities = []
for location in coordinator.data.locations:
for device in location.devices:
for device_sensor in DEVICE_SENSORS:
if device_sensor.suitable_fn(device):
entities.append(
LyricSensor(
coordinator,
device_sensor,
location,
device,
)
)
async_add_entities(
LyricSensor(
coordinator,

View File

@ -311,15 +311,12 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Add a NextDNS entities from a config_entry."""
sensors: list[NextDnsSensor] = []
coordinators = hass.data[DOMAIN][entry.entry_id]
for description in SENSORS:
sensors.append(
NextDnsSensor(coordinators[description.coordinator_type], description)
)
async_add_entities(sensors)
async_add_entities(
NextDnsSensor(coordinators[description.coordinator_type], description)
for description in SENSORS
)
class NextDnsSensor(

View File

@ -21,11 +21,10 @@ def setup_platform(
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up the QR code image processing platform."""
entities = []
for camera in config[CONF_SOURCE]:
entities.append(QrEntity(camera[CONF_ENTITY_ID], camera.get(CONF_NAME)))
add_entities(entities)
add_entities(
QrEntity(camera[CONF_ENTITY_ID], camera.get(CONF_NAME))
for camera in config[CONF_SOURCE]
)
class QrEntity(ImageProcessingEntity):

View File

@ -556,10 +556,11 @@ def _drop_foreign_key_constraints(
) -> None:
"""Drop foreign key constraints for a table on specific columns."""
inspector = sqlalchemy.inspect(engine)
drops = []
for foreign_key in inspector.get_foreign_keys(table):
if foreign_key["name"] and foreign_key["constrained_columns"] == columns:
drops.append(ForeignKeyConstraint((), (), name=foreign_key["name"]))
drops = [
ForeignKeyConstraint((), (), name=foreign_key["name"])
for foreign_key in inspector.get_foreign_keys(table)
if foreign_key["name"] and foreign_key["constrained_columns"] == columns
]
# Bind the ForeignKeyConstraints to the table
old_table = Table(table, MetaData(), *drops) # noqa: F841

View File

@ -219,14 +219,17 @@ async def get_coap_context(hass: HomeAssistant) -> COAP:
ipv4: list[IPv4Address] = []
if not network.async_only_default_interface_enabled(adapters):
for address in await network.async_get_enabled_source_ips(hass):
if address.version == 4 and not (
ipv4.extend(
address
for address in await network.async_get_enabled_source_ips(hass)
if address.version == 4
and not (
address.is_link_local
or address.is_loopback
or address.is_multicast
or address.is_unspecified
):
ipv4.append(address)
)
)
LOGGER.debug("Network IPv4 addresses: %s", ipv4)
if DOMAIN in hass.data:
port = hass.data[DOMAIN].get(CONF_COAP_PORT, DEFAULT_COAP_PORT)

View File

@ -89,10 +89,7 @@ class SigfoxAPI:
"""Get a list of device types."""
url = urljoin(API_URL, "devicetypes")
response = requests.get(url, auth=self._auth, timeout=10)
device_types = []
for device in json.loads(response.text)["data"]:
device_types.append(device["id"])
return device_types
return [device["id"] for device in json.loads(response.text)["data"]]
def get_devices(self, device_types):
"""Get the device_id of each device registered."""

View File

@ -29,14 +29,14 @@ async def async_setup_entry(
data: SleepIQData = hass.data[DOMAIN][entry.entry_id]
entities: list[SleepIQBedEntity] = []
for bed in data.client.beds.values():
for preset in bed.foundation.presets:
entities.append(SleepIQSelectEntity(data.data_coordinator, bed, preset))
for foot_warmer in bed.foundation.foot_warmers:
entities.append(
SleepIQFootWarmingTempSelectEntity(
data.data_coordinator, bed, foot_warmer
)
)
entities.extend(
SleepIQSelectEntity(data.data_coordinator, bed, preset)
for preset in bed.foundation.presets
)
entities.extend(
SleepIQFootWarmingTempSelectEntity(data.data_coordinator, bed, foot_warmer)
for foot_warmer in bed.foundation.foot_warmers
)
async_add_entities(entities)

View File

@ -124,18 +124,18 @@ class SynologyPhotosMediaSource(MediaSource):
can_expand=True,
)
]
for album in albums:
ret.append(
BrowseMediaSource(
domain=DOMAIN,
identifier=f"{item.identifier}/{album.album_id}",
media_class=MediaClass.DIRECTORY,
media_content_type=MediaClass.IMAGE,
title=album.name,
can_play=False,
can_expand=True,
)
ret.extend(
BrowseMediaSource(
domain=DOMAIN,
identifier=f"{item.identifier}/{album.album_id}",
media_class=MediaClass.DIRECTORY,
media_content_type=MediaClass.IMAGE,
title=album.name,
can_play=False,
can_expand=True,
)
for album in albums
)
return ret

View File

@ -60,11 +60,11 @@ async def async_setup_entry(
for device_id in device_ids:
device = hass_data.manager.device_map[device_id]
if descriptions := SIRENS.get(device.category):
for description in descriptions:
if description.key in device.status:
entities.append(
TuyaSirenEntity(device, hass_data.manager, description)
)
entities.extend(
TuyaSirenEntity(device, hass_data.manager, description)
for description in descriptions
if description.key in device.status
)
async_add_entities(entities)

View File

@ -55,15 +55,6 @@ async def async_setup_entry(
for device_coordinator in device_coordinators.values()
if device_coordinator.device.device_type in DEVICE_TYPE
]
entities = []
for siren_device_coordinator in siren_device_coordinators:
for description in DEVICE_TYPES:
if description.exists_fn(siren_device_coordinator.device):
entities.append(
YoLinkSirenEntity(
config_entry, siren_device_coordinator, description
)
)
async_add_entities(
YoLinkSirenEntity(config_entry, siren_device_coordinator, description)
for siren_device_coordinator in siren_device_coordinators

View File

@ -206,12 +206,11 @@ class ZHAGroup(LogMixin):
@property
def member_entity_ids(self) -> list[str]:
"""Return the ZHA entity ids for all entities for the members of this group."""
all_entity_ids: list[str] = []
for member in self.members:
entity_references = member.associated_entities
for entity_reference in entity_references:
all_entity_ids.append(entity_reference["entity_id"])
return all_entity_ids
return [
entity_reference["entity_id"]
for member in self.members
for entity_reference in member.associated_entities
]
def get_domain_entity_ids(self, domain: str) -> list[str]:
"""Return entity ids from the entity domain for this group."""

View File

@ -221,10 +221,10 @@ class YamlCollection(ObservableCollection[dict]):
self.data[item_id] = item
change_sets.append(CollectionChangeSet(event, item_id, item))
for item_id in old_ids:
change_sets.append(
CollectionChangeSet(CHANGE_REMOVED, item_id, self.data.pop(item_id))
)
change_sets.extend(
CollectionChangeSet(CHANGE_REMOVED, item_id, self.data.pop(item_id))
for item_id in old_ids
)
if change_sets:
await self.notify_changes(change_sets)

View File

@ -142,10 +142,9 @@ def _convert_globs_to_pattern(globs: list[str] | None) -> re.Pattern[str] | None
if globs is None:
return None
translated_patterns: list[str] = []
for glob in set(globs):
if pattern := fnmatch.translate(glob):
translated_patterns.append(pattern)
translated_patterns: list[str] = [
pattern for glob in set(globs) if (pattern := fnmatch.translate(glob))
]
if not translated_patterns:
return None

View File

@ -175,8 +175,7 @@ class HomeAssistantView:
handler = request_handler_factory(hass, self, handler)
for url in urls:
routes.append(router.add_route(method, url, handler))
routes.extend(router.add_route(method, url, handler) for url in urls)
# Use `get` because CORS middleware is not be loaded in emulated_hue
if self.cors_allowed:

View File

@ -57,9 +57,7 @@ class FrozenOrThawed(type):
def _make_dataclass(cls, name: str, bases: tuple[type, ...], kw_only: bool) -> None:
class_fields = _class_fields(cls, kw_only)
dataclass_bases = []
for base in bases:
dataclass_bases.append(getattr(base, "_dataclass", base))
dataclass_bases = [getattr(base, "_dataclass", base) for base in bases]
cls._dataclass = dataclasses.make_dataclass(
name, class_fields, bases=tuple(dataclass_bases), frozen=True
)

View File

@ -347,8 +347,7 @@ def generate_requirements_list(reqs: dict[str, list[str]]) -> str:
"""Generate a pip file based on requirements."""
output = []
for pkg, requirements in sorted(reqs.items(), key=itemgetter(0)):
for req in sorted(requirements):
output.append(f"\n# {req}")
output.extend(f"\n# {req}" for req in sorted(requirements))
if comment_requirement(pkg):
output.append(f"\n# {pkg}\n")

View File

@ -16,8 +16,7 @@ def generate_and_validate(integrations: dict[str, Integration]) -> str:
if not match_types:
continue
for entry in match_types:
match_list.append({"domain": domain, **entry})
match_list.extend({"domain": domain, **entry} for entry in match_types)
return format_python_namespace(
{"BLUETOOTH": match_list},

View File

@ -16,8 +16,7 @@ def generate_and_validate(integrations: dict[str, Integration]) -> str:
if not match_types:
continue
for entry in match_types:
match_list.append({"domain": domain, **entry})
match_list.extend({"domain": domain, **entry} for entry in match_types)
return format_python_namespace(
{"DHCP": match_list},

View File

@ -16,13 +16,13 @@ def generate_and_validate(integrations: dict[str, Integration]) -> str:
if not match_types:
continue
for entry in match_types:
match_list.append(
{
"domain": domain,
**{k: v for k, v in entry.items() if k != "known_devices"},
}
)
match_list.extend(
{
"domain": domain,
**{k: v for k, v in entry.items() if k != "known_devices"},
}
for entry in match_types
)
return format_python_namespace({"USB": match_list})

View File

@ -2397,9 +2397,9 @@ async def test_cached_entity_property_class_attribute(hass: HomeAssistant) -> No
EntityWithClassAttribute4,
)
entities: list[tuple[entity.Entity, entity.Entity]] = []
for cls in classes:
entities.append((cls(), cls()))
entities: list[tuple[entity.Entity, entity.Entity]] = [
(cls(), cls()) for cls in classes
]
for ent in entities:
assert getattr(ent[0], property) == values[0]

View File

@ -3915,9 +3915,9 @@ async def test_entry_reload_concurrency(
),
)
mock_platform(hass, "comp.config_flow", None)
tasks = []
for _ in range(15):
tasks.append(asyncio.create_task(manager.async_reload(entry.entry_id)))
tasks = [
asyncio.create_task(manager.async_reload(entry.entry_id)) for _ in range(15)
]
await asyncio.gather(*tasks)
assert entry.state is config_entries.ConfigEntryState.LOADED
assert loaded == 1

View File

@ -17,10 +17,7 @@ from tests.common import (
def _create_tuples(
value: Enum | list[Enum], constant_prefix: str
) -> list[tuple[Enum, str]]:
result = []
for enum in value:
result.append((enum, constant_prefix))
return result
return [(enum, constant_prefix) for enum in value]
def test_all() -> None:

View File

@ -21,10 +21,7 @@ async def test_executor_shutdown_can_interrupt_threads(
while True:
time.sleep(0.1)
sleep_futures = []
for _ in range(100):
sleep_futures.append(iexecutor.submit(_loop_sleep_in_executor))
sleep_futures = [iexecutor.submit(_loop_sleep_in_executor) for _ in range(100)]
iexecutor.shutdown()