Convert AreaEntry to dataclass (#108648)
* Convert AreaEntry to dataclass * Correct typing of AreaEntry.id * Move responsibility for generating area id to AreaRegistry
This commit is contained in:
parent
8c31e67dbc
commit
ef5d46c79c
1 changed files with 24 additions and 23 deletions
|
@ -2,11 +2,10 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from collections.abc import Container, Iterable, MutableMapping
|
from collections.abc import Iterable, MutableMapping
|
||||||
|
import dataclasses
|
||||||
from typing import Any, Literal, TypedDict, cast
|
from typing import Any, Literal, TypedDict, cast
|
||||||
|
|
||||||
import attr
|
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
|
@ -29,26 +28,15 @@ class EventAreaRegistryUpdatedData(TypedDict):
|
||||||
area_id: str
|
area_id: str
|
||||||
|
|
||||||
|
|
||||||
@attr.s(slots=True, frozen=True)
|
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
|
||||||
class AreaEntry:
|
class AreaEntry:
|
||||||
"""Area Registry Entry."""
|
"""Area Registry Entry."""
|
||||||
|
|
||||||
name: str = attr.ib()
|
aliases: set[str]
|
||||||
normalized_name: str = attr.ib()
|
id: str
|
||||||
aliases: set[str] = attr.ib(
|
name: str
|
||||||
converter=attr.converters.default_if_none(factory=set) # type: ignore[misc]
|
normalized_name: str
|
||||||
)
|
picture: str | None
|
||||||
id: str | None = attr.ib(default=None)
|
|
||||||
picture: str | None = attr.ib(default=None)
|
|
||||||
|
|
||||||
def generate_id(self, existing_ids: Container[str]) -> None:
|
|
||||||
"""Initialize ID."""
|
|
||||||
suggestion = suggestion_base = slugify(self.name)
|
|
||||||
tries = 1
|
|
||||||
while suggestion in existing_ids:
|
|
||||||
tries += 1
|
|
||||||
suggestion = f"{suggestion_base}_{tries}"
|
|
||||||
object.__setattr__(self, "id", suggestion)
|
|
||||||
|
|
||||||
|
|
||||||
class AreaRegistryStore(Store[dict[str, list[dict[str, Any]]]]):
|
class AreaRegistryStore(Store[dict[str, list[dict[str, Any]]]]):
|
||||||
|
@ -133,10 +121,14 @@ class AreaRegistry:
|
||||||
if self.async_get_area_by_name(name):
|
if self.async_get_area_by_name(name):
|
||||||
raise ValueError(f"The name {name} ({normalized_name}) is already in use")
|
raise ValueError(f"The name {name} ({normalized_name}) is already in use")
|
||||||
|
|
||||||
|
area_id = self._generate_area_id(name)
|
||||||
area = AreaEntry(
|
area = AreaEntry(
|
||||||
aliases=aliases, name=name, normalized_name=normalized_name, picture=picture
|
aliases=aliases or set(),
|
||||||
|
id=area_id,
|
||||||
|
name=name,
|
||||||
|
normalized_name=normalized_name,
|
||||||
|
picture=picture,
|
||||||
)
|
)
|
||||||
area.generate_id(self.areas)
|
|
||||||
assert area.id is not None
|
assert area.id is not None
|
||||||
self.areas[area.id] = area
|
self.areas[area.id] = area
|
||||||
self._normalized_name_area_idx[normalized_name] = area.id
|
self._normalized_name_area_idx[normalized_name] = area.id
|
||||||
|
@ -221,7 +213,7 @@ class AreaRegistry:
|
||||||
if not new_values:
|
if not new_values:
|
||||||
return old
|
return old
|
||||||
|
|
||||||
new = self.areas[area_id] = attr.evolve(old, **new_values) # type: ignore[arg-type]
|
new = self.areas[area_id] = dataclasses.replace(old, **new_values) # type: ignore[arg-type]
|
||||||
if normalized_name is not None:
|
if normalized_name is not None:
|
||||||
self._normalized_name_area_idx[
|
self._normalized_name_area_idx[
|
||||||
normalized_name
|
normalized_name
|
||||||
|
@ -273,6 +265,15 @@ class AreaRegistry:
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _generate_area_id(self, name: str) -> str:
|
||||||
|
"""Generate area ID."""
|
||||||
|
suggestion = suggestion_base = slugify(name)
|
||||||
|
tries = 1
|
||||||
|
while suggestion in self.areas:
|
||||||
|
tries += 1
|
||||||
|
suggestion = f"{suggestion_base}_{tries}"
|
||||||
|
return suggestion
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_get(hass: HomeAssistant) -> AreaRegistry:
|
def async_get(hass: HomeAssistant) -> AreaRegistry:
|
||||||
|
|
Loading…
Add table
Reference in a new issue