Skip to content

Commit

Permalink
Add more type hints to helpers (home-assistant#18350)
Browse files Browse the repository at this point in the history
* Add type hints to helpers.entityfilter

* Add type hints to helpers.deprecation
  • Loading branch information
scop authored and balloob committed Nov 11, 2018
1 parent b8c06ad commit 9411fca
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 16 deletions.
13 changes: 7 additions & 6 deletions homeassistant/helpers/deprecation.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
"""Deprecation helpers for Home Assistant."""
import inspect
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.
When a property is added to replace an older property, this decorator can
be added to the new property, listing the old property as the substitute.
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.
"""
def decorator(func):
def decorator(func: Callable) -> Callable:
"""Decorate function as deprecated."""
def func_wrapper(self):
def func_wrapper(self: Callable) -> Any:
"""Wrap for the original function."""
if hasattr(self, substitute_name):
# If this platform is still using the old property, issue
Expand All @@ -28,8 +29,7 @@ def func_wrapper(self):
substitute_name, substitute_name, func.__name__,
inspect.getfile(self.__class__))
warnings[module_name] = True
# pylint: disable=protected-access
func._deprecated_substitute_warnings = warnings
setattr(func, '_deprecated_substitute_warnings', warnings)

# Return the old property
return getattr(self, substitute_name)
Expand All @@ -38,7 +38,8 @@ def func_wrapper(self):
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.
If the new config isn't found, but the old one is, the old value is used
Expand Down
21 changes: 12 additions & 9 deletions homeassistant/helpers/entityfilter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Helper class to implement include/exclude of entities and domains."""
from typing import Callable, Dict, Iterable

import voluptuous as vol

Expand All @@ -11,14 +12,14 @@
CONF_EXCLUDE_ENTITIES = 'exclude_entities'


def _convert_filter(config):
def _convert_filter(config: Dict[str, Iterable[str]]) -> Callable[[str], bool]:
filt = generate_filter(
config[CONF_INCLUDE_DOMAINS],
config[CONF_INCLUDE_ENTITIES],
config[CONF_EXCLUDE_DOMAINS],
config[CONF_EXCLUDE_ENTITIES],
)
filt.config = config
setattr(filt, 'config', config)
return filt


Expand All @@ -33,8 +34,10 @@ def _convert_filter(config):
}), _convert_filter)


def generate_filter(include_domains, include_entities,
exclude_domains, exclude_entities):
def generate_filter(include_domains: Iterable[str],
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."""
include_d = set(include_domains)
include_e = set(include_entities)
Expand All @@ -50,7 +53,7 @@ def generate_filter(include_domains, include_entities,

# Case 2 - includes, no excludes - only include specified entities
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."""
domain = split_entity_id(entity_id)[0]
return (entity_id in include_e or
Expand All @@ -60,7 +63,7 @@ def entity_filter_2(entity_id):

# Case 3 - excludes, no includes - only exclude specified entities
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."""
domain = split_entity_id(entity_id)[0]
return (entity_id not in exclude_e and
Expand All @@ -75,7 +78,7 @@ def entity_filter_3(entity_id):
# note: if both include and exclude domains specified,
# the exclude domains are ignored
if include_d:
def entity_filter_4a(entity_id):
def entity_filter_4a(entity_id: str) -> bool:
"""Return filter function for case 4a."""
domain = split_entity_id(entity_id)[0]
if domain in include_d:
Expand All @@ -88,7 +91,7 @@ def entity_filter_4a(entity_id):
# - if domain is excluded, pass if entity is included
# - if domain is not excluded, pass if entity not excluded
if exclude_d:
def entity_filter_4b(entity_id):
def entity_filter_4b(entity_id: str) -> bool:
"""Return filter function for case 4b."""
domain = split_entity_id(entity_id)[0]
if domain in exclude_d:
Expand All @@ -99,7 +102,7 @@ def entity_filter_4b(entity_id):

# Case 4c - neither include or exclude domain specified
# - 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 entity_id in include_e

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ whitelist_externals=/bin/bash
deps =
-r{toxinidir}/requirements_test.txt
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'

0 comments on commit 9411fca

Please sign in to comment.