From 66c1b0f9ee7259a7cbb128782a1ece43932f68f8 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Tue, 11 Oct 2022 21:05:36 -0700 Subject: [PATCH 1/7] Add type-hints to setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 08a7948f5..21c3191d8 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,6 @@ def get_version_and_cmdclass(package_name): "holoviews>=1.9.1", "ipywidgets", "bokeh", - "pandas", "matplotlib", "plotly", ], @@ -53,6 +52,7 @@ def get_version_and_cmdclass(package_name): "pytest-randomly", "pytest-timeout", "pre_commit", + "pandas", "typeguard", ], "other": [ From 689e9137c227a2df08cd9e4c810b3392887455c9 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Tue, 11 Oct 2022 21:05:35 -0700 Subject: [PATCH 2/7] Add type-hints to adaptive/utils.py --- adaptive/utils.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/adaptive/utils.py b/adaptive/utils.py index a98af12a1..2c34f1778 100644 --- a/adaptive/utils.py +++ b/adaptive/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import abc import functools import gzip @@ -5,20 +7,21 @@ import os import pickle import warnings -from contextlib import contextmanager +from contextlib import _GeneratorContextManager, contextmanager from itertools import product +from typing import Any, Callable, Mapping, Sequence import cloudpickle -def named_product(**items): +def named_product(**items: Mapping[str, Sequence[Any]]): names = items.keys() vals = items.values() return [dict(zip(names, res)) for res in product(*vals)] @contextmanager -def restore(*learners): +def restore(*learners) -> _GeneratorContextManager: states = [learner.__getstate__() for learner in learners] try: yield @@ -27,7 +30,7 @@ def restore(*learners): learner.__setstate__(state) -def cache_latest(f): +def cache_latest(f: Callable) -> Callable: """Cache the latest return value of the function and add it as 'self._cache[f.__name__]'.""" @@ -42,7 +45,7 @@ def wrapper(*args, **kwargs): return wrapper -def save(fname, data, compress=True): +def save(fname: str, data: Any, compress: bool = True) -> None: fname = os.path.expanduser(fname) dirname = os.path.dirname(fname) if dirname: @@ -71,14 +74,14 @@ def save(fname, data, compress=True): return True -def load(fname, compress=True): +def load(fname: str, compress: bool = True): fname = os.path.expanduser(fname) _open = gzip.open if compress else open with _open(fname, "rb") as f: return cloudpickle.load(f) -def copy_docstring_from(other): +def copy_docstring_from(other: Callable) -> Callable: def decorator(method): return functools.wraps(other)(method) From b1e90a1701ca4a2db0cddb47b09ec75761dbcd5e Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Tue, 11 Oct 2022 21:05:34 -0700 Subject: [PATCH 3/7] Add type-hints to adaptive/types.py --- adaptive/types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/adaptive/types.py b/adaptive/types.py index e2d57a44f..67268f822 100644 --- a/adaptive/types.py +++ b/adaptive/types.py @@ -11,3 +11,4 @@ Float: TypeAlias = Union[float, np.float_] Int: TypeAlias = Union[int, np.int_] Real: TypeAlias = Union[Float, Int] +Bool: TypeAlias = Union[bool, np.bool_] From 38ee0f8a41fc4cc430faa945d2db1f8ea4cc524c Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Tue, 11 Oct 2022 21:05:33 -0700 Subject: [PATCH 4/7] Add type-hints to adaptive/tests/test_learners.py --- adaptive/tests/test_learners.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/adaptive/tests/test_learners.py b/adaptive/tests/test_learners.py index d393511fb..8c616e6bb 100644 --- a/adaptive/tests/test_learners.py +++ b/adaptive/tests/test_learners.py @@ -12,6 +12,7 @@ import flaky import numpy as np +import pandas import pytest import scipy.spatial @@ -27,7 +28,6 @@ LearnerND, SequenceLearner, ) -from adaptive.learner.learner1D import with_pandas from adaptive.runner import simple try: @@ -708,7 +708,6 @@ def wrapper(*args, **kwargs): return wrapper -@pytest.mark.skipif(not with_pandas, reason="pandas is not installed") @run_with( Learner1D, Learner2D, @@ -720,8 +719,6 @@ def wrapper(*args, **kwargs): with_all_loss_functions=False, ) def test_to_dataframe(learner_type, f, learner_kwargs): - import pandas - if learner_type is LearnerND: kw = {"point_names": tuple("xyz")[: len(learner_kwargs["bounds"])]} else: From f864e405687ddd8fb8b5eb7825a2a1c74c14700f Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Tue, 11 Oct 2022 21:05:32 -0700 Subject: [PATCH 5/7] Add type-hints to adaptive/tests/test_learner1d.py --- adaptive/tests/test_learner1d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adaptive/tests/test_learner1d.py b/adaptive/tests/test_learner1d.py index 59a8b81a8..7e990bd7b 100644 --- a/adaptive/tests/test_learner1d.py +++ b/adaptive/tests/test_learner1d.py @@ -277,8 +277,8 @@ def f_vec(x, offset=0.123214): def assert_equal_dicts(d1, d2): xs1, ys1 = zip(*sorted(d1.items())) xs2, ys2 = zip(*sorted(d2.items())) - ys1 = np.array(ys1, dtype=np.float) - ys2 = np.array(ys2, dtype=np.float) + ys1 = np.array(ys1, dtype=np.float64) + ys2 = np.array(ys2, dtype=np.float64) np.testing.assert_almost_equal(xs1, xs2) np.testing.assert_almost_equal(ys1, ys2) From 97c85b9c05d635691a7451bcaaa728c57d9f2e8f Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Tue, 11 Oct 2022 21:05:31 -0700 Subject: [PATCH 6/7] Add type-hints to adaptive/tests/test_average_learner1d.py --- adaptive/tests/test_average_learner1d.py | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/adaptive/tests/test_average_learner1d.py b/adaptive/tests/test_average_learner1d.py index 8b2670d77..4286f55b9 100644 --- a/adaptive/tests/test_average_learner1d.py +++ b/adaptive/tests/test_average_learner1d.py @@ -1,6 +1,6 @@ -from itertools import chain - import numpy as np +import pandas as pd +from pandas.testing import assert_series_equal from adaptive import AverageLearner1D from adaptive.tests.test_learners import ( @@ -11,27 +11,13 @@ def almost_equal_dicts(a, b): - assert a.keys() == b.keys() - for k, v1 in a.items(): - v2 = b[k] - if ( - v1 is None - or v2 is None - or isinstance(v1, (tuple, list)) - and any(x is None for x in chain(v1, v2)) - ): - assert v1 == v2 - else: - try: - np.testing.assert_almost_equal(v1, v2) - except TypeError: - raise AssertionError(f"{v1} != {v2}") + assert_series_equal(pd.Series(sorted(a.items())), pd.Series(sorted(b.items()))) def test_tell_many_at_point(): f = generate_random_parametrization(noisy_peak) learner = AverageLearner1D(f, bounds=(-2, 2)) - control = learner.new() + control = AverageLearner1D(f, bounds=(-2, 2)) learner._recompute_losses_factor = 1 control._recompute_losses_factor = 1 simple_run(learner, 100) From ea30a4912656dc008818c36ab2d100566cf86961 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Tue, 11 Oct 2022 21:05:28 -0700 Subject: [PATCH 7/7] Add type-hints to adaptive/notebook_integration.py --- adaptive/notebook_integration.py | 4 +++- adaptive/tests/test_average_learner1d.py | 22 ++++++++++++++++++---- adaptive/tests/test_learners.py | 5 ++++- adaptive/utils.py | 4 ++-- setup.py | 2 +- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/adaptive/notebook_integration.py b/adaptive/notebook_integration.py index 426c04541..60329110e 100644 --- a/adaptive/notebook_integration.py +++ b/adaptive/notebook_integration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import asyncio import datetime import importlib @@ -76,7 +78,7 @@ def ensure_plotly(): raise RuntimeError("plotly is not installed; plotting is disabled.") -def in_ipynb(): +def in_ipynb() -> bool: try: # If we are running in IPython, then `get_ipython()` is always a global return get_ipython().__class__.__name__ == "ZMQInteractiveShell" diff --git a/adaptive/tests/test_average_learner1d.py b/adaptive/tests/test_average_learner1d.py index 4286f55b9..8b2670d77 100644 --- a/adaptive/tests/test_average_learner1d.py +++ b/adaptive/tests/test_average_learner1d.py @@ -1,6 +1,6 @@ +from itertools import chain + import numpy as np -import pandas as pd -from pandas.testing import assert_series_equal from adaptive import AverageLearner1D from adaptive.tests.test_learners import ( @@ -11,13 +11,27 @@ def almost_equal_dicts(a, b): - assert_series_equal(pd.Series(sorted(a.items())), pd.Series(sorted(b.items()))) + assert a.keys() == b.keys() + for k, v1 in a.items(): + v2 = b[k] + if ( + v1 is None + or v2 is None + or isinstance(v1, (tuple, list)) + and any(x is None for x in chain(v1, v2)) + ): + assert v1 == v2 + else: + try: + np.testing.assert_almost_equal(v1, v2) + except TypeError: + raise AssertionError(f"{v1} != {v2}") def test_tell_many_at_point(): f = generate_random_parametrization(noisy_peak) learner = AverageLearner1D(f, bounds=(-2, 2)) - control = AverageLearner1D(f, bounds=(-2, 2)) + control = learner.new() learner._recompute_losses_factor = 1 control._recompute_losses_factor = 1 simple_run(learner, 100) diff --git a/adaptive/tests/test_learners.py b/adaptive/tests/test_learners.py index 8c616e6bb..d393511fb 100644 --- a/adaptive/tests/test_learners.py +++ b/adaptive/tests/test_learners.py @@ -12,7 +12,6 @@ import flaky import numpy as np -import pandas import pytest import scipy.spatial @@ -28,6 +27,7 @@ LearnerND, SequenceLearner, ) +from adaptive.learner.learner1D import with_pandas from adaptive.runner import simple try: @@ -708,6 +708,7 @@ def wrapper(*args, **kwargs): return wrapper +@pytest.mark.skipif(not with_pandas, reason="pandas is not installed") @run_with( Learner1D, Learner2D, @@ -719,6 +720,8 @@ def wrapper(*args, **kwargs): with_all_loss_functions=False, ) def test_to_dataframe(learner_type, f, learner_kwargs): + import pandas + if learner_type is LearnerND: kw = {"point_names": tuple("xyz")[: len(learner_kwargs["bounds"])]} else: diff --git a/adaptive/utils.py b/adaptive/utils.py index 2c34f1778..465883188 100644 --- a/adaptive/utils.py +++ b/adaptive/utils.py @@ -45,7 +45,7 @@ def wrapper(*args, **kwargs): return wrapper -def save(fname: str, data: Any, compress: bool = True) -> None: +def save(fname: str, data: Any, compress: bool = True) -> bool: fname = os.path.expanduser(fname) dirname = os.path.dirname(fname) if dirname: @@ -74,7 +74,7 @@ def save(fname: str, data: Any, compress: bool = True) -> None: return True -def load(fname: str, compress: bool = True): +def load(fname: str, compress: bool = True) -> Any: fname = os.path.expanduser(fname) _open = gzip.open if compress else open with _open(fname, "rb") as f: diff --git a/setup.py b/setup.py index 21c3191d8..08a7948f5 100644 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ def get_version_and_cmdclass(package_name): "holoviews>=1.9.1", "ipywidgets", "bokeh", + "pandas", "matplotlib", "plotly", ], @@ -52,7 +53,6 @@ def get_version_and_cmdclass(package_name): "pytest-randomly", "pytest-timeout", "pre_commit", - "pandas", "typeguard", ], "other": [