Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions homeassistant/helpers/aiohttp_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,14 @@ def _async_create_clientsession(
# If a package requires a different user agent, override it by passing a headers
# dictionary to the request method.
# pylint: disable=protected-access
clientsession._default_headers = MappingProxyType({USER_AGENT: SERVER_SOFTWARE}) # type: ignore[assignment]
clientsession._default_headers = MappingProxyType( # type: ignore[assignment]
{USER_AGENT: SERVER_SOFTWARE},
)

clientsession.close = warn_use(clientsession.close, WARN_CLOSE_MSG) # type: ignore[assignment]
clientsession.close = warn_use( # type: ignore[assignment]
clientsession.close,
WARN_CLOSE_MSG,
)

if auto_cleanup_method:
auto_cleanup_method(hass, clientsession)
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/helpers/condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,8 @@ def sun(
# Special case: before sunrise OR after sunset
# This will handle the very rare case in the polar region when the sun rises/sets
# but does not set/rise.
# However this entire condition does not handle those full days of darkness or light,
# the following should be used instead:
# However this entire condition does not handle those full days of darkness
# or light, the following should be used instead:
#
# condition:
# condition: state
Expand Down
23 changes: 13 additions & 10 deletions homeassistant/helpers/config_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,12 +778,12 @@ def _deprecated_or_removed(
raise_if_present: bool,
option_removed: bool,
) -> Callable[[dict], dict]:
"""
Log key as deprecated and provide a replacement (if exists) or fail.
"""Log key as deprecated and provide a replacement (if exists) or fail.

Expected behavior:
- Outputs or throws the appropriate deprecation warning if key is detected
- Outputs or throws the appropriate error if key is detected and removed from support
- Outputs or throws the appropriate error if key is detected
and removed from support
- Processes schema moving the value from key to replacement_key
- Processes schema changing nothing if only replacement_key provided
- No warning if only replacement_key provided
Expand All @@ -809,7 +809,10 @@ def validator(config: dict) -> dict:
"""Check if key is in config and log warning or error."""
if key in config:
try:
near = f"near {config.__config_file__}:{config.__line__} " # type: ignore[attr-defined]
near = (
f"near {config.__config_file__}" # type: ignore[attr-defined]
f":{config.__line__} "
)
except AttributeError:
near = ""
arguments: tuple[str, ...]
Expand Down Expand Up @@ -851,11 +854,11 @@ def deprecated(
default: Any | None = None,
raise_if_present: bool | None = False,
) -> Callable[[dict], dict]:
"""
Log key as deprecated and provide a replacement (if exists).
"""Log key as deprecated and provide a replacement (if exists).

Expected behavior:
- Outputs the appropriate deprecation warning if key is detected or raises an exception
- Outputs the appropriate deprecation warning if key is detected
or raises an exception
- Processes schema moving the value from key to replacement_key
- Processes schema changing nothing if only replacement_key provided
- No warning if only replacement_key provided
Expand All @@ -876,11 +879,11 @@ def removed(
default: Any | None = None,
raise_if_present: bool | None = True,
) -> Callable[[dict], dict]:
"""
Log key as deprecated and fail the config validation.
"""Log key as deprecated and fail the config validation.

Expected behavior:
- Outputs the appropriate error if key is detected and removed from support or raises an exception
- Outputs the appropriate error if key is detected and removed from
support or raises an exception.
"""
return _deprecated_or_removed(
key,
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/helpers/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def deprecated_cls(*args: _P.args, **kwargs: _P.kwargs) -> _R:
def deprecated_function(
replacement: str,
) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]:
"""Mark function as deprecated and provide a replacement function to be used instead."""
"""Mark function as deprecated and provide a replacement to be used instead."""

def deprecated_decorator(func: Callable[_P, _R]) -> Callable[_P, _R]:
"""Decorate function as deprecated."""
Expand Down
24 changes: 19 additions & 5 deletions homeassistant/helpers/device_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ async def _async_migrate_func(
device.setdefault("configuration_url", None)
device.setdefault("disabled_by", None)
try:
device["entry_type"] = DeviceEntryType(device.get("entry_type")) # type: ignore[arg-type]
device["entry_type"] = DeviceEntryType(
device.get("entry_type"), # type: ignore[arg-type]
)
except ValueError:
device["entry_type"] = None
device.setdefault("name_by_user", None)
Expand Down Expand Up @@ -550,7 +552,10 @@ async def async_load(self) -> None:
config_entries=set(device["config_entries"]),
configuration_url=device["configuration_url"],
# type ignores (if tuple arg was cast): likely https://github.com/python/mypy/issues/8625
connections={tuple(conn) for conn in device["connections"]}, # type: ignore[misc]
connections={
tuple(conn) # type: ignore[misc]
for conn in device["connections"]
},
disabled_by=DeviceEntryDisabler(device["disabled_by"])
if device["disabled_by"]
else None,
Expand All @@ -559,7 +564,10 @@ async def async_load(self) -> None:
else None,
hw_version=device["hw_version"],
id=device["id"],
identifiers={tuple(iden) for iden in device["identifiers"]}, # type: ignore[misc]
identifiers={
tuple(iden) # type: ignore[misc]
for iden in device["identifiers"]
},
manufacturer=device["manufacturer"],
model=device["model"],
name_by_user=device["name_by_user"],
Expand All @@ -572,8 +580,14 @@ async def async_load(self) -> None:
deleted_devices[device["id"]] = DeletedDeviceEntry(
config_entries=set(device["config_entries"]),
# type ignores (if tuple arg was cast): likely https://github.com/python/mypy/issues/8625
connections={tuple(conn) for conn in device["connections"]}, # type: ignore[misc]
identifiers={tuple(iden) for iden in device["identifiers"]}, # type: ignore[misc]
connections={
tuple(conn) # type: ignore[misc]
for conn in device["connections"]
},
identifiers={
tuple(iden) # type: ignore[misc]
for iden in device["identifiers"]
},
id=device["id"],
orphaned_timestamp=device["orphaned_timestamp"],
)
Expand Down
24 changes: 17 additions & 7 deletions homeassistant/helpers/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,11 @@ class EntityCategory(StrEnum):
- Not be included in indirect service calls to devices or areas
"""

# Config: An entity which allows changing the configuration of a device
# Config: An entity which allows changing the configuration of a device.
CONFIG = "config"

# Diagnostic: An entity exposing some configuration parameter or diagnostics of a device
# Diagnostic: An entity exposing some configuration parameter,
# or diagnostics of a device.
DIAGNOSTIC = "diagnostic"


Expand All @@ -198,13 +199,16 @@ class EntityCategory(StrEnum):
class EntityPlatformState(Enum):
"""The platform state of an entity."""

# Not Added: Not yet added to a platform, polling updates are written to the state machine
# Not Added: Not yet added to a platform, polling updates
# are written to the state machine.
NOT_ADDED = auto()

# Added: Added to a platform, polling updates are written to the state machine
# Added: Added to a platform, polling updates
# are written to the state machine.
ADDED = auto()

# Removed: Removed from a platform, polling updates are not written to the state machine
# Removed: Removed from a platform, polling updates
# are not written to the state machine.
REMOVED = auto()


Expand Down Expand Up @@ -458,7 +462,10 @@ def context_recent_time(self) -> timedelta:

@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
"""Return if the entity should be enabled when first added.

This only applies when fist added to the entity registry.
"""
if hasattr(self, "_attr_entity_registry_enabled_default"):
return self._attr_entity_registry_enabled_default
if hasattr(self, "entity_description"):
Expand All @@ -467,7 +474,10 @@ def entity_registry_enabled_default(self) -> bool:

@property
def entity_registry_visible_default(self) -> bool:
"""Return if the entity should be visible when first added to the entity registry."""
"""Return if the entity should be visible when first added.

This only applies when fist added to the entity registry.
"""
if hasattr(self, "_attr_entity_registry_visible_default"):
return self._attr_entity_registry_visible_default
if hasattr(self, "entity_description"):
Expand Down
8 changes: 4 additions & 4 deletions homeassistant/helpers/entity_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ def __init__(

@property
def entities(self) -> Iterable[_EntityT]:
"""
Return an iterable that returns all entities.
"""Return an iterable that returns all entities.

As the underlying dicts may change when async context is lost, callers that
iterate over this asynchronously should make a copy using list() before iterating.
As the underlying dicts may change when async context is lost,
callers that iterate over this asynchronously should make a copy
using list() before iterating.
"""
return chain.from_iterable(
platform.entities.values() # type: ignore[misc]
Expand Down
22 changes: 15 additions & 7 deletions homeassistant/helpers/entity_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,16 @@ def _get_parallel_updates_semaphore(
) -> asyncio.Semaphore | None:
"""Get or create a semaphore for parallel updates.

Semaphore will be created on demand because we base it off if update method is async or not.
Semaphore will be created on demand because we base it off if update
method is async or not.

If parallel updates is set to 0, we skip the semaphore.
If parallel updates is set to a number, we initialize the semaphore to that number.
The default value for parallel requests is decided based on the first entity that is added to Home Assistant.
It's 0 if the entity defines the async_update method, else it's 1.
- If parallel updates is set to 0, we skip the semaphore.
- If parallel updates is set to a number, we initialize the semaphore
to that number.

The default value for parallel requests is decided based on the first
entity that is added to Home Assistant. It's 0 if the entity defines
the async_update method, else it's 1.
"""
if self.parallel_updates_created:
return self.parallel_updates
Expand Down Expand Up @@ -566,7 +570,9 @@ async def _async_add_entity( # noqa: C901
"via_device",
):
if key in device_info:
processed_dev_info[key] = device_info[key] # type: ignore[literal-required]
processed_dev_info[key] = device_info[
key # type: ignore[literal-required]
]

if "configuration_url" in device_info:
if device_info["configuration_url"] is None:
Expand All @@ -586,7 +592,9 @@ async def _async_add_entity( # noqa: C901
)

try:
device = device_registry.async_get_or_create(**processed_dev_info) # type: ignore[arg-type]
device = device_registry.async_get_or_create(
**processed_dev_info # type: ignore[arg-type]
)
device_id = device.id
except RequiredParameterMissing:
pass
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/helpers/entity_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ class RegistryEntry:
has_entity_name: bool = attr.ib(default=False)
name: str | None = attr.ib(default=None)
options: EntityOptionsType = attr.ib(
default=None, converter=attr.converters.default_if_none(factory=dict) # type: ignore[misc]
default=None,
converter=attr.converters.default_if_none(factory=dict), # type: ignore[misc]
)
# As set by integration
original_device_class: str | None = attr.ib(default=None)
Expand Down Expand Up @@ -780,8 +781,7 @@ def async_update_entity_platform(
new_unique_id: str | UndefinedType = UNDEFINED,
new_device_id: str | None | UndefinedType = UNDEFINED,
) -> RegistryEntry:
"""
Update entity platform.
"""Update entity platform.

This should only be used when an entity needs to be migrated between
integrations.
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/helpers/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,8 +710,8 @@ def async_track_state_change_filtered(

Returns
-------
Object used to update the listeners (async_update_listeners) with a new TrackStates or
cancel the tracking (async_remove).
Object used to update the listeners (async_update_listeners) with a new
TrackStates or cancel the tracking (async_remove).

"""
tracker = _TrackStateChangeFiltered(hass, track_states, action)
Expand Down
19 changes: 14 additions & 5 deletions homeassistant/helpers/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ def find_coordinates(
) -> str | None:
"""Try to resolve the a location from a supplied name or entity_id.

Will recursively resolve an entity if pointed to by the state of the supplied entity.
Returns coordinates in the form of '90.000,180.000', an address or the state of the last resolved entity.
Will recursively resolve an entity if pointed to by the state of the supplied
entity.

Returns coordinates in the form of '90.000,180.000', an address or
the state of the last resolved entity.
"""
# Check if a friendly name of a zone was supplied
if (zone_coords := resolve_zone(hass, name)) is not None:
Expand All @@ -70,7 +73,9 @@ def find_coordinates(
zone_entity = hass.states.get(f"zone.{entity_state.state}")
if has_location(zone_entity): # type: ignore[arg-type]
_LOGGER.debug(
"%s is in %s, getting zone location", name, zone_entity.entity_id # type: ignore[union-attr]
"%s is in %s, getting zone location",
name,
zone_entity.entity_id, # type: ignore[union-attr]
)
return _get_location_from_attributes(zone_entity) # type: ignore[arg-type]

Expand All @@ -97,12 +102,16 @@ def find_coordinates(
_LOGGER.debug("Resolving nested entity_id: %s", entity_state.state)
return find_coordinates(hass, entity_state.state, recursion_history)

# Might be an address, coordinates or anything else. This has to be checked by the caller.
# Might be an address, coordinates or anything else.
# This has to be checked by the caller.
return entity_state.state


def resolve_zone(hass: HomeAssistant, zone_name: str) -> str | None:
"""Get a lat/long from a zones friendly_name or None if no zone is found by that friendly_name."""
"""Get a lat/long from a zones friendly_name.

None is returned if no zone is found by that friendly_name.
"""
states = hass.states.async_all("zone")
for state in states:
if state.name == zone_name:
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/helpers/restore_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,9 @@ async def _async_get_restored_data(self) -> StoredState | None:
"""Get data stored for an entity, if any."""
if self.hass is None or self.entity_id is None:
# Return None if this entity isn't added to hass yet
_LOGGER.warning("Cannot get last state. Entity not added to hass") # type: ignore[unreachable]
_LOGGER.warning( # type: ignore[unreachable]
"Cannot get last state. Entity not added to hass"
)
return None
data = await RestoreStateData.async_get_instance(self.hass)
if self.entity_id not in data.last_states:
Expand Down
18 changes: 9 additions & 9 deletions homeassistant/helpers/schema_config_entry_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ class SchemaFlowFormStep(SchemaFlowStep):
"""Optional property to identify next step.

- If `next_step` is a function, it is called if the schema validates successfully or
if no schema is defined. The `next_step` function is passed the union of config entry
options and user input from previous steps. If the function returns None, the flow is
ended with `FlowResultType.CREATE_ENTRY`.
if no schema is defined. The `next_step` function is passed the union of
config entry options and user input from previous steps. If the function returns
None, the flow is ended with `FlowResultType.CREATE_ENTRY`.
- If `next_step` is None, the flow is ended with `FlowResultType.CREATE_ENTRY`.
"""

Expand All @@ -71,11 +71,11 @@ class SchemaFlowFormStep(SchemaFlowStep):
] | None | UndefinedType = UNDEFINED
"""Optional property to populate suggested values.

- If `suggested_values` is UNDEFINED, each key in the schema will get a suggested value
from an option with the same key.
- If `suggested_values` is UNDEFINED, each key in the schema will get a suggested
value from an option with the same key.

Note: if a step is retried due to a validation failure, then the user input will have
priority over the suggested values.
Note: if a step is retried due to a validation failure, then the user input will
have priority over the suggested values.
"""


Expand Down Expand Up @@ -331,8 +331,8 @@ def async_options_flow_finished(
) -> None:
"""Take necessary actions after the options flow is finished, if needed.

The options parameter contains config entry options, which is the union of stored
options and user input from the options flow steps.
The options parameter contains config entry options, which is the union of
stored options and user input from the options flow steps.
"""

@callback
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/helpers/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
def sensor_device_info_to_hass_device_info(
sensor_device_info: SensorDeviceInfo,
) -> DeviceInfo:
"""Convert a sensor_state_data sensor device info to a Home Assistant device info."""
"""Convert a sensor_state_data sensor device info to a HA device info."""
Copy link
Copy Markdown
Member

@bdraco bdraco Jan 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's one way of making it shorter 😄 I got a laugh out of that.

device_info = DeviceInfo()
if sensor_device_info.name is not None:
device_info[const.ATTR_NAME] = sensor_device_info.name
Expand Down
Loading