Type check all helpers (#25373)
* Type check all helpers, add inline exclusions for work in progress * Remove unused Script._template_cache * Add some missing type hints * Remove unneeded type: ignore * Type hint fixes * Mypy assistance tweaks * Don't look for None in deprecated config "at most once" check * Avoid None name slugify attempt when generating entity id * Avoid None state store attempt on entity remove
This commit is contained in:
parent
0653f57fb4
commit
d64f1e767c
19 changed files with 119 additions and 69 deletions
|
@ -1,6 +1,6 @@
|
||||||
"""Helper to check the configuration file."""
|
"""Helper to check the configuration file."""
|
||||||
from collections import OrderedDict, namedtuple
|
from collections import OrderedDict, namedtuple
|
||||||
# from typing import Dict, List, Sequence
|
from typing import List
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
@ -17,6 +17,9 @@ import homeassistant.util.yaml.loader as yaml_loader
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-warn-return-any
|
||||||
|
|
||||||
CheckConfigError = namedtuple(
|
CheckConfigError = namedtuple(
|
||||||
'CheckConfigError', "message domain config")
|
'CheckConfigError', "message domain config")
|
||||||
|
|
||||||
|
@ -25,7 +28,8 @@ CheckConfigError = namedtuple(
|
||||||
class HomeAssistantConfig(OrderedDict):
|
class HomeAssistantConfig(OrderedDict):
|
||||||
"""Configuration result with errors attribute."""
|
"""Configuration result with errors attribute."""
|
||||||
|
|
||||||
errors = attr.ib(default=attr.Factory(list))
|
errors = attr.ib(
|
||||||
|
default=attr.Factory(list)) # type: List[CheckConfigError]
|
||||||
|
|
||||||
def add_error(self, message, domain=None, config=None):
|
def add_error(self, message, domain=None, config=None):
|
||||||
"""Add a single error."""
|
"""Add a single error."""
|
||||||
|
@ -114,9 +118,10 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> \
|
||||||
result.add_error("Component not found: {}".format(domain))
|
result.add_error("Component not found: {}".format(domain))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if hasattr(component, 'CONFIG_SCHEMA'):
|
config_schema = getattr(component, 'CONFIG_SCHEMA', None)
|
||||||
|
if config_schema is not None:
|
||||||
try:
|
try:
|
||||||
config = component.CONFIG_SCHEMA(config)
|
config = config_schema(config)
|
||||||
result[domain] = config[domain]
|
result[domain] = config[domain]
|
||||||
except vol.Invalid as ex:
|
except vol.Invalid as ex:
|
||||||
_comp_error(ex, domain, config)
|
_comp_error(ex, domain, config)
|
||||||
|
@ -133,8 +138,7 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> \
|
||||||
for p_name, p_config in config_per_platform(config, domain):
|
for p_name, p_config in config_per_platform(config, domain):
|
||||||
# Validate component specific platform schema
|
# Validate component specific platform schema
|
||||||
try:
|
try:
|
||||||
p_validated = component_platform_schema( # type: ignore
|
p_validated = component_platform_schema(p_config)
|
||||||
p_config)
|
|
||||||
except vol.Invalid as ex:
|
except vol.Invalid as ex:
|
||||||
_comp_error(ex, domain, config)
|
_comp_error(ex, domain, config)
|
||||||
continue
|
continue
|
||||||
|
@ -163,9 +167,10 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> \
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Validate platform specific schema
|
# Validate platform specific schema
|
||||||
if hasattr(platform, 'PLATFORM_SCHEMA'):
|
platform_schema = getattr(platform, 'PLATFORM_SCHEMA', None)
|
||||||
|
if platform_schema is not None:
|
||||||
try:
|
try:
|
||||||
p_validated = platform.PLATFORM_SCHEMA(p_validated)
|
p_validated = platform_schema(p_validated)
|
||||||
except vol.Invalid as ex:
|
except vol.Invalid as ex:
|
||||||
_comp_error(
|
_comp_error(
|
||||||
ex, '{}.{}'.format(domain, p_name), p_validated)
|
ex, '{}.{}'.format(domain, p_name), p_validated)
|
||||||
|
|
|
@ -4,6 +4,8 @@ from functools import partial
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-defs
|
||||||
|
|
||||||
def register_discovery_flow(domain, title, discovery_function,
|
def register_discovery_flow(domain, title, discovery_function,
|
||||||
connection_class):
|
connection_class):
|
||||||
"""Register flow for discovered integrations that not require auth."""
|
"""Register flow for discovered integrations that not require auth."""
|
||||||
|
|
|
@ -27,6 +27,9 @@ from homeassistant.exceptions import TemplateError
|
||||||
from homeassistant.helpers.logging import KeywordStyleAdapter
|
from homeassistant.helpers.logging import KeywordStyleAdapter
|
||||||
from homeassistant.util import slugify as util_slugify
|
from homeassistant.util import slugify as util_slugify
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-check-untyped-defs, no-warn-return-any
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
TIME_PERIOD_ERROR = "offset {} should be format 'HH:MM' or 'HH:MM:SS'"
|
TIME_PERIOD_ERROR = "offset {} should be format 'HH:MM' or 'HH:MM:SS'"
|
||||||
|
@ -92,7 +95,8 @@ def boolean(value: Any) -> bool:
|
||||||
if value in ('0', 'false', 'no', 'off', 'disable'):
|
if value in ('0', 'false', 'no', 'off', 'disable'):
|
||||||
return False
|
return False
|
||||||
elif isinstance(value, Number):
|
elif isinstance(value, Number):
|
||||||
return value != 0
|
# type ignore: https://github.com/python/mypy/issues/3186
|
||||||
|
return value != 0 # type: ignore
|
||||||
raise vol.Invalid('invalid boolean value {}'.format(value))
|
raise vol.Invalid('invalid boolean value {}'.format(value))
|
||||||
|
|
||||||
|
|
||||||
|
@ -161,7 +165,7 @@ def isdir(value: Any) -> str:
|
||||||
return dir_in
|
return dir_in
|
||||||
|
|
||||||
|
|
||||||
def ensure_list(value: Union[T, Sequence[T]]) -> Sequence[T]:
|
def ensure_list(value: Union[T, Sequence[T], None]) -> Sequence[T]:
|
||||||
"""Wrap value in list if it is not one."""
|
"""Wrap value in list if it is not one."""
|
||||||
if value is None:
|
if value is None:
|
||||||
return []
|
return []
|
||||||
|
@ -556,7 +560,8 @@ def deprecated(key: str,
|
||||||
else:
|
else:
|
||||||
# Unclear when it is None, but it happens, so let's guard.
|
# Unclear when it is None, but it happens, so let's guard.
|
||||||
# https://github.com/home-assistant/home-assistant/issues/24982
|
# https://github.com/home-assistant/home-assistant/issues/24982
|
||||||
module_name = __name__
|
# type ignore/unreachable: https://github.com/python/typeshed/pull/3137
|
||||||
|
module_name = __name__ # type: ignore
|
||||||
|
|
||||||
if replacement_key and invalidation_version:
|
if replacement_key and invalidation_version:
|
||||||
warning = ("The '{key}' option (with value '{value}') is"
|
warning = ("The '{key}' option (with value '{value}') is"
|
||||||
|
@ -606,13 +611,15 @@ def deprecated(key: str,
|
||||||
config.pop(key)
|
config.pop(key)
|
||||||
else:
|
else:
|
||||||
value = default
|
value = default
|
||||||
if (replacement_key
|
keys = [key]
|
||||||
and (replacement_key not in config
|
if replacement_key:
|
||||||
or default == config.get(replacement_key))
|
keys.append(replacement_key)
|
||||||
and value is not None):
|
if value is not None and (
|
||||||
config[replacement_key] = value
|
replacement_key not in config or
|
||||||
|
default == config.get(replacement_key)):
|
||||||
|
config[replacement_key] = value
|
||||||
|
|
||||||
return has_at_most_one_key(key, replacement_key)(config)
|
return has_at_most_one_key(*keys)(config)
|
||||||
|
|
||||||
return validator
|
return validator
|
||||||
|
|
||||||
|
@ -739,7 +746,7 @@ CONDITION_SCHEMA = vol.Any(
|
||||||
ZONE_CONDITION_SCHEMA,
|
ZONE_CONDITION_SCHEMA,
|
||||||
AND_CONDITION_SCHEMA,
|
AND_CONDITION_SCHEMA,
|
||||||
OR_CONDITION_SCHEMA,
|
OR_CONDITION_SCHEMA,
|
||||||
)
|
) # type: vol.Schema
|
||||||
|
|
||||||
_SCRIPT_DELAY_SCHEMA = vol.Schema({
|
_SCRIPT_DELAY_SCHEMA = vol.Schema({
|
||||||
vol.Optional(CONF_ALIAS): string,
|
vol.Optional(CONF_ALIAS): string,
|
||||||
|
|
|
@ -7,6 +7,8 @@ from homeassistant.components.http import HomeAssistantView
|
||||||
from homeassistant.components.http.data_validator import RequestDataValidator
|
from homeassistant.components.http.data_validator import RequestDataValidator
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-untyped-calls, allow-untyped-defs
|
||||||
|
|
||||||
class _BaseFlowManagerView(HomeAssistantView):
|
class _BaseFlowManagerView(HomeAssistantView):
|
||||||
"""Foundation for flow manager views."""
|
"""Foundation for flow manager views."""
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,10 @@ from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
from .typing import HomeAssistantType
|
from .typing import HomeAssistantType
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-check-untyped-defs, no-warn-return-any
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_UNDEF = object()
|
_UNDEF = object()
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.loader import DEPENDENCY_BLACKLIST
|
from homeassistant.loader import DEPENDENCY_BLACKLIST
|
||||||
from homeassistant.util.async_ import run_callback_threadsafe
|
from homeassistant.util.async_ import run_callback_threadsafe
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-untyped-defs, no-check-untyped-defs
|
||||||
|
|
||||||
EVENT_LOAD_PLATFORM = 'load_platform.{}'
|
EVENT_LOAD_PLATFORM = 'load_platform.{}'
|
||||||
ATTR_PLATFORM = 'platform'
|
ATTR_PLATFORM = 'platform'
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,19 @@ from homeassistant.const import (
|
||||||
ATTR_UNIT_OF_MEASUREMENT, DEVICE_DEFAULT_NAME, STATE_OFF, STATE_ON,
|
ATTR_UNIT_OF_MEASUREMENT, DEVICE_DEFAULT_NAME, STATE_OFF, STATE_ON,
|
||||||
STATE_UNAVAILABLE, STATE_UNKNOWN, TEMP_CELSIUS, TEMP_FAHRENHEIT,
|
STATE_UNAVAILABLE, STATE_UNKNOWN, TEMP_CELSIUS, TEMP_FAHRENHEIT,
|
||||||
ATTR_ENTITY_PICTURE, ATTR_SUPPORTED_FEATURES, ATTR_DEVICE_CLASS)
|
ATTR_ENTITY_PICTURE, ATTR_SUPPORTED_FEATURES, ATTR_DEVICE_CLASS)
|
||||||
from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED
|
from homeassistant.helpers.entity_registry import (
|
||||||
from homeassistant.core import HomeAssistant, callback
|
EVENT_ENTITY_REGISTRY_UPDATED, RegistryEntry)
|
||||||
|
from homeassistant.core import HomeAssistant, callback, CALLBACK_TYPE
|
||||||
from homeassistant.config import DATA_CUSTOMIZE
|
from homeassistant.config import DATA_CUSTOMIZE
|
||||||
from homeassistant.exceptions import NoEntitySpecifiedError
|
from homeassistant.exceptions import NoEntitySpecifiedError
|
||||||
from homeassistant.util import ensure_unique_string, slugify
|
from homeassistant.util import ensure_unique_string, slugify
|
||||||
from homeassistant.util.async_ import run_callback_threadsafe
|
from homeassistant.util.async_ import run_callback_threadsafe
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-defs, no-check-untyped-defs
|
||||||
|
# mypy: no-warn-return-any
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
SLOW_UPDATE_WARNING = 10
|
SLOW_UPDATE_WARNING = 10
|
||||||
|
|
||||||
|
@ -34,7 +39,7 @@ def generate_entity_id(entity_id_format: str, name: Optional[str],
|
||||||
current_ids, hass
|
current_ids, hass
|
||||||
).result()
|
).result()
|
||||||
|
|
||||||
name = (slugify(name) or slugify(DEVICE_DEFAULT_NAME)).lower()
|
name = (slugify(name or "") or slugify(DEVICE_DEFAULT_NAME)).lower()
|
||||||
|
|
||||||
return ensure_unique_string(
|
return ensure_unique_string(
|
||||||
entity_id_format.format(name), current_ids)
|
entity_id_format.format(name), current_ids)
|
||||||
|
@ -80,10 +85,10 @@ class Entity:
|
||||||
parallel_updates = None
|
parallel_updates = None
|
||||||
|
|
||||||
# Entry in the entity registry
|
# Entry in the entity registry
|
||||||
registry_entry = None
|
registry_entry = None # type: Optional[RegistryEntry]
|
||||||
|
|
||||||
# Hold list for functions to call on remove.
|
# Hold list for functions to call on remove.
|
||||||
_on_remove = None
|
_on_remove = None # type: Optional[List[CALLBACK_TYPE]]
|
||||||
|
|
||||||
# Context
|
# Context
|
||||||
_context = None
|
_context = None
|
||||||
|
@ -98,7 +103,7 @@ class Entity:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> Optional[str]:
|
||||||
"""Return a unique ID."""
|
"""Return a unique ID."""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -137,7 +142,7 @@ class Entity:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self) -> str:
|
def device_class(self) -> Optional[str]:
|
||||||
"""Return the class of this device, from component DEVICE_CLASSES."""
|
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -181,7 +186,7 @@ class Entity:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self) -> int:
|
def supported_features(self) -> Optional[int]:
|
||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -386,7 +391,7 @@ class Entity:
|
||||||
self.parallel_updates.release()
|
self.parallel_updates.release()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_on_remove(self, func):
|
def async_on_remove(self, func: CALLBACK_TYPE) -> None:
|
||||||
"""Add a function to call when entity removed."""
|
"""Add a function to call when entity removed."""
|
||||||
if self._on_remove is None:
|
if self._on_remove is None:
|
||||||
self._on_remove = []
|
self._on_remove = []
|
||||||
|
@ -421,6 +426,7 @@ class Entity:
|
||||||
Not to be extended by integrations.
|
Not to be extended by integrations.
|
||||||
"""
|
"""
|
||||||
if self.registry_entry is not None:
|
if self.registry_entry is not None:
|
||||||
|
assert self.hass is not None
|
||||||
self.async_on_remove(self.hass.bus.async_listen(
|
self.async_on_remove(self.hass.bus.async_listen(
|
||||||
EVENT_ENTITY_REGISTRY_UPDATED, self._async_registry_updated))
|
EVENT_ENTITY_REGISTRY_UPDATED, self._async_registry_updated))
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@ from homeassistant.loader import bind_hass, async_get_integration
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
from .entity_platform import EntityPlatform
|
from .entity_platform import EntityPlatform
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-untyped-defs, no-check-untyped-defs
|
||||||
|
|
||||||
DEFAULT_SCAN_INTERVAL = timedelta(seconds=15)
|
DEFAULT_SCAN_INTERVAL = timedelta(seconds=15)
|
||||||
DATA_INSTANCES = 'entity_components'
|
DATA_INSTANCES = 'entity_components'
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@ from homeassistant.util.async_ import (
|
||||||
|
|
||||||
from .event import async_track_time_interval, async_call_later
|
from .event import async_track_time_interval, async_call_later
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-untyped-defs, no-check-untyped-defs
|
||||||
|
|
||||||
SLOW_SETUP_WARNING = 10
|
SLOW_SETUP_WARNING = 10
|
||||||
SLOW_SETUP_MAX_WAIT = 60
|
SLOW_SETUP_MAX_WAIT = 60
|
||||||
PLATFORM_NOT_READY_RETRIES = 10
|
PLATFORM_NOT_READY_RETRIES = 10
|
||||||
|
|
|
@ -23,6 +23,10 @@ from homeassistant.util.yaml import load_yaml
|
||||||
|
|
||||||
from .typing import HomeAssistantType
|
from .typing import HomeAssistantType
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-check-untyped-defs, no-warn-return-any
|
||||||
|
|
||||||
PATH_REGISTRY = 'entity_registry.yaml'
|
PATH_REGISTRY = 'entity_registry.yaml'
|
||||||
DATA_REGISTRY = 'entity_registry'
|
DATA_REGISTRY = 'entity_registry'
|
||||||
EVENT_ENTITY_REGISTRY_UPDATED = 'entity_registry_updated'
|
EVENT_ENTITY_REGISTRY_UPDATED = 'entity_registry_updated'
|
||||||
|
@ -48,7 +52,8 @@ class RegistryEntry:
|
||||||
config_entry_id = attr.ib(type=str, default=None)
|
config_entry_id = attr.ib(type=str, default=None)
|
||||||
disabled_by = attr.ib(
|
disabled_by = attr.ib(
|
||||||
type=str, default=None,
|
type=str, default=None,
|
||||||
validator=attr.validators.in_((DISABLED_HASS, DISABLED_USER, None)))
|
validator=attr.validators.in_((DISABLED_HASS, DISABLED_USER, None))
|
||||||
|
) # type: Optional[str]
|
||||||
domain = attr.ib(type=str, init=False, repr=False)
|
domain = attr.ib(type=str, init=False, repr=False)
|
||||||
|
|
||||||
@domain.default
|
@domain.default
|
||||||
|
|
|
@ -7,13 +7,16 @@ import attr
|
||||||
|
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
from homeassistant.helpers.sun import get_astral_event_next
|
from homeassistant.helpers.sun import get_astral_event_next
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback, CALLBACK_TYPE
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_NOW, EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL,
|
ATTR_NOW, EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL,
|
||||||
SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET, EVENT_CORE_CONFIG_UPDATE)
|
SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET, EVENT_CORE_CONFIG_UPDATE)
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
from homeassistant.util.async_ import run_callback_threadsafe
|
from homeassistant.util.async_ import run_callback_threadsafe
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-check-untyped-defs, no-warn-return-any
|
||||||
# PyLint does not like the use of threaded_listener_factory
|
# PyLint does not like the use of threaded_listener_factory
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
|
@ -172,7 +175,7 @@ track_same_state = threaded_listener_factory(async_track_same_state)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@bind_hass
|
@bind_hass
|
||||||
def async_track_point_in_time(hass, action, point_in_time):
|
def async_track_point_in_time(hass, action, point_in_time) -> CALLBACK_TYPE:
|
||||||
"""Add a listener that fires once after a specific point in time."""
|
"""Add a listener that fires once after a specific point in time."""
|
||||||
utc_point_in_time = dt_util.as_utc(point_in_time)
|
utc_point_in_time = dt_util.as_utc(point_in_time)
|
||||||
|
|
||||||
|
@ -190,7 +193,8 @@ track_point_in_time = threaded_listener_factory(async_track_point_in_time)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@bind_hass
|
@bind_hass
|
||||||
def async_track_point_in_utc_time(hass, action, point_in_time):
|
def async_track_point_in_utc_time(
|
||||||
|
hass, action, point_in_time) -> CALLBACK_TYPE:
|
||||||
"""Add a listener that fires once after a specific point in UTC time."""
|
"""Add a listener that fires once after a specific point in UTC time."""
|
||||||
# Ensure point_in_time is UTC
|
# Ensure point_in_time is UTC
|
||||||
point_in_time = dt_util.as_utc(point_in_time)
|
point_in_time = dt_util.as_utc(point_in_time)
|
||||||
|
|
|
@ -3,6 +3,8 @@ import inspect
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-untyped-defs, no-check-untyped-defs
|
||||||
|
|
||||||
class KeywordMessage:
|
class KeywordMessage:
|
||||||
"""
|
"""
|
||||||
Represents a logging message with keyword arguments.
|
Represents a logging message with keyword arguments.
|
||||||
|
|
|
@ -15,6 +15,10 @@ from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.json import JSONEncoder
|
from homeassistant.helpers.json import JSONEncoder
|
||||||
from homeassistant.helpers.storage import Store # noqa pylint_disable=unused-import
|
from homeassistant.helpers.storage import Store # noqa pylint_disable=unused-import
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-untyped-calls, allow-untyped-defs, no-check-untyped-defs
|
||||||
|
# mypy: no-warn-return-any
|
||||||
|
|
||||||
DATA_RESTORE_STATE_TASK = 'restore_state_task'
|
DATA_RESTORE_STATE_TASK = 'restore_state_task'
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -182,8 +186,8 @@ class RestoreStateData():
|
||||||
# we're going to serialize it to JSON and then re-load it.
|
# we're going to serialize it to JSON and then re-load it.
|
||||||
if state is not None:
|
if state is not None:
|
||||||
state = State.from_dict(_encode_complex(state.as_dict()))
|
state = State.from_dict(_encode_complex(state.as_dict()))
|
||||||
|
if state is not None:
|
||||||
self.last_states[entity_id] = StoredState(state, dt_util.utcnow())
|
self.last_states[entity_id] = StoredState(state, dt_util.utcnow())
|
||||||
|
|
||||||
self.entity_ids.remove(entity_id)
|
self.entity_ids.remove(entity_id)
|
||||||
|
|
||||||
|
@ -219,6 +223,7 @@ class RestoreEntity(Entity):
|
||||||
|
|
||||||
async def async_internal_added_to_hass(self) -> None:
|
async def async_internal_added_to_hass(self) -> None:
|
||||||
"""Register this entity as a restorable entity."""
|
"""Register this entity as a restorable entity."""
|
||||||
|
assert self.hass is not None
|
||||||
_, data = await asyncio.gather(
|
_, data = await asyncio.gather(
|
||||||
super().async_internal_added_to_hass(),
|
super().async_internal_added_to_hass(),
|
||||||
RestoreStateData.async_get_instance(self.hass),
|
RestoreStateData.async_get_instance(self.hass),
|
||||||
|
@ -227,6 +232,7 @@ class RestoreEntity(Entity):
|
||||||
|
|
||||||
async def async_internal_will_remove_from_hass(self) -> None:
|
async def async_internal_will_remove_from_hass(self) -> None:
|
||||||
"""Run when entity will be removed from hass."""
|
"""Run when entity will be removed from hass."""
|
||||||
|
assert self.hass is not None
|
||||||
_, data = await asyncio.gather(
|
_, data = await asyncio.gather(
|
||||||
super().async_internal_will_remove_from_hass(),
|
super().async_internal_will_remove_from_hass(),
|
||||||
RestoreStateData.async_get_instance(self.hass),
|
RestoreStateData.async_get_instance(self.hass),
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
|
from datetime import datetime
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
from typing import Optional, Sequence
|
from typing import Optional, Sequence, Callable, Dict, List, Set, Tuple
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant, Context, callback
|
from homeassistant.core import HomeAssistant, Context, callback, CALLBACK_TYPE
|
||||||
from homeassistant.const import CONF_CONDITION, CONF_TIMEOUT
|
from homeassistant.const import CONF_CONDITION, CONF_TIMEOUT
|
||||||
from homeassistant import exceptions
|
from homeassistant import exceptions
|
||||||
from homeassistant.helpers import (
|
from homeassistant.helpers import (
|
||||||
|
@ -20,6 +21,10 @@ import homeassistant.util.dt as date_util
|
||||||
from homeassistant.util.async_ import (
|
from homeassistant.util.async_ import (
|
||||||
run_coroutine_threadsafe, run_callback_threadsafe)
|
run_coroutine_threadsafe, run_callback_threadsafe)
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-check-untyped-defs
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
CONF_ALIAS = 'alias'
|
CONF_ALIAS = 'alias'
|
||||||
|
@ -76,7 +81,8 @@ class _SuspendScript(Exception):
|
||||||
class Script():
|
class Script():
|
||||||
"""Representation of a script."""
|
"""Representation of a script."""
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant, sequence, name: str = None,
|
def __init__(self, hass: HomeAssistant, sequence,
|
||||||
|
name: Optional[str] = None,
|
||||||
change_listener=None) -> None:
|
change_listener=None) -> None:
|
||||||
"""Initialize the script."""
|
"""Initialize the script."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
|
@ -85,14 +91,13 @@ class Script():
|
||||||
self.name = name
|
self.name = name
|
||||||
self._change_listener = change_listener
|
self._change_listener = change_listener
|
||||||
self._cur = -1
|
self._cur = -1
|
||||||
self._exception_step = None
|
self._exception_step = None # type: Optional[int]
|
||||||
self.last_action = None
|
self.last_action = None
|
||||||
self.last_triggered = None
|
self.last_triggered = None # type: Optional[datetime]
|
||||||
self.can_cancel = any(CONF_DELAY in action or CONF_WAIT_TEMPLATE
|
self.can_cancel = any(CONF_DELAY in action or CONF_WAIT_TEMPLATE
|
||||||
in action for action in self.sequence)
|
in action for action in self.sequence)
|
||||||
self._async_listener = []
|
self._async_listener = [] # type: List[CALLBACK_TYPE]
|
||||||
self._template_cache = {}
|
self._config_cache = {} # type: Dict[Set[Tuple], Callable[..., bool]]
|
||||||
self._config_cache = {}
|
|
||||||
self._actions = {
|
self._actions = {
|
||||||
ACTION_DELAY: self._async_delay,
|
ACTION_DELAY: self._async_delay,
|
||||||
ACTION_WAIT_TEMPLATE: self._async_wait_template,
|
ACTION_WAIT_TEMPLATE: self._async_wait_template,
|
||||||
|
|
|
@ -19,6 +19,9 @@ import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.util.async_ import run_coroutine_threadsafe
|
from homeassistant.util.async_ import run_coroutine_threadsafe
|
||||||
from homeassistant.helpers.typing import HomeAssistantType
|
from homeassistant.helpers.typing import HomeAssistantType
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-defs, no-check-untyped-defs
|
||||||
|
|
||||||
CONF_SERVICE = 'service'
|
CONF_SERVICE = 'service'
|
||||||
CONF_SERVICE_TEMPLATE = 'service_template'
|
CONF_SERVICE_TEMPLATE = 'service_template'
|
||||||
CONF_SERVICE_ENTITY_ID = 'entity_id'
|
CONF_SERVICE_ENTITY_ID = 'entity_id'
|
||||||
|
|
|
@ -3,7 +3,7 @@ import asyncio
|
||||||
from json import JSONEncoder
|
from json import JSONEncoder
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from typing import Dict, List, Optional, Callable, Union
|
from typing import Dict, List, Optional, Callable, Union, Any, Type
|
||||||
|
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
|
@ -11,6 +11,10 @@ from homeassistant.loader import bind_hass
|
||||||
from homeassistant.util import json as json_util
|
from homeassistant.util import json as json_util
|
||||||
from homeassistant.helpers.event import async_call_later
|
from homeassistant.helpers.event import async_call_later
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-warn-return-any
|
||||||
|
|
||||||
STORAGE_DIR = '.storage'
|
STORAGE_DIR = '.storage'
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -48,17 +52,17 @@ class Store:
|
||||||
"""Class to help storing data."""
|
"""Class to help storing data."""
|
||||||
|
|
||||||
def __init__(self, hass, version: int, key: str, private: bool = False, *,
|
def __init__(self, hass, version: int, key: str, private: bool = False, *,
|
||||||
encoder: JSONEncoder = None):
|
encoder: Optional[Type[JSONEncoder]] = None):
|
||||||
"""Initialize storage class."""
|
"""Initialize storage class."""
|
||||||
self.version = version
|
self.version = version
|
||||||
self.key = key
|
self.key = key
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self._private = private
|
self._private = private
|
||||||
self._data = None
|
self._data = None # type: Optional[Dict[str, Any]]
|
||||||
self._unsub_delay_listener = None
|
self._unsub_delay_listener = None
|
||||||
self._unsub_stop_listener = None
|
self._unsub_stop_listener = None
|
||||||
self._write_lock = asyncio.Lock()
|
self._write_lock = asyncio.Lock()
|
||||||
self._load_task = None
|
self._load_task = None # type: Optional[asyncio.Future]
|
||||||
self._encoder = encoder
|
self._encoder = encoder
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -12,7 +12,7 @@ from typing import Iterable
|
||||||
import jinja2
|
import jinja2
|
||||||
from jinja2 import contextfilter, contextfunction
|
from jinja2 import contextfilter, contextfunction
|
||||||
from jinja2.sandbox import ImmutableSandboxedEnvironment
|
from jinja2.sandbox import ImmutableSandboxedEnvironment
|
||||||
from jinja2.utils import Namespace
|
from jinja2.utils import Namespace # type: ignore
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID, ATTR_LATITUDE, ATTR_LONGITUDE, ATTR_UNIT_OF_MEASUREMENT,
|
ATTR_ENTITY_ID, ATTR_LATITUDE, ATTR_LONGITUDE, ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
@ -26,6 +26,10 @@ from homeassistant.loader import bind_hass
|
||||||
from homeassistant.util import convert, dt as dt_util, location as loc_util
|
from homeassistant.util import convert, dt as dt_util, location as loc_util
|
||||||
from homeassistant.util.async_ import run_callback_threadsafe
|
from homeassistant.util.async_ import run_callback_threadsafe
|
||||||
|
|
||||||
|
|
||||||
|
# mypy: allow-incomplete-defs, allow-untyped-calls, allow-untyped-defs
|
||||||
|
# mypy: no-check-untyped-defs, no-warn-return-any
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_SENTINEL = object()
|
_SENTINEL = object()
|
||||||
DATE_STR_FORMAT = "%Y-%m-%d %H:%M:%S"
|
DATE_STR_FORMAT = "%Y-%m-%d %H:%M:%S"
|
||||||
|
@ -192,14 +196,13 @@ class Template:
|
||||||
|
|
||||||
This method must be run in the event loop.
|
This method must be run in the event loop.
|
||||||
"""
|
"""
|
||||||
if self._compiled is None:
|
compiled = self._compiled or self._ensure_compiled()
|
||||||
self._ensure_compiled()
|
|
||||||
|
|
||||||
if variables is not None:
|
if variables is not None:
|
||||||
kwargs.update(variables)
|
kwargs.update(variables)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self._compiled.render(kwargs).strip()
|
return compiled.render(kwargs).strip()
|
||||||
except jinja2.TemplateError as err:
|
except jinja2.TemplateError as err:
|
||||||
raise TemplateError(err)
|
raise TemplateError(err)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""JSON utility functions."""
|
"""JSON utility functions."""
|
||||||
import logging
|
import logging
|
||||||
from typing import Union, List, Dict, Optional
|
from typing import Union, List, Dict, Optional, Type
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
@ -42,7 +42,7 @@ def load_json(filename: str, default: Union[List, Dict, None] = None) \
|
||||||
|
|
||||||
def save_json(filename: str, data: Union[List, Dict],
|
def save_json(filename: str, data: Union[List, Dict],
|
||||||
private: bool = False, *,
|
private: bool = False, *,
|
||||||
encoder: Optional[json.JSONEncoder] = None) -> None:
|
encoder: Optional[Type[json.JSONEncoder]] = None) -> None:
|
||||||
"""Save JSON data to a file.
|
"""Save JSON data to a file.
|
||||||
|
|
||||||
Returns True on success.
|
Returns True on success.
|
||||||
|
|
19
mypyrc
19
mypyrc
|
@ -1,21 +1,4 @@
|
||||||
homeassistant/*.py
|
homeassistant/*.py
|
||||||
homeassistant/auth/
|
homeassistant/auth/
|
||||||
|
homeassistant/helpers/
|
||||||
homeassistant/util/
|
homeassistant/util/
|
||||||
homeassistant/helpers/__init__.py
|
|
||||||
homeassistant/helpers/aiohttp_client.py
|
|
||||||
homeassistant/helpers/area_registry.py
|
|
||||||
homeassistant/helpers/condition.py
|
|
||||||
homeassistant/helpers/deprecation.py
|
|
||||||
homeassistant/helpers/dispatcher.py
|
|
||||||
homeassistant/helpers/entity_values.py
|
|
||||||
homeassistant/helpers/entityfilter.py
|
|
||||||
homeassistant/helpers/icon.py
|
|
||||||
homeassistant/helpers/intent.py
|
|
||||||
homeassistant/helpers/json.py
|
|
||||||
homeassistant/helpers/location.py
|
|
||||||
homeassistant/helpers/signal.py
|
|
||||||
homeassistant/helpers/state.py
|
|
||||||
homeassistant/helpers/sun.py
|
|
||||||
homeassistant/helpers/temperature.py
|
|
||||||
homeassistant/helpers/translation.py
|
|
||||||
homeassistant/helpers/typing.py
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue