Make config entry disabled_by an enum (#60445)
* Make config entry disabled_by an enum * Update homeassistant/config_entries.py Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
aa83b0388a
commit
7db3246de4
7 changed files with 78 additions and 22 deletions
|
@ -304,7 +304,8 @@ async def config_entry_update(hass, connection, msg):
|
|||
"type": "config_entries/disable",
|
||||
"entry_id": str,
|
||||
# We only allow setting disabled_by user via API.
|
||||
"disabled_by": vol.Any(config_entries.DISABLED_USER, None),
|
||||
# No Enum support like this in voluptuous, use .value
|
||||
"disabled_by": vol.Any(config_entries.ConfigEntryDisabler.USER.value, None),
|
||||
}
|
||||
)
|
||||
async def config_entry_disable(hass, connection, msg):
|
||||
|
|
|
@ -13,6 +13,7 @@ from typing import TYPE_CHECKING, Any, Callable, Optional, cast
|
|||
import weakref
|
||||
|
||||
from homeassistant import data_entry_flow, loader
|
||||
from homeassistant.backports.enum import StrEnum
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import CALLBACK_TYPE, CoreState, HomeAssistant, callback
|
||||
from homeassistant.exceptions import (
|
||||
|
@ -22,6 +23,7 @@ from homeassistant.exceptions import (
|
|||
)
|
||||
from homeassistant.helpers import device_registry, entity_registry
|
||||
from homeassistant.helpers.event import Event
|
||||
from homeassistant.helpers.frame import report
|
||||
from homeassistant.helpers.typing import (
|
||||
UNDEFINED,
|
||||
ConfigType,
|
||||
|
@ -128,7 +130,15 @@ RECONFIGURE_NOTIFICATION_ID = "config_entry_reconfigure"
|
|||
|
||||
EVENT_FLOW_DISCOVERED = "config_entry_discovered"
|
||||
|
||||
DISABLED_USER = "user"
|
||||
|
||||
class ConfigEntryDisabler(StrEnum):
|
||||
"""What disabled a config entry."""
|
||||
|
||||
USER = "user"
|
||||
|
||||
|
||||
# DISABLED_* is deprecated, to be removed in 2022.3
|
||||
DISABLED_USER = ConfigEntryDisabler.USER.value
|
||||
|
||||
RELOAD_AFTER_UPDATE_DELAY = 30
|
||||
|
||||
|
@ -195,7 +205,7 @@ class ConfigEntry:
|
|||
unique_id: str | None = None,
|
||||
entry_id: str | None = None,
|
||||
state: ConfigEntryState = ConfigEntryState.NOT_LOADED,
|
||||
disabled_by: str | None = None,
|
||||
disabled_by: ConfigEntryDisabler | None = None,
|
||||
) -> None:
|
||||
"""Initialize a config entry."""
|
||||
# Unique id of the config entry
|
||||
|
@ -237,6 +247,16 @@ class ConfigEntry:
|
|||
self.unique_id = unique_id
|
||||
|
||||
# Config entry is disabled
|
||||
if isinstance(disabled_by, str) and not isinstance(
|
||||
disabled_by, ConfigEntryDisabler
|
||||
):
|
||||
report( # type: ignore[unreachable]
|
||||
"uses str for config entry disabled_by. This is deprecated and will "
|
||||
"stop working in Home Assistant 2022.3, it should be updated to use "
|
||||
"ConfigEntryDisabler instead",
|
||||
error_if_core=False,
|
||||
)
|
||||
disabled_by = ConfigEntryDisabler(disabled_by)
|
||||
self.disabled_by = disabled_by
|
||||
|
||||
# Supports unload
|
||||
|
@ -924,7 +944,9 @@ class ConfigEntries:
|
|||
# New in 0.104
|
||||
unique_id=entry.get("unique_id"),
|
||||
# New in 2021.3
|
||||
disabled_by=entry.get("disabled_by"),
|
||||
disabled_by=ConfigEntryDisabler(entry["disabled_by"])
|
||||
if entry.get("disabled_by")
|
||||
else None,
|
||||
# New in 2021.6
|
||||
pref_disable_new_entities=pref_disable_new_entities,
|
||||
pref_disable_polling=entry.get("pref_disable_polling"),
|
||||
|
@ -985,7 +1007,7 @@ class ConfigEntries:
|
|||
return await self.async_setup(entry_id)
|
||||
|
||||
async def async_set_disabled_by(
|
||||
self, entry_id: str, disabled_by: str | None
|
||||
self, entry_id: str, disabled_by: ConfigEntryDisabler | None
|
||||
) -> bool:
|
||||
"""Disable an entry.
|
||||
|
||||
|
@ -994,7 +1016,18 @@ class ConfigEntries:
|
|||
if (entry := self.async_get_entry(entry_id)) is None:
|
||||
raise UnknownEntry
|
||||
|
||||
if entry.disabled_by == disabled_by:
|
||||
if isinstance(disabled_by, str) and not isinstance(
|
||||
disabled_by, ConfigEntryDisabler
|
||||
):
|
||||
report( # type: ignore[unreachable]
|
||||
"uses str for config entry disabled_by. This is deprecated and will "
|
||||
"stop working in Home Assistant 2022.3, it should be updated to use "
|
||||
"ConfigEntryDisabler instead",
|
||||
error_if_core=False,
|
||||
)
|
||||
disabled_by = ConfigEntryDisabler(disabled_by)
|
||||
|
||||
if entry.disabled_by is disabled_by:
|
||||
return True
|
||||
|
||||
entry.disabled_by = disabled_by
|
||||
|
|
|
@ -79,7 +79,7 @@ async def test_get_entries(hass, client):
|
|||
domain="comp3",
|
||||
title="Test 3",
|
||||
source="bla3",
|
||||
disabled_by=core_ce.DISABLED_USER,
|
||||
disabled_by=core_ce.ConfigEntryDisabler.USER,
|
||||
).add_to_hass(hass)
|
||||
|
||||
resp = await client.get("/api/config/config_entries/entry")
|
||||
|
@ -121,7 +121,7 @@ async def test_get_entries(hass, client):
|
|||
"supports_unload": False,
|
||||
"pref_disable_new_entities": False,
|
||||
"pref_disable_polling": False,
|
||||
"disabled_by": core_ce.DISABLED_USER,
|
||||
"disabled_by": core_ce.ConfigEntryDisabler.USER,
|
||||
"reason": None,
|
||||
},
|
||||
]
|
||||
|
@ -877,14 +877,14 @@ async def test_disable_entry(hass, hass_ws_client):
|
|||
"id": 5,
|
||||
"type": "config_entries/disable",
|
||||
"entry_id": entry.entry_id,
|
||||
"disabled_by": core_ce.DISABLED_USER,
|
||||
"disabled_by": core_ce.ConfigEntryDisabler.USER,
|
||||
}
|
||||
)
|
||||
response = await ws_client.receive_json()
|
||||
|
||||
assert response["success"]
|
||||
assert response["result"] == {"require_restart": True}
|
||||
assert entry.disabled_by == core_ce.DISABLED_USER
|
||||
assert entry.disabled_by is core_ce.ConfigEntryDisabler.USER
|
||||
assert entry.state is core_ce.ConfigEntryState.FAILED_UNLOAD
|
||||
|
||||
# Enable
|
||||
|
@ -930,7 +930,7 @@ async def test_disable_entry_nonexisting(hass, hass_ws_client):
|
|||
"id": 5,
|
||||
"type": "config_entries/disable",
|
||||
"entry_id": "non_existing",
|
||||
"disabled_by": core_ce.DISABLED_USER,
|
||||
"disabled_by": core_ce.ConfigEntryDisabler.USER,
|
||||
}
|
||||
)
|
||||
response = await ws_client.receive_json()
|
||||
|
|
|
@ -10,7 +10,7 @@ from zwave_js_server.model.node import Node
|
|||
from homeassistant.components.hassio.handler import HassioAPIError
|
||||
from homeassistant.components.zwave_js.const import DOMAIN
|
||||
from homeassistant.components.zwave_js.helpers import get_device_id
|
||||
from homeassistant.config_entries import DISABLED_USER, ConfigEntryState
|
||||
from homeassistant.config_entries import ConfigEntryDisabler, ConfigEntryState
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
|
@ -554,7 +554,9 @@ async def test_stop_addon(
|
|||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
await hass.config_entries.async_set_disabled_by(entry.entry_id, DISABLED_USER)
|
||||
await hass.config_entries.async_set_disabled_by(
|
||||
entry.entry_id, ConfigEntryDisabler.USER
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == entry_state
|
||||
|
|
|
@ -1342,7 +1342,7 @@ async def test_disable_config_entry_disables_devices(hass, registry):
|
|||
assert entry2.disabled
|
||||
|
||||
await hass.config_entries.async_set_disabled_by(
|
||||
config_entry.entry_id, config_entries.DISABLED_USER
|
||||
config_entry.entry_id, config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -1382,7 +1382,7 @@ async def test_only_disable_device_if_all_config_entries_are_disabled(hass, regi
|
|||
assert not entry1.disabled
|
||||
|
||||
await hass.config_entries.async_set_disabled_by(
|
||||
config_entry1.entry_id, config_entries.DISABLED_USER
|
||||
config_entry1.entry_id, config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -1390,7 +1390,7 @@ async def test_only_disable_device_if_all_config_entries_are_disabled(hass, regi
|
|||
assert not entry1.disabled
|
||||
|
||||
await hass.config_entries.async_set_disabled_by(
|
||||
config_entry2.entry_id, config_entries.DISABLED_USER
|
||||
config_entry2.entry_id, config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
|
|
@ -919,7 +919,7 @@ async def test_disable_config_entry_disables_entities(hass, registry):
|
|||
assert entry3.disabled
|
||||
|
||||
await hass.config_entries.async_set_disabled_by(
|
||||
config_entry.entry_id, config_entries.DISABLED_USER
|
||||
config_entry.entry_id, config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
|
|
@ -529,7 +529,7 @@ async def test_domains_gets_domains_excludes_ignore_and_disabled(manager):
|
|||
).add_to_manager(manager)
|
||||
MockConfigEntry(domain="test3").add_to_manager(manager)
|
||||
MockConfigEntry(
|
||||
domain="disabled", disabled_by=config_entries.DISABLED_USER
|
||||
domain="disabled", disabled_by=config_entries.ConfigEntryDisabler.USER
|
||||
).add_to_manager(manager)
|
||||
assert manager.async_domains() == ["test", "test2", "test3"]
|
||||
assert manager.async_domains(include_ignore=False) == ["test", "test2", "test3"]
|
||||
|
@ -1323,7 +1323,7 @@ async def test_entry_disable_succeed(hass, manager):
|
|||
|
||||
# Disable
|
||||
assert await manager.async_set_disabled_by(
|
||||
entry.entry_id, config_entries.DISABLED_USER
|
||||
entry.entry_id, config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
assert len(async_unload_entry.mock_calls) == 1
|
||||
assert len(async_setup.mock_calls) == 0
|
||||
|
@ -1358,7 +1358,7 @@ async def test_entry_disable_without_reload_support(hass, manager):
|
|||
|
||||
# Disable
|
||||
assert not await manager.async_set_disabled_by(
|
||||
entry.entry_id, config_entries.DISABLED_USER
|
||||
entry.entry_id, config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
assert len(async_setup.mock_calls) == 0
|
||||
assert len(async_setup_entry.mock_calls) == 0
|
||||
|
@ -1374,7 +1374,9 @@ async def test_entry_disable_without_reload_support(hass, manager):
|
|||
|
||||
async def test_entry_enable_without_reload_support(hass, manager):
|
||||
"""Test that we can disable an entry without reload support."""
|
||||
entry = MockConfigEntry(domain="comp", disabled_by=config_entries.DISABLED_USER)
|
||||
entry = MockConfigEntry(
|
||||
domain="comp", disabled_by=config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
async_setup = AsyncMock(return_value=True)
|
||||
|
@ -1398,7 +1400,7 @@ async def test_entry_enable_without_reload_support(hass, manager):
|
|||
|
||||
# Disable
|
||||
assert not await manager.async_set_disabled_by(
|
||||
entry.entry_id, config_entries.DISABLED_USER
|
||||
entry.entry_id, config_entries.ConfigEntryDisabler.USER
|
||||
)
|
||||
assert len(async_setup.mock_calls) == 1
|
||||
assert len(async_setup_entry.mock_calls) == 1
|
||||
|
@ -2966,3 +2968,21 @@ async def test_loading_old_data(hass, hass_storage):
|
|||
assert entry.title == "Mock title"
|
||||
assert entry.data == {"my": "data"}
|
||||
assert entry.pref_disable_new_entities is True
|
||||
|
||||
|
||||
async def test_deprecated_disabled_by_str_ctor(hass, caplog):
|
||||
"""Test deprecated str disabled_by constructor enumizes and logs a warning."""
|
||||
entry = MockConfigEntry(disabled_by=config_entries.ConfigEntryDisabler.USER.value)
|
||||
assert entry.disabled_by is config_entries.ConfigEntryDisabler.USER
|
||||
assert " str for config entry disabled_by. This is deprecated " in caplog.text
|
||||
|
||||
|
||||
async def test_deprecated_disabled_by_str_set(hass, manager, caplog):
|
||||
"""Test deprecated str set disabled_by enumizes and logs a warning."""
|
||||
entry = MockConfigEntry()
|
||||
entry.add_to_manager(manager)
|
||||
assert await manager.async_set_disabled_by(
|
||||
entry.entry_id, config_entries.ConfigEntryDisabler.USER.value
|
||||
)
|
||||
assert entry.disabled_by is config_entries.ConfigEntryDisabler.USER
|
||||
assert " str for config entry disabled_by. This is deprecated " in caplog.text
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue