From 61db0ff4f349ae369cec62d8dbc442bf4d14671f Mon Sep 17 00:00:00 2001 From: AdrianSosic Date: Fri, 2 Aug 2024 16:18:14 +0200 Subject: [PATCH 1/6] Expire deprecations from 0.7.2 --- CHANGELOG.md | 5 +++ baybe/campaign.py | 12 ------ baybe/deprecation.py | 49 ---------------------- baybe/targets/base.py | 27 +----------- baybe/utils/interval.py | 11 ----- docs/templates/custom-module-template.rst | 2 +- tests/test_deprecations.py | 51 +---------------------- 7 files changed, 9 insertions(+), 148 deletions(-) delete mode 100644 baybe/deprecation.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 131a443a2..259e7eaf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `SearchSpace`, `SubspaceDiscrete` and `SubspaceContinuous` is no longer possible. The dataframe must now be passed as positional argument. +### Expired Deprecations (from 0.7.*) +- `Interval.is_finite` property +- Specifying target configs without explicit type information +- Specifying parameters/constraints at the top level of a campaign configuration JSON + ## [0.9.1] - 2024-06-04 ### Changed - Discrete searchspace memory estimate is now natively represented in bytes diff --git a/baybe/campaign.py b/baybe/campaign.py index 84440a9ea..01cef8acf 100644 --- a/baybe/campaign.py +++ b/baybe/campaign.py @@ -149,13 +149,7 @@ def from_config(cls, config_json: str) -> Campaign: Returns: The constructed campaign. """ - from baybe.deprecation import compatibilize_config - config = json.loads(config_json) - - # Temporarily enable backward compatibility - config = compatibilize_config(config) - return converter.structure(config, Campaign) @classmethod @@ -165,13 +159,7 @@ def validate_config(cls, config_json: str) -> None: Args: config_json: The JSON that should be validated. """ - from baybe.deprecation import compatibilize_config - config = json.loads(config_json) - - # Temporarily enable backward compatibility - config = compatibilize_config(config) - _validation_converter.structure(config, Campaign) def add_measurements( diff --git a/baybe/deprecation.py b/baybe/deprecation.py deleted file mode 100644 index e8cd190cf..000000000 --- a/baybe/deprecation.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Temporary name aliases for backward compatibility.""" - -import warnings - - -def compatibilize_config(config: dict) -> dict: - """Turn a legacy-format config into the new format.""" - if "parameters" not in config: - return config - - if "searchspace" in config: - raise ValueError( - "Something is wrong with your campaign config. " - "It neither adheres to the deprecated nor the new format." - ) - - warnings.warn( - ''' - Specifying parameters/constraints at the top level of the - campaign configuration JSON is deprecated and will not be - supported in future releases. - Instead, use a dedicated "searchspace" field that can be - used to customize the creation of the search space, - offering the possibility to specify a desired constructor. - - To replicate the old behavior, use - """ - ... - "searchspace": { - "constructor": "from_product", - "parameters": , - "constraints": - } - ... - """ - - For the available constructors and the parameters they expect, - see `baybe.searchspace.core.SearchSpace`.''', - UserWarning, - ) - - config = config.copy() - config["searchspace"] = { - "constructor": "from_product", - "parameters": config.pop("parameters"), - "constraints": config.pop("constraints", None), - } - - return config diff --git a/baybe/targets/base.py b/baybe/targets/base.py index 615c325ba..22b3b48da 100644 --- a/baybe/targets/base.py +++ b/baybe/targets/base.py @@ -2,7 +2,6 @@ from __future__ import annotations -import warnings from abc import ABC, abstractmethod from typing import TYPE_CHECKING @@ -58,30 +57,6 @@ def __str__(self) -> str: return str(self.summary()) -def _add_missing_type_hook(hook): - """Adjust the structuring hook such that it auto-fills missing target types. - - Used for backward compatibility only and will be removed in future versions. - """ - - def added_type_hook(dict_, cls): - if "type" not in dict_: - warnings.warn( - f"The target type is not specified for target '{dict_['name']}' and " - f"thus automatically set to 'NumericalTarget'. " - f"However, omitting the target type is deprecated and will no longer " - f"be supported in future versions. " - f"Therefore, please add an explicit target type.", - DeprecationWarning, - ) - dict_["type"] = "NumericalTarget" - return hook(dict_, cls) - - return added_type_hook - - # Register (un-)structure hooks -converter.register_structure_hook( - Target, _add_missing_type_hook(get_base_structure_hook(Target)) -) +converter.register_structure_hook(Target, get_base_structure_hook(Target)) converter.register_unstructure_hook(Target, unstructure_base) diff --git a/baybe/utils/interval.py b/baybe/utils/interval.py index 0a4ea8d9e..0b09599de 100644 --- a/baybe/utils/interval.py +++ b/baybe/utils/interval.py @@ -1,6 +1,5 @@ """Utilities for handling intervals.""" -import warnings from collections.abc import Iterable from functools import singledispatchmethod from typing import TYPE_CHECKING, Any @@ -75,16 +74,6 @@ def is_fully_unbounded(self) -> bool: """Check if the interval represents the entire real number line.""" return not (self.is_left_bounded or self.is_right_bounded) - @property - def is_finite(self) -> bool: - """Check whether the interval is finite.""" - warnings.warn( - "The use of 'Interval.is_finite' is deprecated and will be disabled in " - "a future version. Use 'Interval.is_bounded' instead.", - DeprecationWarning, - ) - return np.isfinite(self.lower) and np.isfinite(self.upper) - @property def center(self) -> float | None: """The center of the interval, or ``None`` if the interval is unbounded.""" diff --git a/docs/templates/custom-module-template.rst b/docs/templates/custom-module-template.rst index 5bfe28f31..931bc18d8 100644 --- a/docs/templates/custom-module-template.rst +++ b/docs/templates/custom-module-template.rst @@ -61,7 +61,7 @@ :template: custom-module-template.rst :recursive: {% for item in modules %} -{% if not item in ("baybe.deprecation", "baybe.strategies.deprecation", "baybe.objectives.deprecation", "baybe.recommenders.pure.bayesian.sequential_greedy") %} +{% if not item in ("baybe.strategies.deprecation", "baybe.objectives.deprecation", "baybe.recommenders.pure.bayesian.sequential_greedy") %} {{ item }} {%- endif %} {%- endfor %} diff --git a/tests/test_deprecations.py b/tests/test_deprecations.py index cfd2fff76..0effd7bb4 100644 --- a/tests/test_deprecations.py +++ b/tests/test_deprecations.py @@ -30,9 +30,7 @@ StreamingSequentialStrategy, TwoPhaseStrategy, ) -from baybe.targets.base import Target from baybe.targets.numerical import NumericalTarget -from baybe.utils.interval import Interval def test_missing_recommender_type(config): @@ -64,53 +62,6 @@ def test_deprecated_strategies(test_objects): strategy(**arguments) -def test_deprecated_interval_is_finite(): - """Using the deprecated ``Interval.is_finite`` property raises a warning.""" - with pytest.warns(DeprecationWarning): - Interval(0, 1).is_finite - - -def test_missing_target_type(): - """Specifying a target without a corresponding type raises a warning.""" - with pytest.warns(DeprecationWarning): - Target.from_json( - json.dumps( - { - "name": "missing_type", - "mode": "MAX", - } - ) - ) - - -old_style_config = """ -{ - "parameters": [ - { - "type": "CategoricalParameter", - "name": "Granularity", - "values": ["coarse", "fine", "ultra-fine"] - } - ], - "objective": { - "mode": "SINGLE", - "targets": [ - { - "name": "Yield", - "mode": "MAX" - } - ] - } -} -""" - - -def test_deprecated_config(): - """Using the deprecated config format raises a warning.""" - with pytest.warns(UserWarning): - Campaign.from_config(old_style_config) - - @pytest.mark.parametrize("flag", [False, True]) def test_deprecated_campaign_tolerance_flag(flag): """Constructing a Campaign with the deprecated tolerance flag raises an error.""" @@ -160,11 +111,13 @@ def test_deprecated_objective_class(): "mode": "DESIRABILITY", "targets": [ { + "type": "NumericalTarget", "name": "Yield", "mode": "MAX", "bounds": [0, 1] }, { + "type": "NumericalTarget", "name": "Waste", "mode": "MIN", "bounds": [0, 1] From 6371d976a07ffc0b44de9af87a71b6d5dc8d0bbe Mon Sep 17 00:00:00 2001 From: AdrianSosic Date: Fri, 2 Aug 2024 16:26:31 +0200 Subject: [PATCH 2/6] Expire deprecations from 0.7.3 --- CHANGELOG.md | 4 ++++ baybe/campaign.py | 24 ------------------------ baybe/recommenders/meta/base.py | 31 +------------------------------ tests/test_deprecations.py | 28 ---------------------------- 4 files changed, 5 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 259e7eaf5..683eda961 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Interval.is_finite` property - Specifying target configs without explicit type information - Specifying parameters/constraints at the top level of a campaign configuration JSON +- Passing `numerical_measurements_must_be_within_tolerance` to `Campaign` +- `batch_quantity` argument +- Passing `allow_repeated_recommendations` or `allow_recommending_already_measured` + to `MetaRecommender` (or former `Strategy`) ## [0.9.1] - 2024-06-04 ### Changed diff --git a/baybe/campaign.py b/baybe/campaign.py index 01cef8acf..2359479fc 100644 --- a/baybe/campaign.py +++ b/baybe/campaign.py @@ -83,10 +83,6 @@ class Campaign(SerialMixin): ) """The cached recommendations.""" - # Deprecation - numerical_measurements_must_be_within_tolerance: bool = field(default=None) - """Deprecated! Raises an error when used.""" - def __str__(self) -> str: start_bold = "\033[1m" end_bold = "\033[0m" @@ -105,16 +101,6 @@ def __str__(self) -> str: strategy: RecommenderProtocol = field(default=None) """Deprecated! Raises an error when used.""" - @numerical_measurements_must_be_within_tolerance.validator - def _validate_tolerance_flag(self, _, value) -> None: - """Raise a DeprecationError if the tolerance flag is used.""" - if value is not None: - raise DeprecationError( - f"Passing 'numerical_measurements_must_be_within_tolerance' to " - f"the constructor is deprecated. The flag has become a parameter of " - f"{self.__class__.__name__}.{Campaign.add_measurements.__name__}." - ) - @strategy.validator def _validate_strategy(self, _, value) -> None: """Raise a DeprecationError if the strategy attribute is used.""" @@ -243,13 +229,11 @@ def add_measurements( def recommend( self, batch_size: int, - batch_quantity: int = None, # type: ignore[assignment] ) -> pd.DataFrame: """Provide the recommendations for the next batch of experiments. Args: batch_size: Number of requested recommendations. - batch_quantity: Deprecated! Use ``batch_size`` instead. Returns: Dataframe containing the recommendations in experimental representation. @@ -257,13 +241,6 @@ def recommend( Raises: ValueError: If ``batch_size`` is smaller than 1. """ - if batch_quantity is not None: - raise DeprecationError( - f"Passing the keyword 'batch_quantity' to " - f"'{self.__class__.__name__}.{self.recommend.__name__}' is deprecated. " - f"Use 'batch_size' instead." - ) - if batch_size < 1: raise ValueError( f"You must at least request one recommendation per batch, but provided " @@ -317,7 +294,6 @@ def _drop_version(dict_: dict) -> dict: converter, _cattrs_include_init_false=True, # TODO: Remove once deprecation got expired: - numerical_measurements_must_be_within_tolerance=cattrs.override(omit=True), strategy=cattrs.override(omit=True), ) structure_hook = cattrs.gen.make_dict_structure_fn( diff --git a/baybe/recommenders/meta/base.py b/baybe/recommenders/meta/base.py index 825bb0ede..92d4f5cf4 100644 --- a/baybe/recommenders/meta/base.py +++ b/baybe/recommenders/meta/base.py @@ -5,9 +5,8 @@ import cattrs import pandas as pd -from attrs import define, field +from attrs import define -from baybe.exceptions import DeprecationError from baybe.objectives.base import Objective from baybe.recommenders.base import RecommenderProtocol from baybe.recommenders.deprecation import structure_recommender_protocol @@ -21,34 +20,6 @@ class MetaRecommender(SerialMixin, RecommenderProtocol, ABC): """Abstract base class for all meta recommenders.""" - allow_repeated_recommendations: bool = field(default=None, kw_only=True) - """Deprecated! The flag has become an attribute of - :class:`baybe.recommenders.pure.base.PureRecommender`.""" - - allow_recommending_already_measured: bool = field(default=None, kw_only=True) - """Deprecated! The flag has become an attribute of - :class:`baybe.recommenders.pure.base.PureRecommender`.""" - - @allow_repeated_recommendations.validator - def _validate_allow_repeated_recommendations(self, _, value): - """Raise a ``DeprecationError`` if the flag is used.""" - if value is not None: - raise DeprecationError( - f"Passing 'allow_repeated_recommendations' to " - f"'{self.__class__.__name__}' is deprecated. The flag has become an " - f"attribute of the '{PureRecommender.__name__}' classes." - ) - - @allow_recommending_already_measured.validator - def _validate_allow_recommending_already_measured(self, _, value): - """Raise a ``DeprecationError`` if the flag is used.""" - if value is not None: - raise DeprecationError( - f"Passing 'allow_recommending_already_measured' to " - f"{self.__class__.__name__} is deprecated. The flag has become an " - f"attribute of {PureRecommender.__name__}." - ) - @abstractmethod def select_recommender( self, diff --git a/tests/test_deprecations.py b/tests/test_deprecations.py index 0effd7bb4..f11837495 100644 --- a/tests/test_deprecations.py +++ b/tests/test_deprecations.py @@ -14,7 +14,6 @@ from baybe.objectives.desirability import DesirabilityObjective from baybe.parameters.numerical import NumericalContinuousParameter from baybe.recommenders.base import RecommenderProtocol -from baybe.recommenders.meta.sequential import TwoPhaseMetaRecommender from baybe.recommenders.pure.bayesian import ( BotorchRecommender, SequentialGreedyRecommender, @@ -62,33 +61,6 @@ def test_deprecated_strategies(test_objects): strategy(**arguments) -@pytest.mark.parametrize("flag", [False, True]) -def test_deprecated_campaign_tolerance_flag(flag): - """Constructing a Campaign with the deprecated tolerance flag raises an error.""" - with pytest.raises(DeprecationError): - Campaign( - Mock(spec=SearchSpace), - Mock(spec=Objective), - Mock(spec=RecommenderProtocol), - numerical_measurements_must_be_within_tolerance=flag, - ) - - -def test_deprecated_batch_quantity_keyword(campaign): - """Using the deprecated batch_quantity keyword raises an error.""" - with pytest.raises(DeprecationError): - campaign.recommend(batch_size=5, batch_quantity=5) - - -@pytest.mark.parametrize("flag", (True, False)) -def test_deprecated_strategy_allow_flags(flag): - """Using the deprecated recommender "allow" flags raises an error.""" - with pytest.raises(DeprecationError): - TwoPhaseMetaRecommender(allow_recommending_already_measured=flag) - with pytest.raises(DeprecationError): - TwoPhaseMetaRecommender(allow_repeated_recommendations=flag) - - def test_deprecated_strategy_campaign_flag(recommender): """Using the deprecated strategy keyword raises an error.""" with pytest.raises(DeprecationError): From 833fa011f955535a48970094721313965eb1c1dd Mon Sep 17 00:00:00 2001 From: AdrianSosic Date: Fri, 2 Aug 2024 16:34:18 +0200 Subject: [PATCH 3/6] Expire deprecations from 0.7.4 --- CHANGELOG.md | 1 + baybe/campaign.py | 19 +--------- baybe/strategies/__init__.py | 13 ------- baybe/strategies/deprecation.py | 45 ----------------------- docs/templates/custom-module-template.rst | 2 +- tests/test_deprecations.py | 43 ---------------------- 6 files changed, 3 insertions(+), 120 deletions(-) delete mode 100644 baybe/strategies/__init__.py delete mode 100644 baybe/strategies/deprecation.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 683eda961..f8b0fc7b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `batch_quantity` argument - Passing `allow_repeated_recommendations` or `allow_recommending_already_measured` to `MetaRecommender` (or former `Strategy`) +- `*Strategy` classes and `baybe.strategies` subpackage ## [0.9.1] - 2024-06-04 ### Changed diff --git a/baybe/campaign.py b/baybe/campaign.py index 2359479fc..fc956769b 100644 --- a/baybe/campaign.py +++ b/baybe/campaign.py @@ -11,7 +11,6 @@ from attrs.converters import optional from attrs.validators import instance_of -from baybe.exceptions import DeprecationError from baybe.objectives.base import Objective, to_objective from baybe.parameters.base import Parameter from baybe.recommenders.base import RecommenderProtocol @@ -98,18 +97,6 @@ def __str__(self) -> str: return campaign_str.replace("\n", "\n ").replace("\r", "\r ") - strategy: RecommenderProtocol = field(default=None) - """Deprecated! Raises an error when used.""" - - @strategy.validator - def _validate_strategy(self, _, value) -> None: - """Raise a DeprecationError if the strategy attribute is used.""" - if value is not None: - raise DeprecationError( - "Passing 'strategy' to the constructor is deprecated. The attribute " - "has been renamed to 'recommender'." - ) - @property def measurements(self) -> pd.DataFrame: """The experimental data added to the Campaign.""" @@ -290,11 +277,7 @@ def _drop_version(dict_: dict) -> dict: # Register de-/serialization hooks unstructure_hook = cattrs.gen.make_dict_unstructure_fn( - Campaign, - converter, - _cattrs_include_init_false=True, - # TODO: Remove once deprecation got expired: - strategy=cattrs.override(omit=True), + Campaign, converter, _cattrs_include_init_false=True ) structure_hook = cattrs.gen.make_dict_structure_fn( Campaign, converter, _cattrs_include_init_false=True, _cattrs_forbid_extra_keys=True diff --git a/baybe/strategies/__init__.py b/baybe/strategies/__init__.py deleted file mode 100644 index 418316928..000000000 --- a/baybe/strategies/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -"""BayBE strategies.""" - -from baybe.strategies.deprecation import ( - SequentialStrategy, - StreamingSequentialStrategy, - TwoPhaseStrategy, -) - -__all__ = [ - "SequentialStrategy", - "StreamingSequentialStrategy", - "TwoPhaseStrategy", -] diff --git a/baybe/strategies/deprecation.py b/baybe/strategies/deprecation.py deleted file mode 100644 index f41a3e618..000000000 --- a/baybe/strategies/deprecation.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Temporary functionality for backward compatibility.""" - -import warnings - -from baybe.recommenders.meta import ( - SequentialMetaRecommender, - StreamingSequentialMetaRecommender, - TwoPhaseMetaRecommender, -) - - -def TwoPhaseStrategy(*args, **kwargs) -> TwoPhaseMetaRecommender: - """A ``TwoPhaseStrategy`` alias for backward compatibility.""" # noqa: D401 (imperative mood) - warnings.warn( - f"'TwoPhaseStrategy' is deprecated and will be removed in a future " - f"version. Please use 'recommenders.{TwoPhaseMetaRecommender.__name__}' class " - f"instead.", - DeprecationWarning, - ) - - return TwoPhaseMetaRecommender(*args, **kwargs) - - -def SequentialStrategy(*args, **kwargs) -> SequentialMetaRecommender: - """A ``SequentialStrategy`` alias for backward compatibility.""" # noqa: D401 (imperative mood) - warnings.warn( - f"'SequentialStrategy' is deprecated and will be removed in a future version. " - f"Please use 'recommenders.{SequentialMetaRecommender.__name__}' class " - f"instead.", - DeprecationWarning, - ) - - return SequentialMetaRecommender(*args, **kwargs) - - -def StreamingSequentialStrategy(*args, **kwargs) -> StreamingSequentialMetaRecommender: - """A ``StreamingSequentialStrategy`` alias for backward compatibility.""" # noqa: D401 (imperative mood) - warnings.warn( - f"'StreamingSequentialStrategy' is deprecated and will be removed in a future " - f"version. Please use " - f"'recommenders.{StreamingSequentialMetaRecommender.__name__}' class instead.", - DeprecationWarning, - ) - - return StreamingSequentialMetaRecommender(*args, **kwargs) diff --git a/docs/templates/custom-module-template.rst b/docs/templates/custom-module-template.rst index 931bc18d8..329973b4b 100644 --- a/docs/templates/custom-module-template.rst +++ b/docs/templates/custom-module-template.rst @@ -61,7 +61,7 @@ :template: custom-module-template.rst :recursive: {% for item in modules %} -{% if not item in ("baybe.strategies.deprecation", "baybe.objectives.deprecation", "baybe.recommenders.pure.bayesian.sequential_greedy") %} +{% if not item in ("baybe.objectives.deprecation", "baybe.recommenders.pure.bayesian.sequential_greedy") %} {{ item }} {%- endif %} {%- endfor %} diff --git a/tests/test_deprecations.py b/tests/test_deprecations.py index f11837495..18f42b214 100644 --- a/tests/test_deprecations.py +++ b/tests/test_deprecations.py @@ -1,7 +1,6 @@ """Deprecation tests.""" import json -from unittest.mock import Mock import pandas as pd import pytest @@ -13,22 +12,11 @@ from baybe.objectives.base import Objective from baybe.objectives.desirability import DesirabilityObjective from baybe.parameters.numerical import NumericalContinuousParameter -from baybe.recommenders.base import RecommenderProtocol from baybe.recommenders.pure.bayesian import ( BotorchRecommender, SequentialGreedyRecommender, ) -from baybe.recommenders.pure.nonpredictive.sampling import ( - FPSRecommender, - RandomRecommender, -) from baybe.searchspace.continuous import SubspaceContinuous -from baybe.searchspace.core import SearchSpace -from baybe.strategies import ( - SequentialStrategy, - StreamingSequentialStrategy, - TwoPhaseStrategy, -) from baybe.targets.numerical import NumericalTarget @@ -41,37 +29,6 @@ def test_missing_recommender_type(config): Campaign.from_config(config_without_strategy_type) -# Create some recommenders of different class for better differentiation after roundtrip -RECOMMENDERS = [RandomRecommender(), FPSRecommender()] -assert len(RECOMMENDERS) == len({rec.__class__.__name__ for rec in RECOMMENDERS}) - - -@pytest.mark.parametrize( - "test_objects", - [ - (TwoPhaseStrategy, {}), - (SequentialStrategy, {"recommenders": RECOMMENDERS}), - (StreamingSequentialStrategy, {"recommenders": RECOMMENDERS}), - ], -) -def test_deprecated_strategies(test_objects): - """Using the deprecated strategy classes raises a warning.""" - strategy, arguments = test_objects - with pytest.warns(DeprecationWarning): - strategy(**arguments) - - -def test_deprecated_strategy_campaign_flag(recommender): - """Using the deprecated strategy keyword raises an error.""" - with pytest.raises(DeprecationError): - Campaign( - Mock(spec=SearchSpace), - Mock(spec=Objective), - Mock(spec=RecommenderProtocol), - strategy=recommender, - ) - - def test_deprecated_objective_class(): """Using the deprecated objective class raises a warning.""" with pytest.warns(DeprecationWarning): From c2538504756d91743f1ecf661f3953661789e9fc Mon Sep 17 00:00:00 2001 From: AdrianSosic Date: Fri, 2 Aug 2024 17:06:39 +0200 Subject: [PATCH 4/6] Expire deprecation for using MetaRecommender configs without type --- CHANGELOG.md | 5 ++-- baybe/recommenders/base.py | 6 +++-- baybe/recommenders/deprecation.py | 42 ------------------------------- baybe/recommenders/meta/base.py | 6 +++-- tests/test_deprecations.py | 12 --------- 5 files changed, 11 insertions(+), 60 deletions(-) delete mode 100644 baybe/recommenders/deprecation.py diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b0fc7b4..125a7cf86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,13 +98,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Expired Deprecations (from 0.7.*) - `Interval.is_finite` property -- Specifying target configs without explicit type information -- Specifying parameters/constraints at the top level of a campaign configuration JSON +- Specifying target configs without type information +- Specifying parameters/constraints at the top level of a campaign configs - Passing `numerical_measurements_must_be_within_tolerance` to `Campaign` - `batch_quantity` argument - Passing `allow_repeated_recommendations` or `allow_recommending_already_measured` to `MetaRecommender` (or former `Strategy`) - `*Strategy` classes and `baybe.strategies` subpackage +- Specifying `MetaRecommender` (or former `Strategy`) configs without type information ## [0.9.1] - 2024-06-04 ### Changed diff --git a/baybe/recommenders/base.py b/baybe/recommenders/base.py index 2042ada06..7539f1bbf 100644 --- a/baybe/recommenders/base.py +++ b/baybe/recommenders/base.py @@ -6,9 +6,9 @@ import pandas as pd from baybe.objectives.base import Objective -from baybe.recommenders.deprecation import structure_recommender_protocol from baybe.searchspace import SearchSpace from baybe.serialization import converter, unstructure_base +from baybe.serialization.core import get_base_structure_hook @runtime_checkable @@ -57,4 +57,6 @@ def recommend( ), ), ) -converter.register_structure_hook(RecommenderProtocol, structure_recommender_protocol) +converter.register_structure_hook( + RecommenderProtocol, get_base_structure_hook(RecommenderProtocol) +) diff --git a/baybe/recommenders/deprecation.py b/baybe/recommenders/deprecation.py deleted file mode 100644 index 91fa3336d..000000000 --- a/baybe/recommenders/deprecation.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Temporary functionality for backward compatibility.""" - -from __future__ import annotations - -import warnings -from typing import TYPE_CHECKING - -from cattrs.gen import make_dict_structure_fn - -from baybe.serialization import converter -from baybe.utils.basic import get_subclasses - -if TYPE_CHECKING: - from baybe.recommenders.base import RecommenderProtocol - - -def structure_recommender_protocol(val: dict, _) -> RecommenderProtocol: - """A structure hook using ``TwoPhaseMetaRecommender`` as fallback type.""" # noqa: D401 (imperative mood) - from baybe.recommenders.base import RecommenderProtocol - from baybe.recommenders.meta.sequential import TwoPhaseMetaRecommender - - try: - val = val.copy() - _type = val.pop("type") - cls = next( - (cl for cl in get_subclasses(RecommenderProtocol) if cl.__name__ == _type), - None, - ) - if cls is None: - raise ValueError(f"Unknown subclass '{_type}'.") - except KeyError: - cls = TwoPhaseMetaRecommender - warnings.warn( - f"A recommender has been specified without a corresponding type. " - f"As a fallback, '{TwoPhaseMetaRecommender.__name__}' is used. " - f"However, this behavior is deprecated and will be disabled in " - f"a future version.", - DeprecationWarning, - ) - fun = make_dict_structure_fn(cls, converter, _cattrs_forbid_extra_keys=True) # type: ignore - - return fun(val, cls) diff --git a/baybe/recommenders/meta/base.py b/baybe/recommenders/meta/base.py index 92d4f5cf4..7460a9b69 100644 --- a/baybe/recommenders/meta/base.py +++ b/baybe/recommenders/meta/base.py @@ -9,11 +9,11 @@ from baybe.objectives.base import Objective from baybe.recommenders.base import RecommenderProtocol -from baybe.recommenders.deprecation import structure_recommender_protocol from baybe.recommenders.pure.base import PureRecommender from baybe.recommenders.pure.nonpredictive.base import NonPredictiveRecommender from baybe.searchspace import SearchSpace from baybe.serialization import SerialMixin, converter, unstructure_base +from baybe.serialization.core import get_base_structure_hook @define @@ -88,4 +88,6 @@ def recommend( ), ), ) -converter.register_structure_hook(MetaRecommender, structure_recommender_protocol) +converter.register_structure_hook( + MetaRecommender, get_base_structure_hook(MetaRecommender) +) diff --git a/tests/test_deprecations.py b/tests/test_deprecations.py index 18f42b214..47c36a8fd 100644 --- a/tests/test_deprecations.py +++ b/tests/test_deprecations.py @@ -1,11 +1,8 @@ """Deprecation tests.""" -import json - import pandas as pd import pytest -from baybe import Campaign from baybe.acquisition.base import AcquisitionFunction from baybe.exceptions import DeprecationError from baybe.objective import Objective as OldObjective @@ -20,15 +17,6 @@ from baybe.targets.numerical import NumericalTarget -def test_missing_recommender_type(config): - """Specifying a recommender without a corresponding type raises a warning.""" - dict_ = json.loads(config) - dict_["recommender"].pop("type") - config_without_strategy_type = json.dumps(dict_) - with pytest.warns(DeprecationWarning): - Campaign.from_config(config_without_strategy_type) - - def test_deprecated_objective_class(): """Using the deprecated objective class raises a warning.""" with pytest.warns(DeprecationWarning): From ea1bc9c585e65053f6afee9e976252518cf4dbde Mon Sep 17 00:00:00 2001 From: AdrianSosic Date: Fri, 2 Aug 2024 17:08:32 +0200 Subject: [PATCH 5/6] Add release date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 125a7cf86..7854b2543 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.10.0] - 2024-08-02 ### Breaking Changes - Providing an explicit `batch_size` is now mandatory when asking for recommendations - `RecommenderProtocol.recommend` now accepts an optional `Objective` From f8f85a3636c5d8806fe49826871aee0ea7735a85 Mon Sep 17 00:00:00 2001 From: AdrianSosic Date: Fri, 2 Aug 2024 17:26:50 +0200 Subject: [PATCH 6/6] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7854b2543..0fcb475fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,7 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 two fixed low and high dimensional prior regimes - The previous default kernel factory has been renamed to `EDBOKernelFactory` and now fully reflects the original logic -- The default acquisition function has been changed from "qEI" to "qLogEI" for improved +- The default acquisition function has been changed from `qEI` to `qLogEI` for improved numerical stability ### Removed @@ -95,6 +95,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Passing a dataframe via the `data` argument to the `transform` methods of `SearchSpace`, `SubspaceDiscrete` and `SubspaceContinuous` is no longer possible. The dataframe must now be passed as positional argument. +- The new `allow_extra` flag is automatically set to `True` in `transform` methods + of search space classes when left unspecified ### Expired Deprecations (from 0.7.*) - `Interval.is_finite` property