From dac6307b57446e55463692a9bad32fbe8226d9f3 Mon Sep 17 00:00:00 2001 From: David Wu <133224895+David-Wu1119@users.noreply.github.com> Date: Mon, 7 Sep 2026 01:03:53 -0700 Subject: [PATCH] Type the dlna_dms domain data with a HassKey (#181100) --- homeassistant/components/dlna_dms/const.py | 10 +++++++++- homeassistant/components/dlna_dms/dms.py | 19 ++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/dlna_dms/const.py b/homeassistant/components/dlna_dms/const.py index 4bc3d58d079a..7b7a58872ec6 100644 --- a/homeassistant/components/dlna_dms/const.py +++ b/homeassistant/components/dlna_dms/const.py @@ -2,15 +2,23 @@ from collections.abc import Mapping import logging -from typing import Final +from typing import TYPE_CHECKING, Final from homeassistant.components.media_player import MediaClass +from homeassistant.util.hass_dict import HassKey + +if TYPE_CHECKING: + from .dms import DlnaDmsData LOGGER = logging.getLogger(__package__) DOMAIN: Final = "dlna_dms" DEFAULT_NAME: Final = "DLNA Media Server" +# One DlnaDmsData holds the device and source registries for every config +# entry, so it is shared rather than owned by any one entry. +DOMAIN_DATA: HassKey[DlnaDmsData] = HassKey(DOMAIN) + CONF_SOURCE_ID: Final = "source_id" CONFIG_VERSION: Final = 1 diff --git a/homeassistant/components/dlna_dms/dms.py b/homeassistant/components/dlna_dms/dms.py index 7133c6f86a50..63ed280e9aba 100644 --- a/homeassistant/components/dlna_dms/dms.py +++ b/homeassistant/components/dlna_dms/dms.py @@ -1,12 +1,11 @@ """Wrapper for media_source around async_upnp_client's DmsDevice .""" -# pylint: disable=home-assistant-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern import asyncio from collections.abc import Callable, Coroutine from dataclasses import dataclass from enum import StrEnum import functools -from typing import Any, cast +from typing import Any from async_upnp_client.aiohttp import AiohttpSessionRequester from async_upnp_client.client import UpnpRequester @@ -37,6 +36,7 @@ from .const import ( DLNA_RESOLVE_FILTER, DLNA_SORT_CRITERIA, DOMAIN, + DOMAIN_DATA, LOGGER, MEDIA_CLASS_MAP, PATH_OBJECT_ID_FLAG, @@ -91,12 +91,17 @@ class DlnaDmsData: @callback def get_domain_data(hass: HomeAssistant) -> DlnaDmsData: - """Obtain this integration's domain data, creating it if needed.""" - if DOMAIN in hass.data: - return cast(DlnaDmsData, hass.data[DOMAIN]) + """Obtain this integration's domain data, creating it if needed. - data = DlnaDmsData(hass) - hass.data[DOMAIN] = data + Creation is deferred to the first caller rather than done at setup, to + avoid building DlnaDmsData and its dependencies until a device is + actually connected to. This module is imported to run the config flow + for any DMS device discovered on the network, including ignored ones. + """ + if (data := hass.data.get(DOMAIN_DATA)) is not None: + return data + + data = hass.data[DOMAIN_DATA] = DlnaDmsData(hass) return data