From 538e5643118f51393fcf4ff13a7e38b34a78ac86 Mon Sep 17 00:00:00 2001 From: Cameron Evans Date: Thu, 26 Mar 2020 14:46:00 -0700 Subject: [PATCH] Fix accidental removal of HEAD^^ in HEAD^ --- atools/_memoize_decorator.py | 2 +- setup.py | 2 +- test/test_memoize_decorator.py | 36 ++++++++++++++++++++++------------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/atools/_memoize_decorator.py b/atools/_memoize_decorator.py index 7700beb..a76105a 100644 --- a/atools/_memoize_decorator.py +++ b/atools/_memoize_decorator.py @@ -113,7 +113,7 @@ def table_name(self) -> str: def bind_key_lifetime(self, raw_key: Tuple[Any, ...], key: Union[int, str]) -> None: for raw_key_part in raw_key: - if type(raw_key_part).__hash__ is object.__hash__: + if (raw_key_part is not None) and (type(raw_key_part).__hash__ is object.__hash__): finalize(raw_key_part, self.reset_key, key) def default_keygen(self, *args, **kwargs) -> Tuple[Hashable, ...]: diff --git a/setup.py b/setup.py index b998439..1a88c11 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='atools', - version='0.13.0', + version='0.13.1', packages=find_packages(), 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 6655933..3702abf 100644 --- a/test/test_memoize_decorator.py +++ b/test/test_memoize_decorator.py @@ -55,6 +55,18 @@ def foo() -> None: assert body.call_count == 1 +def test_none_arg() -> None: + body = MagicMock() + + @memoize + def foo(_bar) -> None: + body() + + foo(None) + foo(None) + assert body.call_count == 1 + + def test_class_function() -> None: body = MagicMock() @@ -73,7 +85,7 @@ def foo(self) -> None: f.foo() f.foo() body.assert_called_once() - + def test_keyword_same_as_default() -> None: body = MagicMock() @@ -571,7 +583,7 @@ def test_memoize_class_preserves_doc() -> None: @memoize class Foo: """Foo doc""" - + assert Foo.__doc__ == "Foo doc" @@ -581,7 +593,7 @@ def test_keygen_overrides_default() -> None: @memoize(keygen=lambda bar, baz: (bar,)) def foo(bar: int, baz: int) -> int: body(bar, baz) - + return bar + baz assert foo(2, 2) == 4 @@ -592,12 +604,12 @@ def foo(bar: int, baz: int) -> int: @pytest.mark.asyncio async def test_keygen_awaits_awaitable_parts() -> None: - + key_part_body = MagicMock() async def key_part(bar: int, baz: int) -> Tuple[Hashable, ...]: key_part_body(bar, baz) - + return bar, body = MagicMock() @@ -612,7 +624,7 @@ async def foo(bar: int, baz: int) -> int: # noinspection PyArgumentEqualDefault assert await foo(2, 200) == 4 body.assert_called_once_with(2, 2) - + assert key_part_body.call_count == 2 key_part_body.assert_has_calls( [call(2, 2), call(2, 200)] @@ -620,7 +632,7 @@ async def foo(bar: int, baz: int) -> int: def test_db_creates_table_for_each_decorator(db_path: Path) -> None: - + assert get_table_len(db_path) == 0 @memoize(db_path=db_path) @@ -638,7 +650,7 @@ def bar() -> None: def test_db_reloads_values_from_disk(db_path: Path) -> None: body = MagicMock() - + def foo() -> None: @memoize(db_path=db_path) @@ -649,7 +661,7 @@ def foo_inner() -> None: foo() foo() - + assert body.call_count == 1 @@ -702,7 +714,7 @@ def _foo(_i: int) -> None: for i in range(10): foo(i) assert len(foo.memoize) == 10 - + foo = get_foo() assert len(foo.memoize) == 10 @@ -722,8 +734,8 @@ def foo_inner(_i: int) -> None: assert body.call_count == 10 foo(reversed(range(10))) assert body.call_count == 15 - - + + def test_db_with_duration_expires_stale_values( db_path: Path, time: MagicMock,