diff --git a/homeassistant/components/aprs/device_tracker.py b/homeassistant/components/aprs/device_tracker.py index 6bae9ce6ebe..b1467a6d2e4 100644 --- a/homeassistant/components/aprs/device_tracker.py +++ b/homeassistant/components/aprs/device_tracker.py @@ -1,7 +1,6 @@ """Support for APRS device tracking.""" from __future__ import annotations -from collections.abc import Callable import logging import threading @@ -12,6 +11,7 @@ import voluptuous as vol from homeassistant.components.device_tracker import ( PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, + SeeCallback, ) from homeassistant.const import ( ATTR_GPS_ACCURACY, @@ -87,7 +87,7 @@ def gps_accuracy(gps, posambiguity: int) -> int: def setup_scanner( hass: HomeAssistant, config: ConfigType, - see: Callable[..., None], + see: SeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the APRS tracker.""" @@ -123,8 +123,13 @@ class AprsListenerThread(threading.Thread): """APRS message listener.""" def __init__( - self, callsign: str, password: str, host: str, server_filter: str, see - ): + self, + callsign: str, + password: str, + host: str, + server_filter: str, + see: SeeCallback, + ) -> None: """Initialize the class.""" super().__init__() diff --git a/homeassistant/components/bluetooth_le_tracker/device_tracker.py b/homeassistant/components/bluetooth_le_tracker/device_tracker.py index f85cc2bad0a..a650e65b8f2 100644 --- a/homeassistant/components/bluetooth_le_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_le_tracker/device_tracker.py @@ -2,7 +2,6 @@ from __future__ import annotations import asyncio -from collections.abc import Awaitable, Callable from datetime import datetime, timedelta import logging from uuid import UUID @@ -22,6 +21,7 @@ from homeassistant.components.device_tracker.const import ( ) from homeassistant.components.device_tracker.legacy import ( YAML_DEVICES, + AsyncSeeCallback, async_load_config, ) from homeassistant.const import CONF_SCAN_INTERVAL, EVENT_HOMEASSISTANT_STOP @@ -57,7 +57,7 @@ PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( async def async_setup_scanner( # noqa: C901 hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the Bluetooth LE Scanner.""" diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index b62333c0489..90ae473a0cd 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -2,7 +2,7 @@ from __future__ import annotations import asyncio -from collections.abc import Awaitable, Callable +from collections.abc import Awaitable from datetime import datetime, timedelta import logging from typing import Final @@ -23,6 +23,7 @@ from homeassistant.components.device_tracker.const import ( ) from homeassistant.components.device_tracker.legacy import ( YAML_DEVICES, + AsyncSeeCallback, Device, async_load_config, ) @@ -78,7 +79,7 @@ def discover_devices(device_id: int) -> list[tuple[str, str]]: async def see_device( hass: HomeAssistant, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, mac: str, device_name: str, rssi: tuple[int] | None = None, @@ -130,7 +131,7 @@ def lookup_name(mac: str) -> str | None: async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the Bluetooth Scanner.""" diff --git a/homeassistant/components/demo/device_tracker.py b/homeassistant/components/demo/device_tracker.py index 74122932337..dacbd95219b 100644 --- a/homeassistant/components/demo/device_tracker.py +++ b/homeassistant/components/demo/device_tracker.py @@ -1,9 +1,9 @@ """Demo platform for the Device tracker component.""" from __future__ import annotations -from collections.abc import Callable import random +from homeassistant.components.device_tracker import SeeCallback from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -13,7 +13,7 @@ from .const import DOMAIN, SERVICE_RANDOMIZE_DEVICE_TRACKER_DATA def setup_scanner( hass: HomeAssistant, config: ConfigType, - see: Callable[..., None], + see: SeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the demo tracker.""" @@ -42,7 +42,7 @@ def setup_scanner( see( dev_id="demo_home_boy", host_name="Home Boy", - gps=[hass.config.latitude - 0.00002, hass.config.longitude + 0.00002], + gps=(hass.config.latitude - 0.00002, hass.config.longitude + 0.00002), gps_accuracy=20, battery=53, ) diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index e9222156b00..5617d56ac3f 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -33,7 +33,9 @@ from .legacy import ( # noqa: F401 SERVICE_SEE, SERVICE_SEE_PAYLOAD_SCHEMA, SOURCE_TYPES, + AsyncSeeCallback, DeviceScanner, + SeeCallback, async_setup_integration as async_setup_legacy_integration, see, ) diff --git a/homeassistant/components/device_tracker/legacy.py b/homeassistant/components/device_tracker/legacy.py index 87026fc32ff..d8097a68ad5 100644 --- a/homeassistant/components/device_tracker/legacy.py +++ b/homeassistant/components/device_tracker/legacy.py @@ -6,7 +6,7 @@ from collections.abc import Callable, Coroutine, Sequence from datetime import datetime, timedelta import hashlib from types import ModuleType -from typing import Any, Final, final +from typing import Any, Final, Protocol, final import attr import voluptuous as vol @@ -124,6 +124,48 @@ YAML_DEVICES: Final = "known_devices.yaml" EVENT_NEW_DEVICE: Final = "device_tracker_new_device" +class SeeCallback(Protocol): + """Protocol type for DeviceTracker.see callback.""" + + def __call__( + self, + mac: str | None = None, + dev_id: str | None = None, + host_name: str | None = None, + location_name: str | None = None, + gps: GPSType | None = None, + gps_accuracy: int | None = None, + battery: int | None = None, + attributes: dict[str, Any] | None = None, + source_type: str = SOURCE_TYPE_GPS, + picture: str | None = None, + icon: str | None = None, + consider_home: timedelta | None = None, + ) -> None: + """Define see type.""" + + +class AsyncSeeCallback(Protocol): + """Protocol type for DeviceTracker.async_see callback.""" + + async def __call__( + self, + mac: str | None = None, + dev_id: str | None = None, + host_name: str | None = None, + location_name: str | None = None, + gps: GPSType | None = None, + gps_accuracy: int | None = None, + battery: int | None = None, + attributes: dict[str, Any] | None = None, + source_type: str = SOURCE_TYPE_GPS, + picture: str | None = None, + icon: str | None = None, + consider_home: timedelta | None = None, + ) -> None: + """Define async_see type.""" + + def see( hass: HomeAssistant, mac: str | None = None, @@ -133,7 +175,7 @@ def see( gps: GPSType | None = None, gps_accuracy: int | None = None, battery: int | None = None, - attributes: dict | None = None, + attributes: dict[str, Any] | None = None, ) -> None: """Call service to notify you see device.""" data: dict[str, Any] = { @@ -447,7 +489,7 @@ class DeviceTracker: gps: GPSType | None = None, gps_accuracy: int | None = None, battery: int | None = None, - attributes: dict | None = None, + attributes: dict[str, Any] | None = None, source_type: str = SOURCE_TYPE_GPS, picture: str | None = None, icon: str | None = None, @@ -480,7 +522,7 @@ class DeviceTracker: gps: GPSType | None = None, gps_accuracy: int | None = None, battery: int | None = None, - attributes: dict | None = None, + attributes: dict[str, Any] | None = None, source_type: str = SOURCE_TYPE_GPS, picture: str | None = None, icon: str | None = None, diff --git a/homeassistant/components/fleetgo/device_tracker.py b/homeassistant/components/fleetgo/device_tracker.py index bfafb5561d7..e80acae8627 100644 --- a/homeassistant/components/fleetgo/device_tracker.py +++ b/homeassistant/components/fleetgo/device_tracker.py @@ -1,7 +1,6 @@ """Support for FleetGO Platform.""" from __future__ import annotations -from collections.abc import Callable import logging import requests @@ -10,6 +9,7 @@ import voluptuous as vol from homeassistant.components.device_tracker import ( PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, + SeeCallback, ) from homeassistant.const import ( CONF_CLIENT_ID, @@ -39,7 +39,7 @@ PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( def setup_scanner( hass: HomeAssistant, config: ConfigType, - see: Callable[..., None], + see: SeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the DeviceScanner and check if login is valid.""" @@ -53,7 +53,7 @@ def setup_scanner( class FleetGoDeviceScanner: """Define a scanner for the FleetGO platform.""" - def __init__(self, config, see): + def __init__(self, config, see: SeeCallback): """Initialize FleetGoDeviceScanner.""" self._include = config.get(CONF_INCLUDE) self._see = see diff --git a/homeassistant/components/google_maps/device_tracker.py b/homeassistant/components/google_maps/device_tracker.py index 62627c2e905..8d8be8c0fe1 100644 --- a/homeassistant/components/google_maps/device_tracker.py +++ b/homeassistant/components/google_maps/device_tracker.py @@ -1,7 +1,6 @@ """Support for Google Maps location sharing.""" from __future__ import annotations -from collections.abc import Callable from datetime import timedelta import logging @@ -12,6 +11,7 @@ import voluptuous as vol from homeassistant.components.device_tracker import ( PLATFORM_SCHEMA as PLATFORM_SCHEMA_BASE, SOURCE_TYPE_GPS, + SeeCallback, ) from homeassistant.const import ( ATTR_BATTERY_CHARGING, @@ -50,7 +50,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA_BASE.extend( def setup_scanner( hass: HomeAssistant, config: ConfigType, - see: Callable[..., None], + see: SeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the Google Maps Location sharing scanner.""" @@ -61,7 +61,7 @@ def setup_scanner( class GoogleMapsScanner: """Representation of an Google Maps location sharing account.""" - def __init__(self, hass, config: ConfigType, see) -> None: + def __init__(self, hass, config: ConfigType, see: SeeCallback) -> None: """Initialize the scanner.""" self.see = see self.username = config[CONF_USERNAME] diff --git a/homeassistant/components/icloud/device_tracker.py b/homeassistant/components/icloud/device_tracker.py index 9c2004f0edb..ec543a9ed30 100644 --- a/homeassistant/components/icloud/device_tracker.py +++ b/homeassistant/components/icloud/device_tracker.py @@ -1,10 +1,9 @@ """Support for tracking for iCloud devices.""" from __future__ import annotations -from collections.abc import Awaitable, Callable from typing import Any -from homeassistant.components.device_tracker import SOURCE_TYPE_GPS +from homeassistant.components.device_tracker import SOURCE_TYPE_GPS, AsyncSeeCallback from homeassistant.components.device_tracker.config_entry import TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback @@ -25,7 +24,7 @@ from .const import ( async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Old way of setting up the iCloud tracker.""" diff --git a/homeassistant/components/meraki/device_tracker.py b/homeassistant/components/meraki/device_tracker.py index 86c9ecf95fb..7447d8ce879 100644 --- a/homeassistant/components/meraki/device_tracker.py +++ b/homeassistant/components/meraki/device_tracker.py @@ -1,7 +1,6 @@ """Support for the Meraki CMX location service.""" from __future__ import annotations -from collections.abc import Awaitable, Callable from http import HTTPStatus import json import logging @@ -11,6 +10,7 @@ import voluptuous as vol from homeassistant.components.device_tracker import ( PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, SOURCE_TYPE_ROUTER, + AsyncSeeCallback, ) from homeassistant.components.http import HomeAssistantView from homeassistant.core import HomeAssistant, callback @@ -34,7 +34,7 @@ PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up an endpoint for the Meraki tracker.""" @@ -50,7 +50,7 @@ class MerakiView(HomeAssistantView): name = "api:meraki" requires_auth = False - def __init__(self, config, async_see): + def __init__(self, config: ConfigType, async_see: AsyncSeeCallback) -> None: """Initialize Meraki URL endpoints.""" self.async_see = async_see self.validator = config[CONF_VALIDATOR] diff --git a/homeassistant/components/mqtt_json/device_tracker.py b/homeassistant/components/mqtt_json/device_tracker.py index 1d99e6d7b6f..f0330e39e86 100644 --- a/homeassistant/components/mqtt_json/device_tracker.py +++ b/homeassistant/components/mqtt_json/device_tracker.py @@ -1,7 +1,6 @@ """Support for GPS tracking MQTT enabled devices.""" from __future__ import annotations -from collections.abc import Awaitable, Callable import json import logging @@ -10,6 +9,7 @@ import voluptuous as vol from homeassistant.components import mqtt from homeassistant.components.device_tracker import ( PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, + AsyncSeeCallback, ) from homeassistant.components.mqtt import CONF_QOS from homeassistant.const import ( @@ -43,7 +43,7 @@ PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend(mqtt.config.SCHEMA_BASE).extend( async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the MQTT JSON tracker.""" diff --git a/homeassistant/components/mysensors/device_tracker.py b/homeassistant/components/mysensors/device_tracker.py index d5332ab70bf..3c204776b7d 100644 --- a/homeassistant/components/mysensors/device_tracker.py +++ b/homeassistant/components/mysensors/device_tracker.py @@ -1,10 +1,10 @@ """Support for tracking MySensors devices.""" from __future__ import annotations -from collections.abc import Awaitable, Callable from typing import Any, cast from homeassistant.components import mysensors +from homeassistant.components.device_tracker import AsyncSeeCallback from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -18,7 +18,7 @@ from .helpers import on_unload async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the MySensors device scanner.""" @@ -63,7 +63,12 @@ async def async_setup_scanner( class MySensorsDeviceScanner(mysensors.device.MySensorsDevice): """Represent a MySensors scanner.""" - def __init__(self, hass: HomeAssistant, async_see: Callable, *args: Any) -> None: + def __init__( + self, + hass: HomeAssistant, + async_see: AsyncSeeCallback, + *args: Any, + ) -> None: """Set up instance.""" super().__init__(*args) self.async_see = async_see diff --git a/homeassistant/components/ping/device_tracker.py b/homeassistant/components/ping/device_tracker.py index 0a0e397e6d8..cbce224a373 100644 --- a/homeassistant/components/ping/device_tracker.py +++ b/homeassistant/components/ping/device_tracker.py @@ -2,7 +2,6 @@ from __future__ import annotations import asyncio -from collections.abc import Awaitable, Callable from datetime import timedelta import logging import subprocess @@ -13,6 +12,7 @@ import voluptuous as vol from homeassistant import const, util from homeassistant.components.device_tracker import ( PLATFORM_SCHEMA as BASE_PLATFORM_SCHEMA, + AsyncSeeCallback, ) from homeassistant.components.device_tracker.const import ( CONF_SCAN_INTERVAL, @@ -83,7 +83,7 @@ class HostSubProcess: async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the Host objects and return the update function.""" diff --git a/homeassistant/components/tile/device_tracker.py b/homeassistant/components/tile/device_tracker.py index 61e9a1bdcd9..492c202df08 100644 --- a/homeassistant/components/tile/device_tracker.py +++ b/homeassistant/components/tile/device_tracker.py @@ -1,11 +1,11 @@ """Support for Tile device trackers.""" from __future__ import annotations -from collections.abc import Awaitable, Callable import logging from pytile.tile import Tile +from homeassistant.components.device_tracker import AsyncSeeCallback from homeassistant.components.device_tracker.config_entry import TrackerEntity from homeassistant.components.device_tracker.const import SOURCE_TYPE_GPS from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry @@ -52,7 +52,7 @@ async def async_setup_entry( async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Detect a legacy configuration and import it.""" diff --git a/homeassistant/components/traccar/device_tracker.py b/homeassistant/components/traccar/device_tracker.py index 970cd20d640..f9676d37aa2 100644 --- a/homeassistant/components/traccar/device_tracker.py +++ b/homeassistant/components/traccar/device_tracker.py @@ -2,7 +2,6 @@ from __future__ import annotations import asyncio -from collections.abc import Awaitable, Callable from datetime import datetime, timedelta import logging @@ -21,6 +20,7 @@ from homeassistant.components.device_tracker import ( CONF_SCAN_INTERVAL, PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, SOURCE_TYPE_GPS, + AsyncSeeCallback, ) from homeassistant.components.device_tracker.config_entry import TrackerEntity from homeassistant.config_entries import ConfigEntry @@ -174,7 +174,7 @@ async def async_setup_entry( async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Validate the configuration and return a Traccar scanner.""" @@ -208,7 +208,7 @@ class TraccarScanner: self, api: ApiClient, hass: HomeAssistant, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, scan_interval: timedelta, max_accuracy: int, skip_accuracy_on: bool, diff --git a/homeassistant/components/volvooncall/device_tracker.py b/homeassistant/components/volvooncall/device_tracker.py index 74a88fb69ab..866634fc5e1 100644 --- a/homeassistant/components/volvooncall/device_tracker.py +++ b/homeassistant/components/volvooncall/device_tracker.py @@ -1,9 +1,7 @@ """Support for tracking a Volvo.""" from __future__ import annotations -from collections.abc import Awaitable, Callable - -from homeassistant.components.device_tracker import SOURCE_TYPE_GPS +from homeassistant.components.device_tracker import SOURCE_TYPE_GPS, AsyncSeeCallback from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -15,7 +13,7 @@ from . import DATA_KEY, SIGNAL_STATE_UPDATED async def async_setup_scanner( hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: """Set up the Volvo tracker.""" @@ -26,7 +24,7 @@ async def async_setup_scanner( data = hass.data[DATA_KEY] instrument = data.instrument(vin, component, attr, slug_attr) - async def see_vehicle(): + async def see_vehicle() -> None: """Handle the reporting of the vehicle position.""" host_name = instrument.vehicle_name dev_id = f"volvo_{slugify(host_name)}" diff --git a/pylint/plugins/hass_enforce_type_hints.py b/pylint/plugins/hass_enforce_type_hints.py index 680d25414aa..3b50c072eb6 100644 --- a/pylint/plugins/hass_enforce_type_hints.py +++ b/pylint/plugins/hass_enforce_type_hints.py @@ -293,7 +293,7 @@ _FUNCTION_MATCH: dict[str, list[TypeHintMatch]] = { arg_types={ 0: "HomeAssistant", 1: "ConfigType", - 2: "Callable[..., None]", + 2: "SeeCallback", 3: "DiscoveryInfoType | None", }, return_type="bool", @@ -303,7 +303,7 @@ _FUNCTION_MATCH: dict[str, list[TypeHintMatch]] = { arg_types={ 0: "HomeAssistant", 1: "ConfigType", - 2: "Callable[..., Awaitable[None]]", + 2: "AsyncSeeCallback", 3: "DiscoveryInfoType | None", }, return_type="bool", diff --git a/tests/pylint/test_enforce_type_hints.py b/tests/pylint/test_enforce_type_hints.py index e549d21fe0f..54824e5c0b0 100644 --- a/tests/pylint/test_enforce_type_hints.py +++ b/tests/pylint/test_enforce_type_hints.py @@ -201,7 +201,7 @@ def test_invalid_discovery_info( async def async_setup_scanner( #@ hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: dict[str, Any] | None = None, #@ ) -> bool: pass @@ -234,7 +234,7 @@ def test_valid_discovery_info( async def async_setup_scanner( #@ hass: HomeAssistant, config: ConfigType, - async_see: Callable[..., Awaitable[None]], + async_see: AsyncSeeCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: pass