mirror of
https://github.com/home-assistant/core.git
synced 2025-12-25 05:26:47 +00:00
Black
This commit is contained in:
@@ -15,23 +15,24 @@ from homeassistant.util.async_ import run_coroutine_threadsafe
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_COMPONENT = 'component'
|
||||
ATTR_COMPONENT = "component"
|
||||
|
||||
DATA_SETUP = 'setup_tasks'
|
||||
DATA_DEPS_REQS = 'deps_reqs_processed'
|
||||
DATA_SETUP = "setup_tasks"
|
||||
DATA_DEPS_REQS = "deps_reqs_processed"
|
||||
|
||||
SLOW_SETUP_WARNING = 10
|
||||
|
||||
|
||||
def setup_component(hass: core.HomeAssistant, domain: str,
|
||||
config: Dict) -> bool:
|
||||
def setup_component(hass: core.HomeAssistant, domain: str, config: Dict) -> bool:
|
||||
"""Set up a component and all its dependencies."""
|
||||
return run_coroutine_threadsafe( # type: ignore
|
||||
async_setup_component(hass, domain, config), hass.loop).result()
|
||||
async_setup_component(hass, domain, config), hass.loop
|
||||
).result()
|
||||
|
||||
|
||||
async def async_setup_component(hass: core.HomeAssistant, domain: str,
|
||||
config: Dict) -> bool:
|
||||
async def async_setup_component(
|
||||
hass: core.HomeAssistant, domain: str, config: Dict
|
||||
) -> bool:
|
||||
"""Set up a component and all its dependencies.
|
||||
|
||||
This method is a coroutine.
|
||||
@@ -45,50 +46,55 @@ async def async_setup_component(hass: core.HomeAssistant, domain: str,
|
||||
return await setup_tasks[domain] # type: ignore
|
||||
|
||||
task = setup_tasks[domain] = hass.async_create_task(
|
||||
_async_setup_component(hass, domain, config))
|
||||
_async_setup_component(hass, domain, config)
|
||||
)
|
||||
|
||||
return await task # type: ignore
|
||||
|
||||
|
||||
async def _async_process_dependencies(
|
||||
hass: core.HomeAssistant, config: Dict, name: str,
|
||||
dependencies: List[str]) -> bool:
|
||||
hass: core.HomeAssistant, config: Dict, name: str, dependencies: List[str]
|
||||
) -> bool:
|
||||
"""Ensure all dependencies are set up."""
|
||||
blacklisted = [dep for dep in dependencies
|
||||
if dep in loader.DEPENDENCY_BLACKLIST]
|
||||
blacklisted = [dep for dep in dependencies if dep in loader.DEPENDENCY_BLACKLIST]
|
||||
|
||||
if blacklisted and name != 'default_config':
|
||||
_LOGGER.error("Unable to set up dependencies of %s: "
|
||||
"found blacklisted dependencies: %s",
|
||||
name, ', '.join(blacklisted))
|
||||
if blacklisted and name != "default_config":
|
||||
_LOGGER.error(
|
||||
"Unable to set up dependencies of %s: "
|
||||
"found blacklisted dependencies: %s",
|
||||
name,
|
||||
", ".join(blacklisted),
|
||||
)
|
||||
return False
|
||||
|
||||
tasks = [async_setup_component(hass, dep, config) for dep
|
||||
in dependencies]
|
||||
tasks = [async_setup_component(hass, dep, config) for dep in dependencies]
|
||||
|
||||
if not tasks:
|
||||
return True
|
||||
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
failed = [dependencies[idx] for idx, res
|
||||
in enumerate(results) if not res]
|
||||
failed = [dependencies[idx] for idx, res in enumerate(results) if not res]
|
||||
|
||||
if failed:
|
||||
_LOGGER.error("Unable to set up dependencies of %s. "
|
||||
"Setup failed for dependencies: %s",
|
||||
name, ', '.join(failed))
|
||||
_LOGGER.error(
|
||||
"Unable to set up dependencies of %s. " "Setup failed for dependencies: %s",
|
||||
name,
|
||||
", ".join(failed),
|
||||
)
|
||||
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
async def _async_setup_component(hass: core.HomeAssistant,
|
||||
domain: str, config: Dict) -> bool:
|
||||
async def _async_setup_component(
|
||||
hass: core.HomeAssistant, domain: str, config: Dict
|
||||
) -> bool:
|
||||
"""Set up a component for Home Assistant.
|
||||
|
||||
This method is a coroutine.
|
||||
"""
|
||||
|
||||
def log_error(msg: str, link: bool = True) -> None:
|
||||
"""Log helper."""
|
||||
_LOGGER.error("Setup failed for %s: %s", domain, msg)
|
||||
@@ -105,13 +111,18 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
await loader.async_component_dependencies(hass, domain)
|
||||
except loader.IntegrationNotFound as err:
|
||||
_LOGGER.error(
|
||||
"Not setting up %s because we are unable to resolve "
|
||||
"(sub)dependency %s", domain, err.domain)
|
||||
"Not setting up %s because we are unable to resolve " "(sub)dependency %s",
|
||||
domain,
|
||||
err.domain,
|
||||
)
|
||||
return False
|
||||
except loader.CircularDependency as err:
|
||||
_LOGGER.error(
|
||||
"Not setting up %s because it contains a circular dependency: "
|
||||
"%s -> %s", domain, err.from_domain, err.to_domain)
|
||||
"Not setting up %s because it contains a circular dependency: " "%s -> %s",
|
||||
domain,
|
||||
err.from_domain,
|
||||
err.to_domain,
|
||||
)
|
||||
return False
|
||||
|
||||
# Process requirements as soon as possible, so we can import the component
|
||||
@@ -123,7 +134,8 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
return False
|
||||
|
||||
processed_config = await conf_util.async_process_component_config(
|
||||
hass, config, integration)
|
||||
hass, config, integration
|
||||
)
|
||||
|
||||
if processed_config is None:
|
||||
log_error("Invalid config.")
|
||||
@@ -138,22 +150,27 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
log_error("Unable to import component", False)
|
||||
return False
|
||||
|
||||
if hasattr(component, 'PLATFORM_SCHEMA'):
|
||||
if hasattr(component, "PLATFORM_SCHEMA"):
|
||||
# Entity components have their own warning
|
||||
warn_task = None
|
||||
else:
|
||||
warn_task = hass.loop.call_later(
|
||||
SLOW_SETUP_WARNING, _LOGGER.warning,
|
||||
SLOW_SETUP_WARNING,
|
||||
_LOGGER.warning,
|
||||
"Setup of %s is taking over %s seconds.",
|
||||
domain, SLOW_SETUP_WARNING)
|
||||
domain,
|
||||
SLOW_SETUP_WARNING,
|
||||
)
|
||||
|
||||
try:
|
||||
if hasattr(component, 'async_setup'):
|
||||
if hasattr(component, "async_setup"):
|
||||
result = await component.async_setup( # type: ignore
|
||||
hass, processed_config)
|
||||
elif hasattr(component, 'setup'):
|
||||
hass, processed_config
|
||||
)
|
||||
elif hasattr(component, "setup"):
|
||||
result = await hass.async_add_executor_job(
|
||||
component.setup, hass, processed_config) # type: ignore
|
||||
component.setup, hass, processed_config
|
||||
) # type: ignore
|
||||
else:
|
||||
log_error("No setup function defined.")
|
||||
return False
|
||||
@@ -171,8 +188,10 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
log_error("Integration failed to initialize.")
|
||||
return False
|
||||
if result is not True:
|
||||
log_error("Integration {!r} did not return boolean if setup was "
|
||||
"successful. Disabling component.".format(domain))
|
||||
log_error(
|
||||
"Integration {!r} did not return boolean if setup was "
|
||||
"successful. Disabling component.".format(domain)
|
||||
)
|
||||
return False
|
||||
|
||||
if hass.config_entries:
|
||||
@@ -185,29 +204,23 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
if domain in hass.data[DATA_SETUP]:
|
||||
hass.data[DATA_SETUP].pop(domain)
|
||||
|
||||
hass.bus.async_fire(
|
||||
EVENT_COMPONENT_LOADED,
|
||||
{ATTR_COMPONENT: domain}
|
||||
)
|
||||
hass.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: domain})
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_prepare_setup_platform(hass: core.HomeAssistant,
|
||||
hass_config: Dict,
|
||||
domain: str, platform_name: str) \
|
||||
-> Optional[ModuleType]:
|
||||
async def async_prepare_setup_platform(
|
||||
hass: core.HomeAssistant, hass_config: Dict, domain: str, platform_name: str
|
||||
) -> Optional[ModuleType]:
|
||||
"""Load a platform and makes sure dependencies are setup.
|
||||
|
||||
This method is a coroutine.
|
||||
"""
|
||||
platform_path = PLATFORM_FORMAT.format(domain=domain,
|
||||
platform=platform_name)
|
||||
platform_path = PLATFORM_FORMAT.format(domain=domain, platform=platform_name)
|
||||
|
||||
def log_error(msg: str) -> None:
|
||||
"""Log helper."""
|
||||
_LOGGER.error("Unable to prepare setup for platform %s: %s",
|
||||
platform_path, msg)
|
||||
_LOGGER.error("Unable to prepare setup for platform %s: %s", platform_path, msg)
|
||||
async_notify_setup_error(hass, platform_path)
|
||||
|
||||
try:
|
||||
@@ -243,11 +256,8 @@ async def async_prepare_setup_platform(hass: core.HomeAssistant,
|
||||
log_error("Unable to import the component ({}).".format(exc))
|
||||
return None
|
||||
|
||||
if (hasattr(component, 'setup')
|
||||
or hasattr(component, 'async_setup')):
|
||||
if not await async_setup_component(
|
||||
hass, integration.domain, hass_config
|
||||
):
|
||||
if hasattr(component, "setup") or hasattr(component, "async_setup"):
|
||||
if not await async_setup_component(hass, integration.domain, hass_config):
|
||||
log_error("Unable to set up component.")
|
||||
return None
|
||||
|
||||
@@ -255,8 +265,8 @@ async def async_prepare_setup_platform(hass: core.HomeAssistant,
|
||||
|
||||
|
||||
async def async_process_deps_reqs(
|
||||
hass: core.HomeAssistant, config: Dict,
|
||||
integration: loader.Integration) -> None:
|
||||
hass: core.HomeAssistant, config: Dict, integration: loader.Integration
|
||||
) -> None:
|
||||
"""Process all dependencies and requirements for a module.
|
||||
|
||||
Module is a Python module of either a component or platform.
|
||||
@@ -269,16 +279,17 @@ async def async_process_deps_reqs(
|
||||
return
|
||||
|
||||
if integration.dependencies and not await _async_process_dependencies(
|
||||
hass,
|
||||
config,
|
||||
integration.domain,
|
||||
integration.dependencies
|
||||
hass, config, integration.domain, integration.dependencies
|
||||
):
|
||||
raise HomeAssistantError("Could not set up all dependencies.")
|
||||
|
||||
if (not hass.config.skip_pip and integration.requirements and
|
||||
not await requirements.async_process_requirements(
|
||||
hass, integration.domain, integration.requirements)):
|
||||
if (
|
||||
not hass.config.skip_pip
|
||||
and integration.requirements
|
||||
and not await requirements.async_process_requirements(
|
||||
hass, integration.domain, integration.requirements
|
||||
)
|
||||
):
|
||||
raise HomeAssistantError("Could not install all requirements.")
|
||||
|
||||
processed.add(integration.domain)
|
||||
@@ -286,17 +297,18 @@ async def async_process_deps_reqs(
|
||||
|
||||
@core.callback
|
||||
def async_when_setup(
|
||||
hass: core.HomeAssistant, component: str,
|
||||
when_setup_cb: Callable[
|
||||
[core.HomeAssistant, str], Awaitable[None]]) -> None:
|
||||
hass: core.HomeAssistant,
|
||||
component: str,
|
||||
when_setup_cb: Callable[[core.HomeAssistant, str], Awaitable[None]],
|
||||
) -> None:
|
||||
"""Call a method when a component is setup."""
|
||||
|
||||
async def when_setup() -> None:
|
||||
"""Call the callback."""
|
||||
try:
|
||||
await when_setup_cb(hass, component)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception('Error handling when_setup callback for %s',
|
||||
component)
|
||||
_LOGGER.exception("Error handling when_setup callback for %s", component)
|
||||
|
||||
# Running it in a new task so that it always runs after
|
||||
if component in hass.config.components:
|
||||
|
||||
Reference in New Issue
Block a user