From 291ff9772be32007b7ddec314c209990751ce860 Mon Sep 17 00:00:00 2001 From: Sassan Haradji Date: Fri, 22 Mar 2024 04:11:26 +0400 Subject: [PATCH] fix: automatically unsubscribe autoruns when the weakref is dead --- CHANGELOG.md | 4 ++++ pyproject.toml | 2 +- redux/autorun.py | 6 ++++-- tests/test_weakref.py | 2 ++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20e2231..fb22075 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Version 0.12.7 + +- fix: automatically unsubscribe autoruns when the weakref is dead + ## Version 0.12.6 - refactor: drop logging fixture and use standard pytest logger in tests diff --git a/pyproject.toml b/pyproject.toml index c05862b..8f7275f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "python-redux" -version = "0.12.6" +version = "0.12.7" description = "Redux implementation for Python" authors = ["Sassan Haradji "] license = "Apache-2.0" diff --git a/redux/autorun.py b/redux/autorun.py index 6c70349..bf44852 100644 --- a/redux/autorun.py +++ b/redux/autorun.py @@ -51,7 +51,7 @@ def __init__( # noqa: PLR0913 elif inspect.ismethod(func): self._func = weakref.WeakMethod(func) else: - self._func = weakref.ref(func) + self._func = weakref.ref(func, lambda _: self.unsubscribe()) self._options = options self._last_selector_result: SelectorOutput | None = None @@ -68,7 +68,7 @@ def __init__( # noqa: PLR0913 if self._options.initial_run and store._state is not None: # noqa: SLF001 self._check_and_call(store._state) # noqa: SLF001 - store.subscribe(self._check_and_call, keep_ref=options.keep_ref) + self.unsubscribe = store.subscribe(self._check_and_call) def inform_subscribers( self: Autorun[ @@ -175,6 +175,8 @@ def _check_and_call( ) else: self.inform_subscribers() + else: + self.unsubscribe() def __call__( self: Autorun[ diff --git a/tests/test_weakref.py b/tests/test_weakref.py index 1e9c57d..ec162f6 100644 --- a/tests/test_weakref.py +++ b/tests/test_weakref.py @@ -1,6 +1,7 @@ # ruff: noqa: D100, D101, D102, D103, D104, D107 from __future__ import annotations +import gc import weakref from dataclasses import replace from typing import TYPE_CHECKING, Generator @@ -115,6 +116,7 @@ def render_without_keep_ref(_: int) -> int: ref = weakref.ref(render_without_keep_ref) del render_without_keep_ref + gc.collect() assert ref() is None store.dispatch(IncrementAction())