From b018e3bc174abf6ec96b6c6ff88aff4bec286866 Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Fri, 16 Feb 2024 16:01:42 -0500 Subject: [PATCH 1/7] bug fix: properly clone tuples --- lenskit/util/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lenskit/util/__init__.py b/lenskit/util/__init__.py index 0ebe9619e..03a4d2333 100644 --- a/lenskit/util/__init__.py +++ b/lenskit/util/__init__.py @@ -60,8 +60,10 @@ def clone(algo): sps = dict([(k, clone(v)) for (k, v) in params.items()]) return algo.__class__(**sps) - elif isinstance(algo, list) or isinstance(algo, tuple): + elif isinstance(algo, list): return [clone(a) for a in algo] + elif isinstance(algo, tuple): + return tuple(clone(a) for a in algo) else: return deepcopy(algo) From c710d6bbbdec40fe8e36355b3769ae0e367bfa6c Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Fri, 16 Feb 2024 16:12:07 -0500 Subject: [PATCH 2/7] test the util.clone() method --- tests/test_bias.py | 16 ++++++++++++++++ tests/test_util.py | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/test_bias.py b/tests/test_bias.py index 50af8106a..cde6084f4 100644 --- a/tests/test_bias.py +++ b/tests/test_bias.py @@ -69,6 +69,22 @@ def test_bias_clone(): assert getattr(a2, "user_offsets_", None) is None +def test_bias_clone_damping(): + algo = Bias(damping=(10, 5)) + algo.fit(simple_df) + + params = algo.get_params() + assert sorted(params.keys()) == ["damping", "items", "users"] + + a2 = lku.clone(algo) + assert a2 is not algo + assert getattr(a2, "item_damping", None) == 5 + assert getattr(a2, "user_damping", None) == 10 + assert getattr(a2, "mean_", None) is None + assert getattr(a2, "item_offsets_", None) is None + assert getattr(a2, "user_offsets_", None) is None + + def test_bias_global_only(): algo = Bias(users=False, items=False) algo.fit(simple_df) diff --git a/tests/test_util.py b/tests/test_util.py index 18bf34630..49e738f60 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -10,6 +10,8 @@ import numpy as np import pandas as pd +from hypothesis import given +from hypothesis import strategies as st from lenskit import util as lku @@ -80,3 +82,18 @@ def func(foo): assert len(history) == 1 cache("bar") assert len(history) == 2 + + +@given( + st.one_of( + st.lists(st.floats(allow_nan=False)), + st.tuples(st.floats(allow_nan=False)), + st.integers(), + st.floats(allow_nan=False), + st.emails(), + ) +) +def test_clone_core_obj(obj): + o2 = lku.clone(obj) + assert o2 == obj + assert type(o2) == type(obj) From b72137afa10f7c8881465b61d1b83fb5ebe0e35a Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Sun, 3 Mar 2024 14:31:14 -0500 Subject: [PATCH 3/7] format fifx --- tests/test_util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_util.py b/tests/test_util.py index 49e738f60..acf8123df 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -4,12 +4,13 @@ # Licensed under the MIT license, see LICENSE.md for details. # SPDX-License-Identifier: MIT -import time -import re import pathlib +import re +import time import numpy as np import pandas as pd + from hypothesis import given from hypothesis import strategies as st From c507d0d746de46d77826924b796bcec970a39521 Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Sun, 3 Mar 2024 14:32:47 -0500 Subject: [PATCH 4/7] refine clone test limits --- tests/test_util.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_util.py b/tests/test_util.py index acf8123df..03bb1327b 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -87,10 +87,14 @@ def func(foo): @given( st.one_of( - st.lists(st.floats(allow_nan=False)), - st.tuples(st.floats(allow_nan=False)), st.integers(), st.floats(allow_nan=False), + st.lists(st.floats(allow_nan=False), max_size=100), + st.tuples(st.floats(allow_nan=False)), + st.tuples(st.floats(allow_nan=False), st.floats(allow_nan=False)), + st.tuples( + st.floats(allow_nan=False), st.floats(allow_nan=False), st.floats(allow_nan=False) + ), st.emails(), ) ) From 680ff70e5013cc277ef78d4b4d85658fb34658e6 Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Sun, 3 Mar 2024 15:35:23 -0500 Subject: [PATCH 5/7] suppress health check for clone test --- tests/test_util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_util.py b/tests/test_util.py index 03bb1327b..cf163b711 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -11,7 +11,7 @@ import numpy as np import pandas as pd -from hypothesis import given +from hypothesis import HealthCheck, given, settings from hypothesis import strategies as st from lenskit import util as lku @@ -85,6 +85,7 @@ def func(foo): assert len(history) == 2 +@settings(suppress_health_check=[HealthCheck.too_slow]) @given( st.one_of( st.integers(), From 59839f893c9481603a98c3fd0602fdc45c69fde8 Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Sun, 3 Mar 2024 15:35:34 -0500 Subject: [PATCH 6/7] add asserts for stopwatch stop tests --- tests/test_util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_util.py b/tests/test_util.py index cf163b711..4bf0264e7 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -53,6 +53,7 @@ def test_stopwatch_long_str(): def test_stopwatch_minutes(): w = lku.Stopwatch() w.stop() + assert w.stop_time is not None w.start_time = w.stop_time - 62 s = str(w) p = re.compile(r"1m2.\d\ds") @@ -62,6 +63,7 @@ def test_stopwatch_minutes(): def test_stopwatch_hours(): w = lku.Stopwatch() w.stop() + assert w.stop_time is not None w.start_time = w.stop_time - 3663 s = str(w) p = re.compile(r"1h1m3.\d\ds") From 47ac74a1e51fdea597200d6beb3e758e01121385 Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Sun, 3 Mar 2024 15:35:43 -0500 Subject: [PATCH 7/7] remove unused improts --- tests/test_util.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/test_util.py b/tests/test_util.py index 4bf0264e7..34d408998 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -4,13 +4,9 @@ # Licensed under the MIT license, see LICENSE.md for details. # SPDX-License-Identifier: MIT -import pathlib import re import time -import numpy as np -import pandas as pd - from hypothesis import HealthCheck, given, settings from hypothesis import strategies as st