mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Adjust thread safety check messages to point to developer docs (#117392)
This commit is contained in:
parent
77de1b2331
commit
7871e9279b
@ -1955,7 +1955,7 @@ class ConfigEntries:
|
|||||||
if entry.entry_id not in self._entries:
|
if entry.entry_id not in self._entries:
|
||||||
raise UnknownEntry(entry.entry_id)
|
raise UnknownEntry(entry.entry_id)
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("async_update_entry")
|
self.hass.verify_event_loop_thread("hass.config_entries.async_update_entry")
|
||||||
changed = False
|
changed = False
|
||||||
_setter = object.__setattr__
|
_setter = object.__setattr__
|
||||||
|
|
||||||
|
@ -439,7 +439,10 @@ class HomeAssistant:
|
|||||||
|
|
||||||
# frame is a circular import, so we import it here
|
# frame is a circular import, so we import it here
|
||||||
frame.report(
|
frame.report(
|
||||||
f"calls {what} from a thread",
|
f"calls {what} from a thread. "
|
||||||
|
"For more information, see "
|
||||||
|
"https://developers.home-assistant.io/docs/asyncio_thread_safety/"
|
||||||
|
f"#{what.replace('.', '')}",
|
||||||
error_if_core=True,
|
error_if_core=True,
|
||||||
error_if_integration=True,
|
error_if_integration=True,
|
||||||
)
|
)
|
||||||
@ -802,7 +805,7 @@ class HomeAssistant:
|
|||||||
# check with a check for the `hass.config.debug` flag being set as
|
# check with a check for the `hass.config.debug` flag being set as
|
||||||
# long term we don't want to be checking this in production
|
# long term we don't want to be checking this in production
|
||||||
# environments since it is a performance hit.
|
# environments since it is a performance hit.
|
||||||
self.verify_event_loop_thread("async_create_task")
|
self.verify_event_loop_thread("hass.async_create_task")
|
||||||
return self.async_create_task_internal(target, name, eager_start)
|
return self.async_create_task_internal(target, name, eager_start)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@ -1493,7 +1496,7 @@ class EventBus:
|
|||||||
This method must be run in the event loop.
|
This method must be run in the event loop.
|
||||||
"""
|
"""
|
||||||
_verify_event_type_length_or_raise(event_type)
|
_verify_event_type_length_or_raise(event_type)
|
||||||
self._hass.verify_event_loop_thread("async_fire")
|
self._hass.verify_event_loop_thread("hass.bus.async_fire")
|
||||||
return self.async_fire_internal(
|
return self.async_fire_internal(
|
||||||
event_type, event_data, origin, context, time_fired
|
event_type, event_data, origin, context, time_fired
|
||||||
)
|
)
|
||||||
@ -2506,7 +2509,7 @@ class ServiceRegistry:
|
|||||||
|
|
||||||
This method must be run in the event loop.
|
This method must be run in the event loop.
|
||||||
"""
|
"""
|
||||||
self._hass.verify_event_loop_thread("async_register")
|
self._hass.verify_event_loop_thread("hass.services.async_register")
|
||||||
self._async_register(
|
self._async_register(
|
||||||
domain, service, service_func, schema, supports_response, job_type
|
domain, service, service_func, schema, supports_response, job_type
|
||||||
)
|
)
|
||||||
@ -2565,7 +2568,7 @@ class ServiceRegistry:
|
|||||||
|
|
||||||
This method must be run in the event loop.
|
This method must be run in the event loop.
|
||||||
"""
|
"""
|
||||||
self._hass.verify_event_loop_thread("async_remove")
|
self._hass.verify_event_loop_thread("hass.services.async_remove")
|
||||||
self._async_remove(domain, service)
|
self._async_remove(domain, service)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@ -204,7 +204,7 @@ class AreaRegistry(BaseRegistry[AreasRegistryStoreData]):
|
|||||||
picture: str | None = None,
|
picture: str | None = None,
|
||||||
) -> AreaEntry:
|
) -> AreaEntry:
|
||||||
"""Create a new area."""
|
"""Create a new area."""
|
||||||
self.hass.verify_event_loop_thread("async_create")
|
self.hass.verify_event_loop_thread("area_registry.async_create")
|
||||||
normalized_name = normalize_name(name)
|
normalized_name = normalize_name(name)
|
||||||
|
|
||||||
if self.async_get_area_by_name(name):
|
if self.async_get_area_by_name(name):
|
||||||
@ -233,7 +233,7 @@ class AreaRegistry(BaseRegistry[AreasRegistryStoreData]):
|
|||||||
@callback
|
@callback
|
||||||
def async_delete(self, area_id: str) -> None:
|
def async_delete(self, area_id: str) -> None:
|
||||||
"""Delete area."""
|
"""Delete area."""
|
||||||
self.hass.verify_event_loop_thread("async_delete")
|
self.hass.verify_event_loop_thread("area_registry.async_delete")
|
||||||
device_registry = dr.async_get(self.hass)
|
device_registry = dr.async_get(self.hass)
|
||||||
entity_registry = er.async_get(self.hass)
|
entity_registry = er.async_get(self.hass)
|
||||||
device_registry.async_clear_area_id(area_id)
|
device_registry.async_clear_area_id(area_id)
|
||||||
@ -314,7 +314,7 @@ class AreaRegistry(BaseRegistry[AreasRegistryStoreData]):
|
|||||||
if not new_values:
|
if not new_values:
|
||||||
return old
|
return old
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("_async_update")
|
self.hass.verify_event_loop_thread("area_registry.async_update")
|
||||||
new = self.areas[area_id] = dataclasses.replace(old, **new_values) # type: ignore[arg-type]
|
new = self.areas[area_id] = dataclasses.replace(old, **new_values) # type: ignore[arg-type]
|
||||||
|
|
||||||
self.async_schedule_save()
|
self.async_schedule_save()
|
||||||
|
@ -98,7 +98,7 @@ class CategoryRegistry(BaseRegistry[CategoryRegistryStoreData]):
|
|||||||
icon: str | None = None,
|
icon: str | None = None,
|
||||||
) -> CategoryEntry:
|
) -> CategoryEntry:
|
||||||
"""Create a new category."""
|
"""Create a new category."""
|
||||||
self.hass.verify_event_loop_thread("async_create")
|
self.hass.verify_event_loop_thread("category_registry.async_create")
|
||||||
self._async_ensure_name_is_available(scope, name)
|
self._async_ensure_name_is_available(scope, name)
|
||||||
category = CategoryEntry(
|
category = CategoryEntry(
|
||||||
icon=icon,
|
icon=icon,
|
||||||
@ -122,7 +122,7 @@ class CategoryRegistry(BaseRegistry[CategoryRegistryStoreData]):
|
|||||||
@callback
|
@callback
|
||||||
def async_delete(self, *, scope: str, category_id: str) -> None:
|
def async_delete(self, *, scope: str, category_id: str) -> None:
|
||||||
"""Delete category."""
|
"""Delete category."""
|
||||||
self.hass.verify_event_loop_thread("async_delete")
|
self.hass.verify_event_loop_thread("category_registry.async_delete")
|
||||||
del self.categories[scope][category_id]
|
del self.categories[scope][category_id]
|
||||||
self.hass.bus.async_fire_internal(
|
self.hass.bus.async_fire_internal(
|
||||||
EVENT_CATEGORY_REGISTRY_UPDATED,
|
EVENT_CATEGORY_REGISTRY_UPDATED,
|
||||||
@ -157,7 +157,7 @@ class CategoryRegistry(BaseRegistry[CategoryRegistryStoreData]):
|
|||||||
if not changes:
|
if not changes:
|
||||||
return old
|
return old
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("async_update")
|
self.hass.verify_event_loop_thread("category_registry.async_update")
|
||||||
new = self.categories[scope][category_id] = dataclasses.replace(old, **changes) # type: ignore[arg-type]
|
new = self.categories[scope][category_id] = dataclasses.replace(old, **changes) # type: ignore[arg-type]
|
||||||
|
|
||||||
self.async_schedule_save()
|
self.async_schedule_save()
|
||||||
|
@ -906,7 +906,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
|
|||||||
if not new_values:
|
if not new_values:
|
||||||
return old
|
return old
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("async_update_device")
|
self.hass.verify_event_loop_thread("device_registry.async_update_device")
|
||||||
new = attr.evolve(old, **new_values)
|
new = attr.evolve(old, **new_values)
|
||||||
self.devices[device_id] = new
|
self.devices[device_id] = new
|
||||||
|
|
||||||
@ -933,7 +933,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
|
|||||||
@callback
|
@callback
|
||||||
def async_remove_device(self, device_id: str) -> None:
|
def async_remove_device(self, device_id: str) -> None:
|
||||||
"""Remove a device from the device registry."""
|
"""Remove a device from the device registry."""
|
||||||
self.hass.verify_event_loop_thread("async_remove_device")
|
self.hass.verify_event_loop_thread("device_registry.async_remove_device")
|
||||||
device = self.devices.pop(device_id)
|
device = self.devices.pop(device_id)
|
||||||
self.deleted_devices[device_id] = DeletedDeviceEntry(
|
self.deleted_devices[device_id] = DeletedDeviceEntry(
|
||||||
config_entries=device.config_entries,
|
config_entries=device.config_entries,
|
||||||
|
@ -821,7 +821,7 @@ class EntityRegistry(BaseRegistry):
|
|||||||
unit_of_measurement=unit_of_measurement,
|
unit_of_measurement=unit_of_measurement,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("async_get_or_create")
|
self.hass.verify_event_loop_thread("entity_registry.async_get_or_create")
|
||||||
_validate_item(
|
_validate_item(
|
||||||
self.hass,
|
self.hass,
|
||||||
domain,
|
domain,
|
||||||
@ -894,7 +894,7 @@ class EntityRegistry(BaseRegistry):
|
|||||||
@callback
|
@callback
|
||||||
def async_remove(self, entity_id: str) -> None:
|
def async_remove(self, entity_id: str) -> None:
|
||||||
"""Remove an entity from registry."""
|
"""Remove an entity from registry."""
|
||||||
self.hass.verify_event_loop_thread("async_remove")
|
self.hass.verify_event_loop_thread("entity_registry.async_remove")
|
||||||
entity = self.entities.pop(entity_id)
|
entity = self.entities.pop(entity_id)
|
||||||
config_entry_id = entity.config_entry_id
|
config_entry_id = entity.config_entry_id
|
||||||
key = (entity.domain, entity.platform, entity.unique_id)
|
key = (entity.domain, entity.platform, entity.unique_id)
|
||||||
@ -1089,7 +1089,7 @@ class EntityRegistry(BaseRegistry):
|
|||||||
if not new_values:
|
if not new_values:
|
||||||
return old
|
return old
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("_async_update_entity")
|
self.hass.verify_event_loop_thread("entity_registry.async_update_entity")
|
||||||
|
|
||||||
new = self.entities[entity_id] = attr.evolve(old, **new_values)
|
new = self.entities[entity_id] = attr.evolve(old, **new_values)
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ class FloorRegistry(BaseRegistry[FloorRegistryStoreData]):
|
|||||||
level: int | None = None,
|
level: int | None = None,
|
||||||
) -> FloorEntry:
|
) -> FloorEntry:
|
||||||
"""Create a new floor."""
|
"""Create a new floor."""
|
||||||
self.hass.verify_event_loop_thread("async_create")
|
self.hass.verify_event_loop_thread("floor_registry.async_create")
|
||||||
if floor := self.async_get_floor_by_name(name):
|
if floor := self.async_get_floor_by_name(name):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"The name {name} ({floor.normalized_name}) is already in use"
|
f"The name {name} ({floor.normalized_name}) is already in use"
|
||||||
@ -152,7 +152,7 @@ class FloorRegistry(BaseRegistry[FloorRegistryStoreData]):
|
|||||||
@callback
|
@callback
|
||||||
def async_delete(self, floor_id: str) -> None:
|
def async_delete(self, floor_id: str) -> None:
|
||||||
"""Delete floor."""
|
"""Delete floor."""
|
||||||
self.hass.verify_event_loop_thread("async_delete")
|
self.hass.verify_event_loop_thread("floor_registry.async_delete")
|
||||||
del self.floors[floor_id]
|
del self.floors[floor_id]
|
||||||
self.hass.bus.async_fire_internal(
|
self.hass.bus.async_fire_internal(
|
||||||
EVENT_FLOOR_REGISTRY_UPDATED,
|
EVENT_FLOOR_REGISTRY_UPDATED,
|
||||||
@ -191,7 +191,7 @@ class FloorRegistry(BaseRegistry[FloorRegistryStoreData]):
|
|||||||
if not changes:
|
if not changes:
|
||||||
return old
|
return old
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("async_update")
|
self.hass.verify_event_loop_thread("floor_registry.async_update")
|
||||||
new = self.floors[floor_id] = dataclasses.replace(old, **changes) # type: ignore[arg-type]
|
new = self.floors[floor_id] = dataclasses.replace(old, **changes) # type: ignore[arg-type]
|
||||||
|
|
||||||
self.async_schedule_save()
|
self.async_schedule_save()
|
||||||
|
@ -144,7 +144,7 @@ class IssueRegistry(BaseRegistry):
|
|||||||
translation_placeholders: dict[str, str] | None = None,
|
translation_placeholders: dict[str, str] | None = None,
|
||||||
) -> IssueEntry:
|
) -> IssueEntry:
|
||||||
"""Get issue. Create if it doesn't exist."""
|
"""Get issue. Create if it doesn't exist."""
|
||||||
self.hass.verify_event_loop_thread("async_get_or_create")
|
self.hass.verify_event_loop_thread("issue_registry.async_get_or_create")
|
||||||
if (issue := self.async_get_issue(domain, issue_id)) is None:
|
if (issue := self.async_get_issue(domain, issue_id)) is None:
|
||||||
issue = IssueEntry(
|
issue = IssueEntry(
|
||||||
active=True,
|
active=True,
|
||||||
@ -204,7 +204,7 @@ class IssueRegistry(BaseRegistry):
|
|||||||
@callback
|
@callback
|
||||||
def async_delete(self, domain: str, issue_id: str) -> None:
|
def async_delete(self, domain: str, issue_id: str) -> None:
|
||||||
"""Delete issue."""
|
"""Delete issue."""
|
||||||
self.hass.verify_event_loop_thread("async_delete")
|
self.hass.verify_event_loop_thread("issue_registry.async_delete")
|
||||||
if self.issues.pop((domain, issue_id), None) is None:
|
if self.issues.pop((domain, issue_id), None) is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ class IssueRegistry(BaseRegistry):
|
|||||||
@callback
|
@callback
|
||||||
def async_ignore(self, domain: str, issue_id: str, ignore: bool) -> IssueEntry:
|
def async_ignore(self, domain: str, issue_id: str, ignore: bool) -> IssueEntry:
|
||||||
"""Ignore issue."""
|
"""Ignore issue."""
|
||||||
self.hass.verify_event_loop_thread("async_ignore")
|
self.hass.verify_event_loop_thread("issue_registry.async_ignore")
|
||||||
old = self.issues[(domain, issue_id)]
|
old = self.issues[(domain, issue_id)]
|
||||||
dismissed_version = ha_version if ignore else None
|
dismissed_version = ha_version if ignore else None
|
||||||
if old.dismissed_version == dismissed_version:
|
if old.dismissed_version == dismissed_version:
|
||||||
|
@ -121,7 +121,7 @@ class LabelRegistry(BaseRegistry[LabelRegistryStoreData]):
|
|||||||
description: str | None = None,
|
description: str | None = None,
|
||||||
) -> LabelEntry:
|
) -> LabelEntry:
|
||||||
"""Create a new label."""
|
"""Create a new label."""
|
||||||
self.hass.verify_event_loop_thread("async_create")
|
self.hass.verify_event_loop_thread("label_registry.async_create")
|
||||||
if label := self.async_get_label_by_name(name):
|
if label := self.async_get_label_by_name(name):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"The name {name} ({label.normalized_name}) is already in use"
|
f"The name {name} ({label.normalized_name}) is already in use"
|
||||||
@ -152,7 +152,7 @@ class LabelRegistry(BaseRegistry[LabelRegistryStoreData]):
|
|||||||
@callback
|
@callback
|
||||||
def async_delete(self, label_id: str) -> None:
|
def async_delete(self, label_id: str) -> None:
|
||||||
"""Delete label."""
|
"""Delete label."""
|
||||||
self.hass.verify_event_loop_thread("async_delete")
|
self.hass.verify_event_loop_thread("label_registry.async_delete")
|
||||||
del self.labels[label_id]
|
del self.labels[label_id]
|
||||||
self.hass.bus.async_fire_internal(
|
self.hass.bus.async_fire_internal(
|
||||||
EVENT_LABEL_REGISTRY_UPDATED,
|
EVENT_LABEL_REGISTRY_UPDATED,
|
||||||
@ -192,7 +192,7 @@ class LabelRegistry(BaseRegistry[LabelRegistryStoreData]):
|
|||||||
if not changes:
|
if not changes:
|
||||||
return old
|
return old
|
||||||
|
|
||||||
self.hass.verify_event_loop_thread("async_update")
|
self.hass.verify_event_loop_thread("label_registry.async_update")
|
||||||
new = self.labels[label_id] = dataclasses.replace(old, **changes) # type: ignore[arg-type]
|
new = self.labels[label_id] = dataclasses.replace(old, **changes) # type: ignore[arg-type]
|
||||||
|
|
||||||
self.async_schedule_save()
|
self.async_schedule_save()
|
||||||
|
@ -500,7 +500,7 @@ async def test_async_get_or_create_thread_checks(
|
|||||||
"""We raise when trying to create in the wrong thread."""
|
"""We raise when trying to create in the wrong thread."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_create from a thread. Please report this issue.",
|
match="Detected code that calls area_registry.async_create from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(area_registry.async_create, "Mock1")
|
await hass.async_add_executor_job(area_registry.async_create, "Mock1")
|
||||||
|
|
||||||
@ -512,7 +512,7 @@ async def test_async_update_thread_checks(
|
|||||||
area = area_registry.async_create("Mock1")
|
area = area_registry.async_create("Mock1")
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls _async_update from a thread. Please report this issue.",
|
match="Detected code that calls area_registry.async_update from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(area_registry.async_update, area.id, name="Mock2")
|
partial(area_registry.async_update, area.id, name="Mock2")
|
||||||
@ -526,6 +526,6 @@ async def test_async_delete_thread_checks(
|
|||||||
area = area_registry.async_create("Mock1")
|
area = area_registry.async_create("Mock1")
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_delete from a thread. Please report this issue.",
|
match="Detected code that calls area_registry.async_delete from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(area_registry.async_delete, area.id)
|
await hass.async_add_executor_job(area_registry.async_delete, area.id)
|
||||||
|
@ -403,7 +403,7 @@ async def test_async_create_thread_safety(
|
|||||||
"""Test async_create raises when called from wrong thread."""
|
"""Test async_create raises when called from wrong thread."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_create from a thread. Please report this issue.",
|
match="Detected code that calls category_registry.async_create from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(category_registry.async_create, name="any", scope="any")
|
partial(category_registry.async_create, name="any", scope="any")
|
||||||
@ -418,7 +418,7 @@ async def test_async_delete_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_delete from a thread. Please report this issue.",
|
match="Detected code that calls category_registry.async_delete from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(
|
partial(
|
||||||
@ -437,7 +437,7 @@ async def test_async_update_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_update from a thread. Please report this issue.",
|
match="Detected code that calls category_registry.async_update from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(
|
partial(
|
||||||
|
@ -2485,7 +2485,7 @@ async def test_async_get_or_create_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_update_device from a thread. Please report this issue.",
|
match="Detected code that calls device_registry.async_update_device from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(
|
partial(
|
||||||
@ -2515,7 +2515,7 @@ async def test_async_remove_device_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_remove_device from a thread. Please report this issue.",
|
match="Detected code that calls device_registry.async_remove_device from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
device_registry.async_remove_device, device.id
|
device_registry.async_remove_device, device.id
|
||||||
|
@ -1984,7 +1984,7 @@ async def test_get_or_create_thread_safety(
|
|||||||
"""Test call async_get_or_create_from a thread."""
|
"""Test call async_get_or_create_from a thread."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_get_or_create from a thread. Please report this issue.",
|
match="Detected code that calls entity_registry.async_get_or_create from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
entity_registry.async_get_or_create, "light", "hue", "1234"
|
entity_registry.async_get_or_create, "light", "hue", "1234"
|
||||||
@ -1998,7 +1998,7 @@ async def test_async_update_entity_thread_safety(
|
|||||||
entry = entity_registry.async_get_or_create("light", "hue", "1234")
|
entry = entity_registry.async_get_or_create("light", "hue", "1234")
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls _async_update_entity from a thread. Please report this issue.",
|
match="Detected code that calls entity_registry.async_update_entity from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(
|
partial(
|
||||||
@ -2016,6 +2016,6 @@ async def test_async_remove_thread_safety(
|
|||||||
entry = entity_registry.async_get_or_create("light", "hue", "1234")
|
entry = entity_registry.async_get_or_create("light", "hue", "1234")
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_remove from a thread. Please report this issue.",
|
match="Detected code that calls entity_registry.async_remove from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(entity_registry.async_remove, entry.entity_id)
|
await hass.async_add_executor_job(entity_registry.async_remove, entry.entity_id)
|
||||||
|
@ -367,7 +367,7 @@ async def test_async_create_thread_safety(
|
|||||||
"""Test async_create raises when called from wrong thread."""
|
"""Test async_create raises when called from wrong thread."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_create from a thread. Please report this issue.",
|
match="Detected code that calls floor_registry.async_create from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(floor_registry.async_create, "any")
|
await hass.async_add_executor_job(floor_registry.async_create, "any")
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ async def test_async_delete_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_delete from a thread. Please report this issue.",
|
match="Detected code that calls floor_registry.async_delete from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(floor_registry.async_delete, any_floor)
|
await hass.async_add_executor_job(floor_registry.async_delete, any_floor)
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ async def test_async_update_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_update from a thread. Please report this issue.",
|
match="Detected code that calls floor_registry.async_update from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(floor_registry.async_update, any_floor.floor_id, name="new name")
|
partial(floor_registry.async_update, any_floor.floor_id, name="new name")
|
||||||
|
@ -367,7 +367,7 @@ async def test_get_or_create_thread_safety(
|
|||||||
"""Test call async_get_or_create_from a thread."""
|
"""Test call async_get_or_create_from a thread."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_get_or_create from a thread. Please report this issue.",
|
match="Detected code that calls issue_registry.async_get_or_create from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(
|
partial(
|
||||||
@ -397,7 +397,7 @@ async def test_async_delete_issue_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_delete from a thread. Please report this issue.",
|
match="Detected code that calls issue_registry.async_delete from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
ir.async_delete_issue,
|
ir.async_delete_issue,
|
||||||
@ -422,7 +422,7 @@ async def test_async_ignore_issue_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_ignore from a thread. Please report this issue.",
|
match="Detected code that calls issue_registry.async_ignore from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
ir.async_ignore_issue, hass, "any", "any", True
|
ir.async_ignore_issue, hass, "any", "any", True
|
||||||
|
@ -464,7 +464,7 @@ async def test_async_create_thread_safety(
|
|||||||
"""Test async_create raises when called from wrong thread."""
|
"""Test async_create raises when called from wrong thread."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_create from a thread. Please report this issue.",
|
match="Detected code that calls label_registry.async_create from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(label_registry.async_create, "any")
|
await hass.async_add_executor_job(label_registry.async_create, "any")
|
||||||
|
|
||||||
@ -478,7 +478,7 @@ async def test_async_delete_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_delete from a thread. Please report this issue.",
|
match="Detected code that calls label_registry.async_delete from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(label_registry.async_delete, any_label)
|
await hass.async_add_executor_job(label_registry.async_delete, any_label)
|
||||||
|
|
||||||
@ -492,7 +492,7 @@ async def test_async_update_thread_safety(
|
|||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
match="Detected code that calls async_update from a thread. Please report this issue.",
|
match="Detected code that calls label_registry.async_update from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
partial(label_registry.async_update, any_label.label_id, name="new name")
|
partial(label_registry.async_update, any_label.label_id, name="new name")
|
||||||
|
@ -3442,7 +3442,8 @@ async def test_async_fire_thread_safety(hass: HomeAssistant) -> None:
|
|||||||
events = async_capture_events(hass, "test_event")
|
events = async_capture_events(hass, "test_event")
|
||||||
hass.bus.async_fire("test_event")
|
hass.bus.async_fire("test_event")
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError, match="Detected code that calls async_fire from a thread."
|
RuntimeError,
|
||||||
|
match="Detected code that calls hass.bus.async_fire from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(hass.bus.async_fire, "test_event")
|
await hass.async_add_executor_job(hass.bus.async_fire, "test_event")
|
||||||
|
|
||||||
@ -3452,7 +3453,8 @@ async def test_async_fire_thread_safety(hass: HomeAssistant) -> None:
|
|||||||
async def test_async_register_thread_safety(hass: HomeAssistant) -> None:
|
async def test_async_register_thread_safety(hass: HomeAssistant) -> None:
|
||||||
"""Test async_register thread safety."""
|
"""Test async_register thread safety."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError, match="Detected code that calls async_register from a thread."
|
RuntimeError,
|
||||||
|
match="Detected code that calls hass.services.async_register from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
hass.services.async_register,
|
hass.services.async_register,
|
||||||
@ -3465,7 +3467,8 @@ async def test_async_register_thread_safety(hass: HomeAssistant) -> None:
|
|||||||
async def test_async_remove_thread_safety(hass: HomeAssistant) -> None:
|
async def test_async_remove_thread_safety(hass: HomeAssistant) -> None:
|
||||||
"""Test async_remove thread safety."""
|
"""Test async_remove thread safety."""
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError, match="Detected code that calls async_remove from a thread."
|
RuntimeError,
|
||||||
|
match="Detected code that calls hass.services.async_remove from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
hass.services.async_remove, "test_domain", "test_service"
|
hass.services.async_remove, "test_domain", "test_service"
|
||||||
@ -3479,6 +3482,7 @@ async def test_async_create_task_thread_safety(hass: HomeAssistant) -> None:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
RuntimeError, match="Detected code that calls async_create_task from a thread."
|
RuntimeError,
|
||||||
|
match="Detected code that calls hass.async_create_task from a thread.",
|
||||||
):
|
):
|
||||||
await hass.async_add_executor_job(hass.async_create_task, _any_coro)
|
await hass.async_add_executor_job(hass.async_create_task, _any_coro)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user