diff --git a/atools/memoize_decorator.py b/atools/memoize_decorator.py index 1e54ea3..e757e35 100644 --- a/atools/memoize_decorator.py +++ b/atools/memoize_decorator.py @@ -6,7 +6,7 @@ import inspect from time import time from threading import Lock as SyncLock -from typing import Any, Optional, Tuple, Union +from typing import Any, Optional, Union class _MemoZeroValue: @@ -74,15 +74,15 @@ def reset(self) -> None: self._memos = OrderedDict() self._expire_order = deque() if self._expire_order is not None else None - def make_key(self, *args, **kwargs) -> Tuple: + def make_key(self, *args, **kwargs) -> int: """Returns all params (args, kwargs, and missing default kwargs) for function as kwargs.""" args_as_kwargs = {} for k, v in zip(self._default_kwargs, args): args_as_kwargs[k] = v - return tuple(ChainMap(args_as_kwargs, kwargs, self._default_kwargs).values()) + return hash(tuple(ChainMap(args_as_kwargs, kwargs, self._default_kwargs).values())) - def get_memo(self, key) -> _Memo: + def get_memo(self, key: int) -> _Memo: try: memo = self._memos[key] = self._memos.pop(key) if self._duration is not None and memo.expire_time < time(): diff --git a/setup.py b/setup.py index 3a2fd23..d029798 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='atools', - version='0.6.0', + version='0.6.1', packages=['', 'atools'], python_requires='>=3.6', url='https://github.com/cevans87/atools', diff --git a/test/test_memoize_decorator.py b/test/test_memoize_decorator.py index f1f515d..877f0a9 100644 --- a/test/test_memoize_decorator.py +++ b/test/test_memoize_decorator.py @@ -5,6 +5,7 @@ from datetime import timedelta import unittest from unittest.mock import call, MagicMock, patch +from weakref import ref @async_test_case @@ -465,11 +466,21 @@ async def foo() -> int: self.assertEqual(foo_a, foo_b) - #async def test_memoize_does_not_stop_object_cleanup(self) -> None: - # # TODO make an object, memoize a funciton with that object, and then convert local - # # variable to a weakref. Assert that the object is cleaned up. + async def test_memoize_does_not_stop_object_cleanup(self) -> None: + class Foo: + pass + + @memoize + def foo(_: Foo) -> None: + ... + + f = Foo() + foo(f) - # raise Exception() + r = ref(f) + assert r() is not None + del f + assert r() is None if __name__ == '__main__':