Add more type hints to helpers (#18350)

* Add type hints to helpers.entityfilter

* Add type hints to helpers.deprecation
This commit is contained in:
Ville Skyttä 2018-11-11 18:39:50 +02:00 committed by Paulus Schoutsen
parent b8c06ad019
commit 9411fca955
3 changed files with 20 additions and 16 deletions

View File

@ -1,9 +1,10 @@
"""Deprecation helpers for Home Assistant.""" """Deprecation helpers for Home Assistant."""
import inspect import inspect
import logging import logging
from typing import Any, Callable, Dict, Optional
def deprecated_substitute(substitute_name): def deprecated_substitute(substitute_name: str) -> Callable[..., Callable]:
"""Help migrate properties to new names. """Help migrate properties to new names.
When a property is added to replace an older property, this decorator can When a property is added to replace an older property, this decorator can
@ -11,9 +12,9 @@ def deprecated_substitute(substitute_name):
If the old property is defined, its value will be used instead, and a log If the old property is defined, its value will be used instead, and a log
warning will be issued alerting the user of the impending change. warning will be issued alerting the user of the impending change.
""" """
def decorator(func): def decorator(func: Callable) -> Callable:
"""Decorate function as deprecated.""" """Decorate function as deprecated."""
def func_wrapper(self): def func_wrapper(self: Callable) -> Any:
"""Wrap for the original function.""" """Wrap for the original function."""
if hasattr(self, substitute_name): if hasattr(self, substitute_name):
# If this platform is still using the old property, issue # If this platform is still using the old property, issue
@ -28,8 +29,7 @@ def deprecated_substitute(substitute_name):
substitute_name, substitute_name, func.__name__, substitute_name, substitute_name, func.__name__,
inspect.getfile(self.__class__)) inspect.getfile(self.__class__))
warnings[module_name] = True warnings[module_name] = True
# pylint: disable=protected-access setattr(func, '_deprecated_substitute_warnings', warnings)
func._deprecated_substitute_warnings = warnings
# Return the old property # Return the old property
return getattr(self, substitute_name) return getattr(self, substitute_name)
@ -38,7 +38,8 @@ def deprecated_substitute(substitute_name):
return decorator return decorator
def get_deprecated(config, new_name, old_name, default=None): def get_deprecated(config: Dict[str, Any], new_name: str, old_name: str,
default: Optional[Any] = None) -> Optional[Any]:
"""Allow an old config name to be deprecated with a replacement. """Allow an old config name to be deprecated with a replacement.
If the new config isn't found, but the old one is, the old value is used If the new config isn't found, but the old one is, the old value is used

View File

@ -1,4 +1,5 @@
"""Helper class to implement include/exclude of entities and domains.""" """Helper class to implement include/exclude of entities and domains."""
from typing import Callable, Dict, Iterable
import voluptuous as vol import voluptuous as vol
@ -11,14 +12,14 @@ CONF_EXCLUDE_DOMAINS = 'exclude_domains'
CONF_EXCLUDE_ENTITIES = 'exclude_entities' CONF_EXCLUDE_ENTITIES = 'exclude_entities'
def _convert_filter(config): def _convert_filter(config: Dict[str, Iterable[str]]) -> Callable[[str], bool]:
filt = generate_filter( filt = generate_filter(
config[CONF_INCLUDE_DOMAINS], config[CONF_INCLUDE_DOMAINS],
config[CONF_INCLUDE_ENTITIES], config[CONF_INCLUDE_ENTITIES],
config[CONF_EXCLUDE_DOMAINS], config[CONF_EXCLUDE_DOMAINS],
config[CONF_EXCLUDE_ENTITIES], config[CONF_EXCLUDE_ENTITIES],
) )
filt.config = config setattr(filt, 'config', config)
return filt return filt
@ -33,8 +34,10 @@ FILTER_SCHEMA = vol.All(
}), _convert_filter) }), _convert_filter)
def generate_filter(include_domains, include_entities, def generate_filter(include_domains: Iterable[str],
exclude_domains, exclude_entities): include_entities: Iterable[str],
exclude_domains: Iterable[str],
exclude_entities: Iterable[str]) -> Callable[[str], bool]:
"""Return a function that will filter entities based on the args.""" """Return a function that will filter entities based on the args."""
include_d = set(include_domains) include_d = set(include_domains)
include_e = set(include_entities) include_e = set(include_entities)
@ -50,7 +53,7 @@ def generate_filter(include_domains, include_entities,
# Case 2 - includes, no excludes - only include specified entities # Case 2 - includes, no excludes - only include specified entities
if have_include and not have_exclude: if have_include and not have_exclude:
def entity_filter_2(entity_id): def entity_filter_2(entity_id: str) -> bool:
"""Return filter function for case 2.""" """Return filter function for case 2."""
domain = split_entity_id(entity_id)[0] domain = split_entity_id(entity_id)[0]
return (entity_id in include_e or return (entity_id in include_e or
@ -60,7 +63,7 @@ def generate_filter(include_domains, include_entities,
# Case 3 - excludes, no includes - only exclude specified entities # Case 3 - excludes, no includes - only exclude specified entities
if not have_include and have_exclude: if not have_include and have_exclude:
def entity_filter_3(entity_id): def entity_filter_3(entity_id: str) -> bool:
"""Return filter function for case 3.""" """Return filter function for case 3."""
domain = split_entity_id(entity_id)[0] domain = split_entity_id(entity_id)[0]
return (entity_id not in exclude_e and return (entity_id not in exclude_e and
@ -75,7 +78,7 @@ def generate_filter(include_domains, include_entities,
# note: if both include and exclude domains specified, # note: if both include and exclude domains specified,
# the exclude domains are ignored # the exclude domains are ignored
if include_d: if include_d:
def entity_filter_4a(entity_id): def entity_filter_4a(entity_id: str) -> bool:
"""Return filter function for case 4a.""" """Return filter function for case 4a."""
domain = split_entity_id(entity_id)[0] domain = split_entity_id(entity_id)[0]
if domain in include_d: if domain in include_d:
@ -88,7 +91,7 @@ def generate_filter(include_domains, include_entities,
# - if domain is excluded, pass if entity is included # - if domain is excluded, pass if entity is included
# - if domain is not excluded, pass if entity not excluded # - if domain is not excluded, pass if entity not excluded
if exclude_d: if exclude_d:
def entity_filter_4b(entity_id): def entity_filter_4b(entity_id: str) -> bool:
"""Return filter function for case 4b.""" """Return filter function for case 4b."""
domain = split_entity_id(entity_id)[0] domain = split_entity_id(entity_id)[0]
if domain in exclude_d: if domain in exclude_d:
@ -99,7 +102,7 @@ def generate_filter(include_domains, include_entities,
# Case 4c - neither include or exclude domain specified # Case 4c - neither include or exclude domain specified
# - Only pass if entity is included. Ignore entity excludes. # - Only pass if entity is included. Ignore entity excludes.
def entity_filter_4c(entity_id): def entity_filter_4c(entity_id: str) -> bool:
"""Return filter function for case 4c.""" """Return filter function for case 4c."""
return entity_id in include_e return entity_id in include_e

View File

@ -60,4 +60,4 @@ whitelist_externals=/bin/bash
deps = deps =
-r{toxinidir}/requirements_test.txt -r{toxinidir}/requirements_test.txt
commands = commands =
/bin/bash -c 'mypy homeassistant/*.py homeassistant/{auth,util}/ homeassistant/helpers/{__init__,dispatcher,entity_values,icon,intent,json,location,signal,state,sun,temperature,translation,typing}.py' /bin/bash -c 'mypy homeassistant/*.py homeassistant/{auth,util}/ homeassistant/helpers/{__init__,deprecation,dispatcher,entity_values,entityfilter,icon,intent,json,location,signal,state,sun,temperature,translation,typing}.py'