mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Fix deadlock in holidays dynamic loading (#115385)
This commit is contained in:
parent
6394e25f75
commit
9d7e20f9ca
@ -2,15 +2,36 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
from holidays import country_holidays
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import CONF_COUNTRY, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.setup import SetupPhases, async_pause_setup
|
||||||
|
|
||||||
|
from .const import CONF_PROVINCE
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.CALENDAR]
|
PLATFORMS: list[Platform] = [Platform.CALENDAR]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up Holiday from a config entry."""
|
"""Set up Holiday from a config entry."""
|
||||||
|
country: str = entry.data[CONF_COUNTRY]
|
||||||
|
province: str | None = entry.data.get(CONF_PROVINCE)
|
||||||
|
|
||||||
|
# We only import here to ensure that that its not imported later
|
||||||
|
# in the event loop since the platforms will call country_holidays
|
||||||
|
# which loads python code from disk.
|
||||||
|
with async_pause_setup(hass, SetupPhases.WAIT_IMPORT_PACKAGES):
|
||||||
|
# import executor job is used here because multiple integrations use
|
||||||
|
# the holidays library and it is not thread safe to import it in parallel
|
||||||
|
# https://github.com/python/cpython/issues/83065
|
||||||
|
await hass.async_add_import_executor_job(
|
||||||
|
partial(country_holidays, country, subdiv=province)
|
||||||
|
)
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -11,6 +11,7 @@ from homeassistant.const import CONF_COUNTRY, CONF_LANGUAGE
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryError
|
from homeassistant.exceptions import ConfigEntryError
|
||||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||||
|
from homeassistant.setup import SetupPhases, async_pause_setup
|
||||||
|
|
||||||
from .const import CONF_PROVINCE, DOMAIN, PLATFORMS
|
from .const import CONF_PROVINCE, DOMAIN, PLATFORMS
|
||||||
|
|
||||||
@ -23,7 +24,11 @@ async def _async_validate_country_and_province(
|
|||||||
if not country:
|
if not country:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
await hass.async_add_executor_job(country_holidays, country)
|
with async_pause_setup(hass, SetupPhases.WAIT_IMPORT_PACKAGES):
|
||||||
|
# import executor job is used here because multiple integrations use
|
||||||
|
# the holidays library and it is not thread safe to import it in parallel
|
||||||
|
# https://github.com/python/cpython/issues/83065
|
||||||
|
await hass.async_add_import_executor_job(country_holidays, country)
|
||||||
except NotImplementedError as ex:
|
except NotImplementedError as ex:
|
||||||
async_create_issue(
|
async_create_issue(
|
||||||
hass,
|
hass,
|
||||||
@ -41,9 +46,13 @@ async def _async_validate_country_and_province(
|
|||||||
if not province:
|
if not province:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
await hass.async_add_executor_job(
|
with async_pause_setup(hass, SetupPhases.WAIT_IMPORT_PACKAGES):
|
||||||
partial(country_holidays, country, subdiv=province)
|
# import executor job is used here because multiple integrations use
|
||||||
)
|
# the holidays library and it is not thread safe to import it in parallel
|
||||||
|
# https://github.com/python/cpython/issues/83065
|
||||||
|
await hass.async_add_import_executor_job(
|
||||||
|
partial(country_holidays, country, subdiv=province)
|
||||||
|
)
|
||||||
except NotImplementedError as ex:
|
except NotImplementedError as ex:
|
||||||
async_create_issue(
|
async_create_issue(
|
||||||
hass,
|
hass,
|
||||||
@ -73,9 +82,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
await _async_validate_country_and_province(hass, entry, country, province)
|
await _async_validate_country_and_province(hass, entry, country, province)
|
||||||
|
|
||||||
if country and CONF_LANGUAGE not in entry.options:
|
if country and CONF_LANGUAGE not in entry.options:
|
||||||
cls: HolidayBase = await hass.async_add_executor_job(
|
with async_pause_setup(hass, SetupPhases.WAIT_IMPORT_PACKAGES):
|
||||||
partial(country_holidays, country, subdiv=province)
|
# import executor job is used here because multiple integrations use
|
||||||
)
|
# the holidays library and it is not thread safe to import it in parallel
|
||||||
|
# https://github.com/python/cpython/issues/83065
|
||||||
|
cls: HolidayBase = await hass.async_add_import_executor_job(
|
||||||
|
partial(country_holidays, country, subdiv=province)
|
||||||
|
)
|
||||||
default_language = cls.default_language
|
default_language = cls.default_language
|
||||||
new_options = entry.options.copy()
|
new_options = entry.options.copy()
|
||||||
new_options[CONF_LANGUAGE] = default_language
|
new_options[CONF_LANGUAGE] = default_language
|
||||||
|
Loading…
x
Reference in New Issue
Block a user