Extend add_update_listener support to bound methods (#44238)

This commit is contained in:
jpcornil-git 2021-01-26 22:19:10 +01:00 committed by GitHub
parent 67fcdc5a9c
commit 74a44e03fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,7 +2,7 @@
import asyncio import asyncio
import functools import functools
import logging import logging
from types import MappingProxyType from types import MappingProxyType, MethodType
from typing import Any, Callable, Dict, List, Optional, Set, Union, cast from typing import Any, Callable, Dict, List, Optional, Set, Union, cast
import weakref import weakref
@ -181,7 +181,9 @@ class ConfigEntry:
self.supports_unload = False self.supports_unload = False
# Listeners to call on update # Listeners to call on update
self.update_listeners: List[weakref.ReferenceType[UpdateListenerType]] = [] self.update_listeners: List[
Union[weakref.ReferenceType[UpdateListenerType], weakref.WeakMethod]
] = []
# Function to cancel a scheduled retry # Function to cancel a scheduled retry
self._async_cancel_retry_setup: Optional[Callable[[], Any]] = None self._async_cancel_retry_setup: Optional[Callable[[], Any]] = None
@ -414,7 +416,12 @@ class ConfigEntry:
Returns function to unlisten. Returns function to unlisten.
""" """
weak_listener = weakref.ref(listener) weak_listener: Any
# weakref.ref is not applicable to a bound method, e.g. 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) self.update_listeners.append(weak_listener)
return lambda: self.update_listeners.remove(weak_listener) return lambda: self.update_listeners.remove(weak_listener)