diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 862a664976b..4555a336cc3 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -517,14 +517,14 @@ class AutomationEntity(ToggleEntity, RestoreEntity): if self._trigger_variables: try: variables = self._trigger_variables.async_render( - cast(HomeAssistant, self.hass), None, limited=True + self.hass, None, limited=True ) except template.TemplateError as err: self._logger.error("Error rendering trigger variables: %s", err) return None return await async_initialize_triggers( - cast(HomeAssistant, self.hass), + self.hass, self._trigger_config, self.async_trigger, DOMAIN, diff --git a/homeassistant/components/bond/entity.py b/homeassistant/components/bond/entity.py index cd120d79d56..b56c87f692f 100644 --- a/homeassistant/components/bond/entity.py +++ b/homeassistant/components/bond/entity.py @@ -158,7 +158,6 @@ class BondEntity(Entity): await super().async_added_to_hass() self._update_lock = Lock() self._bpup_subs.subscribe(self._device_id, self._async_bpup_callback) - assert self.hass is not None self.async_on_remove( async_track_time_interval( self.hass, self._async_update_if_bpup_not_alive, _FALLBACK_SCAN_INTERVAL diff --git a/homeassistant/components/climacell/config_flow.py b/homeassistant/components/climacell/config_flow.py index 09e02f3f559..7048e4e5c2a 100644 --- a/homeassistant/components/climacell/config_flow.py +++ b/homeassistant/components/climacell/config_flow.py @@ -110,7 +110,6 @@ class ClimaCellConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self, user_input: Dict[str, Any] = None ) -> Dict[str, Any]: """Handle the initial step.""" - assert self.hass errors = {} if user_input is not None: await self.async_set_unique_id( diff --git a/homeassistant/components/group/__init__.py b/homeassistant/components/group/__init__.py index f185601ce87..1ce0b3e71d7 100644 --- a/homeassistant/components/group/__init__.py +++ b/homeassistant/components/group/__init__.py @@ -395,7 +395,6 @@ class GroupEntity(Entity): async def async_added_to_hass(self) -> None: """Register listeners.""" - assert self.hass is not None async def _update_at_start(_): await self.async_update() @@ -405,8 +404,6 @@ class GroupEntity(Entity): async def async_defer_or_update_ha_state(self) -> None: """Only update once at start.""" - assert self.hass is not None - if self.hass.state != CoreState.running: return diff --git a/homeassistant/components/group/cover.py b/homeassistant/components/group/cover.py index da842ee9f00..c19e81778a0 100644 --- a/homeassistant/components/group/cover.py +++ b/homeassistant/components/group/cover.py @@ -155,7 +155,6 @@ class CoverGroup(GroupEntity, CoverEntity): await self.async_update_supported_features( entity_id, new_state, update_state=False ) - assert self.hass is not None self.async_on_remove( async_track_state_change_event( self.hass, self._entities, self._update_supported_features_event diff --git a/homeassistant/components/group/light.py b/homeassistant/components/group/light.py index 482bdbafdab..cebc697efae 100644 --- a/homeassistant/components/group/light.py +++ b/homeassistant/components/group/light.py @@ -103,7 +103,6 @@ class LightGroup(GroupEntity, light.LightEntity): self.async_set_context(event.context) await self.async_defer_or_update_ha_state() - assert self.hass self.async_on_remove( async_track_state_change_event( self.hass, self._entity_ids, async_state_changed_listener diff --git a/homeassistant/components/huawei_lte/__init__.py b/homeassistant/components/huawei_lte/__init__.py index 341f9c0a118..2d33d1a1822 100644 --- a/homeassistant/components/huawei_lte/__init__.py +++ b/homeassistant/components/huawei_lte/__init__.py @@ -636,7 +636,6 @@ class HuaweiLteBaseEntity(Entity): async def async_added_to_hass(self) -> None: """Connect to update signals.""" - assert self.hass is not None self._unsub_handlers.append( async_dispatcher_connect(self.hass, UPDATE_SIGNAL, self._async_maybe_update) ) diff --git a/homeassistant/components/hyperion/light.py b/homeassistant/components/hyperion/light.py index 838b69cd52b..89f70c8f24d 100644 --- a/homeassistant/components/hyperion/light.py +++ b/homeassistant/components/hyperion/light.py @@ -397,7 +397,6 @@ class HyperionBaseLight(LightEntity): async def async_added_to_hass(self) -> None: """Register callbacks when entity added to hass.""" - assert self.hass self.async_on_remove( async_dispatcher_connect( self.hass, diff --git a/homeassistant/components/hyperion/switch.py b/homeassistant/components/hyperion/switch.py index e2da80e5093..f6317a8f396 100644 --- a/homeassistant/components/hyperion/switch.py +++ b/homeassistant/components/hyperion/switch.py @@ -193,7 +193,6 @@ class HyperionComponentSwitch(SwitchEntity): async def async_added_to_hass(self) -> None: """Register callbacks when entity added to hass.""" - assert self.hass self.async_on_remove( async_dispatcher_connect( self.hass, diff --git a/homeassistant/components/notify/__init__.py b/homeassistant/components/notify/__init__.py index 7be66dc3c59..5e1493a68eb 100644 --- a/homeassistant/components/notify/__init__.py +++ b/homeassistant/components/notify/__init__.py @@ -2,7 +2,7 @@ import asyncio from functools import partial import logging -from typing import Any, Dict, Optional, cast +from typing import Any, Dict, cast import voluptuous as vol @@ -114,7 +114,11 @@ def _async_integration_has_notify_services( class BaseNotificationService: """An abstract class for notification services.""" - hass: Optional[HomeAssistantType] = None + # While not purely typed, it makes typehinting more useful for us + # and removes the need for constant None checks or asserts. + # Ignore types: https://github.com/PyCQA/pylint/issues/3167 + hass: HomeAssistantType = None # type: ignore + # Name => target registered_targets: Dict[str, str] @@ -130,7 +134,9 @@ class BaseNotificationService: kwargs can contain ATTR_TITLE to specify a title. """ - await self.hass.async_add_executor_job(partial(self.send_message, message, **kwargs)) # type: ignore + await self.hass.async_add_executor_job( + partial(self.send_message, message, **kwargs) + ) async def _async_notify_message_service(self, service: ServiceCall) -> None: """Handle sending notification message service calls.""" @@ -175,8 +181,6 @@ class BaseNotificationService: async def async_register_services(self) -> None: """Create or update the notify services.""" - assert self.hass - if hasattr(self, "targets"): stale_targets = set(self.registered_targets) @@ -232,8 +236,6 @@ class BaseNotificationService: async def async_unregister_services(self) -> None: """Unregister the notify services.""" - assert self.hass - if self.registered_targets: remove_targets = set(self.registered_targets) for remove_target_name in remove_targets: diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index 31a0bcd7762..933b07e4f58 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -110,5 +110,4 @@ class NumberEntity(Entity): async def async_set_value(self, value: float) -> None: """Set new value.""" - assert self.hass is not None await self.hass.async_add_executor_job(self.set_value, value) diff --git a/homeassistant/components/remote/__init__.py b/homeassistant/components/remote/__init__.py index 720f7c5ff16..12b81402d61 100644 --- a/homeassistant/components/remote/__init__.py +++ b/homeassistant/components/remote/__init__.py @@ -173,7 +173,6 @@ class RemoteEntity(ToggleEntity): async def async_send_command(self, command: Iterable[str], **kwargs: Any) -> None: """Send commands to a device.""" - assert self.hass is not None await self.hass.async_add_executor_job( ft.partial(self.send_command, command, **kwargs) ) @@ -184,7 +183,6 @@ class RemoteEntity(ToggleEntity): async def async_learn_command(self, **kwargs: Any) -> None: """Learn a command from a device.""" - assert self.hass is not None await self.hass.async_add_executor_job(ft.partial(self.learn_command, **kwargs)) def delete_command(self, **kwargs: Any) -> None: @@ -193,7 +191,6 @@ class RemoteEntity(ToggleEntity): async def async_delete_command(self, **kwargs: Any) -> None: """Delete commands from the database.""" - assert self.hass is not None await self.hass.async_add_executor_job( ft.partial(self.delete_command, **kwargs) ) diff --git a/homeassistant/components/scene/__init__.py b/homeassistant/components/scene/__init__.py index 245d21770ee..4bc63d585be 100644 --- a/homeassistant/components/scene/__init__.py +++ b/homeassistant/components/scene/__init__.py @@ -104,7 +104,6 @@ class Scene(Entity): async def async_activate(self, **kwargs: Any) -> None: """Activate scene. Try to get entities into requested state.""" - assert self.hass task = self.hass.async_add_job(ft.partial(self.activate, **kwargs)) if task: await task diff --git a/homeassistant/components/switch/light.py b/homeassistant/components/switch/light.py index 2650bd61bfb..fc8638162e7 100644 --- a/homeassistant/components/switch/light.py +++ b/homeassistant/components/switch/light.py @@ -120,13 +120,11 @@ class LightSwitch(LightEntity): async def async_added_to_hass(self) -> None: """Register callbacks.""" - assert self.hass is not None self._switch_state = self.hass.states.get(self._switch_entity_id) @callback def async_state_changed_listener(*_: Any) -> None: """Handle child updates.""" - assert self.hass is not None self._switch_state = self.hass.states.get(self._switch_entity_id) self.async_write_ha_state() diff --git a/homeassistant/components/zwave_js/climate.py b/homeassistant/components/zwave_js/climate.py index 9276ec2ed0b..3f6b26f536f 100644 --- a/homeassistant/components/zwave_js/climate.py +++ b/homeassistant/components/zwave_js/climate.py @@ -373,7 +373,6 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity): async def async_set_temperature(self, **kwargs: Any) -> None: """Set new target temperature.""" - assert self.hass hvac_mode: Optional[str] = kwargs.get(ATTR_HVAC_MODE) if hvac_mode is not None: diff --git a/homeassistant/components/zwave_js/config_flow.py b/homeassistant/components/zwave_js/config_flow.py index 4929f7e7869..8ba2909cf20 100644 --- a/homeassistant/components/zwave_js/config_flow.py +++ b/homeassistant/components/zwave_js/config_flow.py @@ -89,7 +89,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self, user_input: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """Handle the initial step.""" - assert self.hass # typing if is_hassio(self.hass): # type: ignore # no-untyped-call return await self.async_step_on_supervisor() @@ -266,7 +265,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self, user_input: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """Start Z-Wave JS add-on.""" - assert self.hass if not self.start_task: self.start_task = self.hass.async_create_task(self._async_start_addon()) return self.async_show_progress( @@ -289,7 +287,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): async def _async_start_addon(self) -> None: """Start the Z-Wave JS add-on.""" - assert self.hass addon_manager: AddonManager = get_addon_manager(self.hass) try: await addon_manager.async_schedule_start_addon() @@ -327,7 +324,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): Get add-on discovery info and server version info. Set unique id and abort if already configured. """ - assert self.hass if not self.ws_address: discovery_info = await self._async_get_addon_discovery_info() self.ws_address = f"ws://{discovery_info['host']}:{discovery_info['port']}" diff --git a/homeassistant/components/zwave_js/entity.py b/homeassistant/components/zwave_js/entity.py index 7620323d940..34b5940bfea 100644 --- a/homeassistant/components/zwave_js/entity.py +++ b/homeassistant/components/zwave_js/entity.py @@ -46,7 +46,6 @@ class ZWaveBaseEntity(Entity): async def async_poll_value(self, refresh_all_values: bool) -> None: """Poll a value.""" - assert self.hass if not refresh_all_values: self.hass.async_create_task( self.info.node.async_poll_value(self.info.primary_value) @@ -75,7 +74,6 @@ class ZWaveBaseEntity(Entity): async def async_added_to_hass(self) -> None: """Call when entity is added.""" - assert self.hass # typing # Add value_changed callbacks. self.async_on_remove( self.info.node.on(EVENT_VALUE_UPDATED, self._value_changed) diff --git a/homeassistant/helpers/config_entry_flow.py b/homeassistant/helpers/config_entry_flow.py index 69248186b53..fea188ca336 100644 --- a/homeassistant/helpers/config_entry_flow.py +++ b/homeassistant/helpers/config_entry_flow.py @@ -59,7 +59,6 @@ class DiscoveryFlowHandler(config_entries.ConfigFlow): return self.async_abort(reason="no_devices_found") # Cancel the discovered one. - assert self.hass is not None for flow in in_progress: self.hass.config_entries.flow.async_abort(flow["flow_id"]) @@ -91,7 +90,6 @@ class DiscoveryFlowHandler(config_entries.ConfigFlow): return self.async_abort(reason="single_instance_allowed") # Cancel other flows. - assert self.hass is not None in_progress = self._async_in_progress() for flow in in_progress: self.hass.config_entries.flow.async_abort(flow["flow_id"]) @@ -144,7 +142,6 @@ class WebhookFlowHandler(config_entries.ConfigFlow): if user_input is None: return self.async_show_form(step_id="user") - assert self.hass is not None webhook_id = self.hass.components.webhook.async_generate_id() if ( diff --git a/homeassistant/helpers/config_entry_oauth2_flow.py b/homeassistant/helpers/config_entry_oauth2_flow.py index 653d07a333e..691715452ea 100644 --- a/homeassistant/helpers/config_entry_oauth2_flow.py +++ b/homeassistant/helpers/config_entry_oauth2_flow.py @@ -234,7 +234,6 @@ class AbstractOAuth2FlowHandler(config_entries.ConfigFlow, metaclass=ABCMeta): self, user_input: Optional[dict] = None ) -> dict: """Handle a flow start.""" - assert self.hass implementations = await async_get_implementations(self.hass, self.DOMAIN) if user_input is not None: @@ -318,7 +317,6 @@ class AbstractOAuth2FlowHandler(config_entries.ConfigFlow, metaclass=ABCMeta): """Handle a flow initialized by discovery.""" await self.async_set_unique_id(self.DOMAIN) - assert self.hass is not None if self.hass.config_entries.async_entries(self.DOMAIN): return self.async_abort(reason="already_configured") diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 7afe1b2ad25..791b1e251cd 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -89,10 +89,13 @@ class Entity(ABC): # SAFE TO OVERWRITE # The properties and methods here are safe to overwrite when inheriting # this class. These may be used to customize the behavior of the entity. - entity_id = None # type: str + entity_id: str = None # type: ignore # Owning hass instance. Will be set by EntityPlatform - hass: Optional[HomeAssistant] = None + # While not purely typed, it makes typehinting more useful for us + # and removes the need for constant None checks or asserts. + # Ignore types: https://github.com/PyCQA/pylint/issues/3167 + hass: HomeAssistant = None # type: ignore # Owning platform instance. Will be set by EntityPlatform platform: Optional[EntityPlatform] = None @@ -391,7 +394,6 @@ class Entity(ABC): ) # Overwrite properties that have been set in the config file. - assert self.hass is not None if DATA_CUSTOMIZE in self.hass.data: attr.update(self.hass.data[DATA_CUSTOMIZE].get(self.entity_id)) @@ -432,7 +434,6 @@ class Entity(ABC): If state is changed more than once before the ha state change task has been executed, the intermediate state transitions will be missed. """ - assert self.hass is not None self.hass.add_job(self.async_update_ha_state(force_refresh)) # type: ignore @callback @@ -448,7 +449,6 @@ class Entity(ABC): been executed, the intermediate state transitions will be missed. """ if force_refresh: - assert self.hass is not None self.hass.async_create_task(self.async_update_ha_state(force_refresh)) else: self.async_write_ha_state() @@ -532,7 +532,7 @@ class Entity(ABC): @callback def add_to_platform_abort(self) -> None: """Abort adding an entity to a platform.""" - self.hass = None + self.hass = None # type: ignore self.platform = None self.parallel_updates = None self._added = False @@ -553,8 +553,6 @@ class Entity(ABC): If the entity doesn't have a non disabled entry in the entity registry, or if force_remove=True, its state will be removed. """ - assert self.hass is not None - if self.platform and not self._added: raise HomeAssistantError( f"Entity {self.entity_id} async_remove called twice" @@ -597,8 +595,6 @@ class Entity(ABC): Not to be extended by integrations. """ - assert self.hass is not None - if self.platform: info = {"domain": self.platform.platform_name} @@ -628,7 +624,6 @@ class Entity(ABC): Not to be extended by integrations. """ if self.platform: - assert self.hass is not None self.hass.data[DATA_ENTITY_SOURCE].pop(self.entity_id) async def _async_registry_updated(self, event: Event) -> None: @@ -642,7 +637,6 @@ class Entity(ABC): if data["action"] != "update": return - assert self.hass is not None ent_reg = await self.hass.helpers.entity_registry.async_get_registry() old = self.registry_entry self.registry_entry = ent_reg.async_get(data["entity_id"]) @@ -717,7 +711,6 @@ class ToggleEntity(Entity): async def async_turn_on(self, **kwargs: Any) -> None: """Turn the entity on.""" - assert self.hass is not None await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs)) def turn_off(self, **kwargs: Any) -> None: @@ -726,7 +719,6 @@ class ToggleEntity(Entity): async def async_turn_off(self, **kwargs: Any) -> None: """Turn the entity off.""" - assert self.hass is not None await self.hass.async_add_executor_job(ft.partial(self.turn_off, **kwargs)) def toggle(self, **kwargs: Any) -> None: diff --git a/homeassistant/helpers/restore_state.py b/homeassistant/helpers/restore_state.py index 4f738887ce3..51ebc6fa774 100644 --- a/homeassistant/helpers/restore_state.py +++ b/homeassistant/helpers/restore_state.py @@ -235,7 +235,6 @@ class RestoreEntity(Entity): async def async_internal_added_to_hass(self) -> None: """Register this entity as a restorable entity.""" - assert self.hass is not None _, data = await asyncio.gather( super().async_internal_added_to_hass(), RestoreStateData.async_get_instance(self.hass), @@ -244,7 +243,6 @@ class RestoreEntity(Entity): async def async_internal_will_remove_from_hass(self) -> None: """Run when entity will be removed from hass.""" - assert self.hass is not None _, data = await asyncio.gather( super().async_internal_will_remove_from_hass(), RestoreStateData.async_get_instance(self.hass), @@ -255,7 +253,7 @@ class RestoreEntity(Entity): """Get the entity state from the previous run.""" 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") + _LOGGER.warning("Cannot get last state. Entity not added to hass") # type: ignore[unreachable] return None data = await RestoreStateData.async_get_instance(self.hass) if self.entity_id not in data.last_states: diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 8b3f6ec6e59..7f768354035 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -425,8 +425,6 @@ class Template: This method must be run in the event loop. """ - assert self.hass - if self.is_static: return False