Remove the weak ref for tracking update listeners (#95798)

This commit is contained in:
Paulus Schoutsen 2023-07-03 14:56:21 -04:00 committed by GitHub
parent 4d3662d4da
commit 0f725a24bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,9 +10,8 @@ from enum import Enum
import functools import functools
import logging import logging
from random import randint from random import randint
from types import MappingProxyType, MethodType from types import MappingProxyType
from typing import TYPE_CHECKING, Any, TypeVar, cast from typing import TYPE_CHECKING, Any, TypeVar, cast
import weakref
from typing_extensions import Self from typing_extensions import Self
@ -303,9 +302,7 @@ class ConfigEntry:
self.supports_remove_device: bool | None = None self.supports_remove_device: bool | None = None
# Listeners to call on update # Listeners to call on update
self.update_listeners: list[ self.update_listeners: list[UpdateListenerType] = []
weakref.ReferenceType[UpdateListenerType] | weakref.WeakMethod
] = []
# Reason why config entry is in a failed state # Reason why config entry is in a failed state
self.reason: str | None = None self.reason: str | None = None
@ -653,16 +650,8 @@ class ConfigEntry:
Returns function to unlisten. Returns function to unlisten.
""" """
weak_listener: Any self.update_listeners.append(listener)
# weakref.ref is not applicable to a bound method, e.g., return lambda: self.update_listeners.remove(listener)
# method of a class instance, as reference will die immediately.
if hasattr(listener, "__self__"):
weak_listener = weakref.WeakMethod(cast(MethodType, listener))
else:
weak_listener = weakref.ref(listener)
self.update_listeners.append(weak_listener)
return lambda: self.update_listeners.remove(weak_listener)
def as_dict(self) -> dict[str, Any]: def as_dict(self) -> dict[str, Any]:
"""Return dictionary version of this entry.""" """Return dictionary version of this entry."""
@ -1348,8 +1337,7 @@ class ConfigEntries:
if not changed: if not changed:
return False return False
for listener_ref in entry.update_listeners: for listener in entry.update_listeners:
if (listener := listener_ref()) is not None:
self.hass.async_create_task( self.hass.async_create_task(
listener(self.hass, entry), listener(self.hass, entry),
f"config entry update listener {entry.title} {entry.domain} {entry.domain}", f"config entry update listener {entry.title} {entry.domain} {entry.domain}",