diff --git a/.strict-typing b/.strict-typing index f133199a7532bc9910d48cd1e0c3ab32e5b23f41..c184990884f137bd8f753743f9c086d5bdb237fb 100644 --- a/.strict-typing +++ b/.strict-typing @@ -16,6 +16,7 @@ homeassistant.auth.providers.* homeassistant.helpers.area_registry homeassistant.helpers.condition homeassistant.helpers.debounce +homeassistant.helpers.deprecation homeassistant.helpers.discovery homeassistant.helpers.entity homeassistant.helpers.entity_values diff --git a/homeassistant/helpers/deprecation.py b/homeassistant/helpers/deprecation.py index 4bf57c1a4e128b1bb745a1b0d5c433e140dfa24f..8d961d7008bc7fc220a70455d5c70fa331d77ac8 100644 --- a/homeassistant/helpers/deprecation.py +++ b/homeassistant/helpers/deprecation.py @@ -5,12 +5,20 @@ from collections.abc import Callable import functools import inspect import logging -from typing import Any +from typing import Any, TypeVar + +from typing_extensions import ParamSpec from ..helpers.frame import MissingIntegrationFrame, get_integration_frame +_ObjectT = TypeVar("_ObjectT", bound=object) +_R = TypeVar("_R") +_P = ParamSpec("_P") + -def deprecated_substitute(substitute_name: str) -> Callable[..., Callable]: +def deprecated_substitute( + substitute_name: str, +) -> Callable[[Callable[[_ObjectT], Any]], Callable[[_ObjectT], Any]]: """Help migrate properties to new names. When a property is added to replace an older property, this decorator can @@ -19,10 +27,10 @@ def deprecated_substitute(substitute_name: str) -> Callable[..., Callable]: warning will be issued alerting the user of the impending change. """ - def decorator(func: Callable) -> Callable: + def decorator(func: Callable[[_ObjectT], Any]) -> Callable[[_ObjectT], Any]: """Decorate function as deprecated.""" - def func_wrapper(self: Callable) -> Any: + def func_wrapper(self: _ObjectT) -> Any: """Wrap for the original function.""" if hasattr(self, substitute_name): # If this platform is still using the old property, issue @@ -81,14 +89,16 @@ def get_deprecated( return config.get(new_name, default) -def deprecated_class(replacement: str) -> Any: +def deprecated_class( + replacement: str, +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: """Mark class as deprecated and provide a replacement class to be used instead.""" - def deprecated_decorator(cls: Any) -> Any: + def deprecated_decorator(cls: Callable[_P, _R]) -> Callable[_P, _R]: """Decorate class as deprecated.""" @functools.wraps(cls) - def deprecated_cls(*args: Any, **kwargs: Any) -> Any: + def deprecated_cls(*args: _P.args, **kwargs: _P.kwargs) -> _R: """Wrap for the original class.""" _print_deprecation_warning(cls, replacement, "class") return cls(*args, **kwargs) @@ -98,14 +108,16 @@ def deprecated_class(replacement: str) -> Any: return deprecated_decorator -def deprecated_function(replacement: str) -> Callable[..., Callable]: +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.""" - def deprecated_decorator(func: Callable) -> Callable: + def deprecated_decorator(func: Callable[_P, _R]) -> Callable[_P, _R]: """Decorate function as deprecated.""" @functools.wraps(func) - def deprecated_func(*args: Any, **kwargs: Any) -> Any: + def deprecated_func(*args: _P.args, **kwargs: _P.kwargs) -> _R: """Wrap for the original function.""" _print_deprecation_warning(func, replacement, "function") return func(*args, **kwargs) diff --git a/mypy.ini b/mypy.ini index 3355680069eab5f62192f4770168d12d826be89d..6321ee04b98146cc141b91708025467db24cd956 100644 --- a/mypy.ini +++ b/mypy.ini @@ -60,6 +60,9 @@ disallow_any_generics = true [mypy-homeassistant.helpers.debounce] disallow_any_generics = true +[mypy-homeassistant.helpers.deprecation] +disallow_any_generics = true + [mypy-homeassistant.helpers.discovery] disallow_any_generics = true