From a46b38d648e5f628e04c7a022ae024b0321b7947 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 28 Apr 2022 20:51:21 +0200 Subject: [PATCH] Type androidtv error decorator (#70976) --- .../components/androidtv/media_player.py | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/androidtv/media_player.py b/homeassistant/components/androidtv/media_player.py index d2a0b97ed6b..0d43ada7bc0 100644 --- a/homeassistant/components/androidtv/media_player.py +++ b/homeassistant/components/androidtv/media_player.py @@ -1,9 +1,11 @@ """Support for functionality to interact with Android TV / Fire TV devices.""" from __future__ import annotations +from collections.abc import Awaitable, Callable, Coroutine from datetime import datetime import functools import logging +from typing import Any, TypeVar from adb_shell.exceptions import ( AdbTimeoutError, @@ -14,6 +16,7 @@ from adb_shell.exceptions import ( ) from androidtv.constants import APPS, KEYS from androidtv.exceptions import LockNotAcquiredException +from typing_extensions import Concatenate, ParamSpec import voluptuous as vol from homeassistant.components import persistent_notification @@ -61,6 +64,10 @@ from .const import ( SIGNAL_CONFIG_ENTITY, ) +_ADBDeviceT = TypeVar("_ADBDeviceT", bound="ADBDevice") +_R = TypeVar("_R") +_P = ParamSpec("_P") + _LOGGER = logging.getLogger(__name__) ATTR_ADB_RESPONSE = "adb_response" @@ -144,18 +151,27 @@ async def async_setup_entry( ) -def adb_decorator(override_available=False): +def adb_decorator( + override_available: bool = False, +) -> Callable[ + [Callable[Concatenate[_ADBDeviceT, _P], Awaitable[_R]]], + Callable[Concatenate[_ADBDeviceT, _P], Coroutine[Any, Any, _R | None]], +]: """Wrap ADB methods and catch exceptions. Allows for overriding the available status of the ADB connection via the `override_available` parameter. """ - def _adb_decorator(func): + def _adb_decorator( + func: Callable[Concatenate[_ADBDeviceT, _P], Awaitable[_R]] + ) -> Callable[Concatenate[_ADBDeviceT, _P], Coroutine[Any, Any, _R | None]]: """Wrap the provided ADB method and catch exceptions.""" @functools.wraps(func) - async def _adb_exception_catcher(self, *args, **kwargs): + async def _adb_exception_catcher( + self: _ADBDeviceT, *args: _P.args, **kwargs: _P.kwargs + ) -> _R | None: """Call an ADB-related method and catch exceptions.""" # pylint: disable=protected-access if not self.available and not override_available: @@ -168,7 +184,7 @@ def adb_decorator(override_available=False): _LOGGER.info( "ADB command not executed because the connection is currently in use" ) - return + return None except self.exceptions as err: _LOGGER.error( "Failed to execute an ADB command. ADB connection re-"