mirror of https://github.com/home-assistant/core
Align valid_entity_id with new slugify (#20231)
* slug * ensure a dot * fix * schema_with_slug_keys * lint * test
This commit is contained in:
parent
6ca0da5c52
commit
c36c708068
|
@ -45,7 +45,7 @@ SCRIPT_ENTRY_SCHEMA = vol.Schema({
|
|||
})
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({cv.slug: SCRIPT_ENTRY_SCHEMA})
|
||||
DOMAIN: cv.schema_with_slug_keys(SCRIPT_ENTRY_SCHEMA)
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
SCRIPT_SERVICE_SCHEMA = vol.Schema(dict)
|
||||
|
|
|
@ -170,10 +170,9 @@ def _no_duplicate_auth_mfa_module(configs: Sequence[Dict[str, Any]]) \
|
|||
return configs
|
||||
|
||||
|
||||
PACKAGES_CONFIG_SCHEMA = vol.Schema({
|
||||
cv.slug: vol.Schema( # Package names are slugs
|
||||
{cv.string: vol.Any(dict, list, None)}) # Component configuration
|
||||
})
|
||||
PACKAGES_CONFIG_SCHEMA = cv.schema_with_slug_keys( # Package names are slugs
|
||||
vol.Schema({cv.string: vol.Any(dict, list, None)}) # Component config
|
||||
)
|
||||
|
||||
CUSTOMIZE_DICT_SCHEMA = vol.Schema({
|
||||
vol.Optional(ATTR_FRIENDLY_NAME): cv.string,
|
||||
|
@ -627,7 +626,7 @@ def _identify_config_schema(module: ModuleType) -> \
|
|||
except (AttributeError, KeyError):
|
||||
return None, None
|
||||
t_schema = str(schema)
|
||||
if t_schema.startswith('{'):
|
||||
if t_schema.startswith('{') or 'schema_with_slug_keys' in t_schema:
|
||||
return ('dict', schema)
|
||||
if t_schema.startswith(('[', 'All(<function ensure_list')):
|
||||
return ('list', schema)
|
||||
|
|
|
@ -12,7 +12,6 @@ import functools
|
|||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
from time import monotonic
|
||||
|
@ -43,7 +42,7 @@ from homeassistant.util.async_ import (
|
|||
fire_coroutine_threadsafe)
|
||||
from homeassistant import util
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.util import location
|
||||
from homeassistant.util import location, slugify
|
||||
from homeassistant.util.unit_system import UnitSystem, METRIC_SYSTEM # NOQA
|
||||
|
||||
# Typing imports that create a circular dependency
|
||||
|
@ -62,9 +61,6 @@ DOMAIN = 'homeassistant'
|
|||
# How long we wait for the result of a service call
|
||||
SERVICE_CALL_LIMIT = 10 # seconds
|
||||
|
||||
# Pattern for validating entity IDs (format: <domain>.<entity>)
|
||||
ENTITY_ID_PATTERN = re.compile(r"^(\w+)\.(\w+)$")
|
||||
|
||||
# How long to wait till things that run on startup have to finish.
|
||||
TIMEOUT_EVENT_START = 15
|
||||
|
||||
|
@ -77,8 +73,12 @@ def split_entity_id(entity_id: str) -> List[str]:
|
|||
|
||||
|
||||
def valid_entity_id(entity_id: str) -> bool:
|
||||
"""Test if an entity ID is a valid format."""
|
||||
return ENTITY_ID_PATTERN.match(entity_id) is not None
|
||||
"""Test if an entity ID is a valid format.
|
||||
|
||||
Format: <domain>.<entity> where both are slugs.
|
||||
"""
|
||||
return ('.' in entity_id and
|
||||
slugify(entity_id) == entity_id.replace('.', '_', 1))
|
||||
|
||||
|
||||
def valid_state(state: str) -> bool:
|
||||
|
|
|
@ -319,7 +319,23 @@ def service(value):
|
|||
.format(value))
|
||||
|
||||
|
||||
def slug(value):
|
||||
def schema_with_slug_keys(value_schema: Union[T, Callable]) -> Callable:
|
||||
"""Ensure dicts have slugs as keys.
|
||||
|
||||
Replacement of vol.Schema({cv.slug: value_schema}) to prevent misleading
|
||||
"Extra keys" errors from voluptuous.
|
||||
"""
|
||||
schema = vol.Schema({str: value_schema})
|
||||
|
||||
def verify(value: Dict) -> Dict:
|
||||
"""Validate all keys are slugs and then the value_schema."""
|
||||
for key in value.keys():
|
||||
slug(key)
|
||||
return schema(value)
|
||||
return verify
|
||||
|
||||
|
||||
def slug(value: Any) -> str:
|
||||
"""Validate value is a valid slug."""
|
||||
if value is None:
|
||||
raise vol.Invalid('Slug should not be None')
|
||||
|
@ -330,7 +346,7 @@ def slug(value):
|
|||
raise vol.Invalid('invalid slug {} (try {})'.format(value, slg))
|
||||
|
||||
|
||||
def slugify(value):
|
||||
def slugify(value: Any) -> str:
|
||||
"""Coerce a value to a slug."""
|
||||
if value is None:
|
||||
raise vol.Invalid('Slug should not be None')
|
||||
|
|
|
@ -139,11 +139,11 @@ class TestWOLSwitch(unittest.TestCase):
|
|||
'mac_address': '00-01-02-03-04-05',
|
||||
'host': 'validhostname',
|
||||
'turn_off': {
|
||||
'service': 'shell_command.turn_off_TARGET',
|
||||
'service': 'shell_command.turn_off_target',
|
||||
},
|
||||
}
|
||||
})
|
||||
calls = mock_service(self.hass, 'shell_command', 'turn_off_TARGET')
|
||||
calls = mock_service(self.hass, 'shell_command', 'turn_off_target')
|
||||
|
||||
state = self.hass.states.get('switch.wake_on_lan')
|
||||
assert STATE_OFF == state.state
|
||||
|
|
Loading…
Reference in New Issue