Fix data update coordinator garbage collection (#137299)

pull/137313/head
epenet 2025-02-04 11:20:06 +01:00 committed by GitHub
parent 4ce3fa8813
commit c3b40e681d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 0 deletions

View File

@ -146,6 +146,10 @@ class Debouncer[_R_co]:
"""Cancel any scheduled call, and prevent new runs."""
self._shutdown_requested = True
self.async_cancel()
# Release hard references to parent function
# https://github.com/home-assistant/core/issues/137237
self._function = None
self._job = None
@callback
def async_cancel(self) -> None:

View File

@ -4,6 +4,7 @@ import asyncio
from datetime import timedelta
import logging
from unittest.mock import AsyncMock, Mock
import weakref
import pytest
@ -529,3 +530,37 @@ async def test_background(
async_fire_time_changed(hass, utcnow() + timedelta(seconds=1))
await hass.async_block_till_done(wait_background_tasks=False)
assert len(calls) == 2
async def test_shutdown_releases_parent_class(hass: HomeAssistant) -> None:
"""Test shutdown releases parent class.
See https://github.com/home-assistant/core/issues/137237
"""
calls = []
class SomeClass:
def run_func(self) -> None:
calls.append(None)
my_class = SomeClass()
my_class_weak_ref = weakref.ref(my_class)
debouncer = debounce.Debouncer(
hass,
_LOGGER,
cooldown=0.01,
immediate=True,
function=my_class.run_func,
)
# Debouncer keeps a reference to the function, prevening GC
del my_class
await debouncer.async_call()
await hass.async_block_till_done()
assert len(calls) == 1
assert my_class_weak_ref() is not None
# Debouncer shutdown releases the class
debouncer.async_shutdown()
assert my_class_weak_ref() is None