From 449777e7a811c965cc9e2cc5a5780fe8e788d61c Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 21:57:19 +0900 Subject: [PATCH 1/8] chore: drop 39-310 add 315 --- pyproject.toml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 38115e19..3a09b80a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,31 +5,33 @@ description = "Bayesian Optimization package" authors = [{ name = "Fernando Nogueira", email = "fmfnogueira@gmail.com" }] license = { file = "LICENSE" } readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.11" classifiers = [ "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Free Threading" ] dependencies = [ "colorama>=0.4.6", "numpy>=1.25; python_version<'3.13'", "numpy>=2.1.3; python_version>='3.13' and python_version<'3.14'", - "numpy>=2.3.0; python_version>='3.14'", + "numpy>=2.3.0; python_version>='3.14' and python_version<'3.15'", + "numpy>=2.3.0; python_version>='3.15'", "packaging>=20.0; python_version<'3.14'", "packaging>=26.0; python_version>='3.14'", "scikit-learn>=1.0.0; python_version<'3.14'", - "scikit-learn>=1.8.0; python_version>='3.14'", + "scikit-learn>=1.8.0; python_version>='3.14' and python_version<'3.15'", + "scikit-learn>=1.9.1; python_version>='3.15'", "scipy>=1.0.0; python_version<'3.13'", "scipy>=1.14.1; python_version>='3.13' and python_version<'3.14'", - "scipy>=1.17.0; python_version>='3.14'", + "scipy>=1.17.0; python_version>='3.14' and python_version<'3.15'", + "scipy>=1.17.0; python_version>='3.15'", ] [project.optional-dependencies] @@ -45,10 +47,8 @@ dev = [ "pytest-cov>=4.1.0", "ruff>=0.15.6", "sphinx-immaterial>=0.12.0", - "sphinx>=7.0.0; python_version<'3.10'", - "sphinx>=8.0.0; python_version>='3.10'", - "sphinx-autodoc-typehints>=2.3.0; python_version<'3.10'", - "sphinx-autodoc-typehints>=2.4.0; python_version>='3.10'", + "sphinx>=8.0.0", + "sphinx-autodoc-typehints>=2.4.0", ] [project.urls] Repository = "https://github.com/bayesian-optimization/BayesianOptimization" From f1cd5d27d18ded8df11b3dcde295ce238da6d0cb Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 22:02:00 +0900 Subject: [PATCH 2/8] fix: action --- .github/workflows/build_docs.yml | 2 +- .github/workflows/format_and_lint.yml | 2 +- .github/workflows/run_tests.yml | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 335ed9c1..929fe91f 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -21,7 +21,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v6 with: - python-version: "3.10" + python-version: "3.11" - name: Get tag uses: olegtarasov/get-tag@v2.1 - name: Install pandoc diff --git a/.github/workflows/format_and_lint.yml b/.github/workflows/format_and_lint.yml index 2f7665f1..51a29256 100644 --- a/.github/workflows/format_and_lint.yml +++ b/.github/workflows/format_and_lint.yml @@ -16,7 +16,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v6 with: - python-version: "3.9" + python-version: "3.11" - name: Install dependencies run: uv sync --extra dev - name: Run pre-commit diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 4b3a061b..f0862526 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.14t", "3.15", "3.15t"] numpy-major: ["1", "2"] exclude: - python-version: "3.13" # numpy<2 is not supported on 3.13+ @@ -26,6 +26,10 @@ jobs: numpy-major: "1" - python-version: "3.14t" numpy-major: "1" + - python-version: "3.15" + numpy-major: "1" + - python-version: "3.15t" + numpy-major: "1" steps: - uses: actions/checkout@v3 From 3df2f209191d312305ae9047494f6b8a8704c3d5 Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 22:05:15 +0900 Subject: [PATCH 3/8] chore: drop py315 --- .github/workflows/run_tests.yml | 6 +----- pyproject.toml | 10 +++------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index f0862526..41759f20 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", "3.12", "3.13", "3.14", "3.14t", "3.15", "3.15t"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.14t"] numpy-major: ["1", "2"] exclude: - python-version: "3.13" # numpy<2 is not supported on 3.13+ @@ -26,10 +26,6 @@ jobs: numpy-major: "1" - python-version: "3.14t" numpy-major: "1" - - python-version: "3.15" - numpy-major: "1" - - python-version: "3.15t" - numpy-major: "1" steps: - uses: actions/checkout@v3 diff --git a/pyproject.toml b/pyproject.toml index 3a09b80a..abbac641 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,24 +14,20 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", - "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Free Threading" ] dependencies = [ "colorama>=0.4.6", "numpy>=1.25; python_version<'3.13'", "numpy>=2.1.3; python_version>='3.13' and python_version<'3.14'", - "numpy>=2.3.0; python_version>='3.14' and python_version<'3.15'", - "numpy>=2.3.0; python_version>='3.15'", + "numpy>=2.3.0; python_version>='3.14'", "packaging>=20.0; python_version<'3.14'", "packaging>=26.0; python_version>='3.14'", "scikit-learn>=1.0.0; python_version<'3.14'", - "scikit-learn>=1.8.0; python_version>='3.14' and python_version<'3.15'", - "scikit-learn>=1.9.1; python_version>='3.15'", + "scikit-learn>=1.8.0; python_version>='3.14'", "scipy>=1.0.0; python_version<'3.13'", "scipy>=1.14.1; python_version>='3.13' and python_version<'3.14'", - "scipy>=1.17.0; python_version>='3.14' and python_version<'3.15'", - "scipy>=1.17.0; python_version>='3.15'", + "scipy>=1.17.0; python_version>='3.14'", ] [project.optional-dependencies] From 88f141cf6074a7cef55abe9261cea3c7d949356d Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 22:06:01 +0900 Subject: [PATCH 4/8] chore: ruff py39 -> py311 --- ruff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index 9c08e69c..c069649e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,6 +1,6 @@ line-length = 110 unsafe-fixes = false -target-version = "py39" +target-version = "py311" extend = "./pyproject.toml" exclude = [ # docs From ba27045d5db721c3977ecace7b6b8a6cafea50eb Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 22:13:19 +0900 Subject: [PATCH 5/8] fix: ruff errors --- bayes_opt/acquisition.py | 4 ++-- bayes_opt/bayesian_optimization.py | 4 ++-- bayes_opt/domain_reduction.py | 9 +++------ bayes_opt/parameter.py | 16 ++++++++-------- bayes_opt/target_space.py | 6 +++++- tests/test_bayesian_optimization.py | 10 +++------- tests/test_notebooks_run.py | 2 +- 7 files changed, 24 insertions(+), 27 deletions(-) diff --git a/bayes_opt/acquisition.py b/bayes_opt/acquisition.py index ce31d27a..4cd6828a 100644 --- a/bayes_opt/acquisition.py +++ b/bayes_opt/acquisition.py @@ -1024,7 +1024,7 @@ def _copy_target_space(self, target_space: TargetSpace) -> TargetSpace: A copy of the target space. """ keys = target_space.keys - pbounds = {key: bound for key, bound in zip(keys, target_space.bounds)} + pbounds = {key: bound for key, bound in zip(keys, target_space.bounds, strict=False)} target_space_copy = TargetSpace( None, pbounds=pbounds, allow_duplicate_points=target_space._allow_duplicate_points ) @@ -1351,7 +1351,7 @@ def set_acquisition_params(self, params: dict[str, Any]) -> None: params : dict Dictionary containing the acquisition function parameters. """ - for acq, acq_params in zip(self.base_acquisitions, params["base_acquisitions_params"]): + for acq, acq_params in zip(self.base_acquisitions, params["base_acquisitions_params"], strict=False): acq.set_acquisition_params(acq_params) self.gains = np.array(params["gains"]) diff --git a/bayes_opt/bayesian_optimization.py b/bayes_opt/bayesian_optimization.py index 737cb0e8..f3f151fd 100644 --- a/bayes_opt/bayesian_optimization.py +++ b/bayes_opt/bayesian_optimization.py @@ -33,7 +33,6 @@ from bayes_opt.acquisition import AcquisitionFunction from bayes_opt.constraint import ConstraintModel - from bayes_opt.domain_reduction import DomainTransformer from bayes_opt.parameter import BoundsMapping, ParamsType Float = np.floating[Any] @@ -476,7 +475,8 @@ def _load_state_dict(self, state: dict[str, Any]) -> None: if state.get("transformed_bounds") and self._bounds_transformer: new_bounds = { - key: bounds for key, bounds in zip(self._space.keys, np.array(state["transformed_bounds"])) + key: bounds + for key, bounds in zip(self._space.keys, np.array(state["transformed_bounds"]), strict=False) } self._space.set_bounds(new_bounds) self._bounds_transformer.initialize(self._space) diff --git a/bayes_opt/domain_reduction.py b/bayes_opt/domain_reduction.py index 243a51bd..634fffdb 100644 --- a/bayes_opt/domain_reduction.py +++ b/bayes_opt/domain_reduction.py @@ -90,7 +90,7 @@ def initialize(self, target_space: TargetSpace) -> None: else: self.minimum_window_value = self.minimum_window_value - any_not_float = any([not isinstance(p, FloatParameter) for p in target_space._params_config.values()]) + any_not_float = any(not isinstance(p, FloatParameter) for p in target_space._params_config.values()) if any_not_float: msg = "Domain reduction is only supported for all-FloatParameter optimization." raise ValueError(msg) @@ -180,11 +180,8 @@ def _trim(self, new_bounds: NDArray[Float], global_bounds: NDArray[Float]) -> ND for i, pbounds in enumerate(new_bounds): # If the one of the bounds is outside the global bounds, reset the bound to the global bound # This is expected to happen when the window is near the global bounds, no warning is issued - if pbounds[0] < global_bounds[i, 0]: - pbounds[0] = global_bounds[i, 0] - - if pbounds[1] > global_bounds[i, 1]: - pbounds[1] = global_bounds[i, 1] + pbounds[0] = max(pbounds[0], global_bounds[i, 0]) + pbounds[1] = min(pbounds[1], global_bounds[i, 1]) # If a lower bound is greater than the associated global upper bound, # reset it to the global lower bound diff --git a/bayes_opt/parameter.py b/bayes_opt/parameter.py index 2eaa7a44..18b9d34f 100644 --- a/bayes_opt/parameter.py +++ b/bayes_opt/parameter.py @@ -3,10 +3,10 @@ from __future__ import annotations import abc -from collections.abc import Sequence +from collections.abc import Callable, Sequence from inspect import signature from numbers import Number -from typing import TYPE_CHECKING, Any, Callable, Union +from typing import TYPE_CHECKING, Any import numpy as np from sklearn.gaussian_process import kernels @@ -23,15 +23,15 @@ FloatBoundsWithoutType = tuple[float, float] FloatBoundsWithType = tuple[float, float, type[float]] - FloatBounds = Union[FloatBoundsWithoutType, FloatBoundsWithType] - IntBounds = tuple[Union[int, float], Union[int, float], type[int]] + FloatBounds = FloatBoundsWithoutType | FloatBoundsWithType + IntBounds = tuple[int | float, int | float, type[int]] CategoricalBounds = Sequence[Any] - Bounds = Union[FloatBounds, IntBounds, CategoricalBounds] + Bounds = FloatBounds | IntBounds | CategoricalBounds BoundsMapping = Mapping[str, Bounds] # FIXME: categorical parameters can be of any type. # This will make static type checking for parameters difficult. - ParamsType = Union[Mapping[str, Any], Sequence[Any], NDArray[Float]] + ParamsType = Mapping[str, Any] | Sequence[Any] | NDArray[Float] def is_numeric(value: Any) -> bool: @@ -280,7 +280,7 @@ def random_sample( random_state = ensure_rng(random_state) return random_state.randint(self.bounds[0], self.bounds[1] + 1, n_samples).astype(float) - def to_float(self, value: int | float) -> float: + def to_float(self, value: float) -> float: """Convert a parameter value to a float. Parameters @@ -290,7 +290,7 @@ def to_float(self, value: int | float) -> float: """ return float(value) - def to_param(self, value: int | float | NDArray[Int] | NDArray[Float]) -> int: + def to_param(self, value: float | NDArray[Int] | NDArray[Float]) -> int: """Convert a float value to a parameter. Parameters diff --git a/bayes_opt/target_space.py b/bayes_opt/target_space.py index 33bf0687..cb308141 100644 --- a/bayes_opt/target_space.py +++ b/bayes_opt/target_space.py @@ -670,7 +670,10 @@ def res(self) -> list[dict[str, Any]]: if self._constraint is None: params = [self.array_to_params(p) for p in self.params] - return [{"target": target, "params": param} for target, param in zip(self.target, params)] + return [ + {"target": target, "params": param} + for target, param in zip(self.target, params, strict=False) + ] params = [self.array_to_params(p) for p in self.params] @@ -681,6 +684,7 @@ def res(self) -> list[dict[str, Any]]: self._constraint_values, params, self._constraint.allowed(self._constraint_values), + strict=False, ) ] diff --git a/tests/test_bayesian_optimization.py b/tests/test_bayesian_optimization.py index 2788e192..5a25093c 100644 --- a/tests/test_bayesian_optimization.py +++ b/tests/test_bayesian_optimization.py @@ -1,6 +1,7 @@ from __future__ import annotations import pickle +import re import warnings from pathlib import Path @@ -329,13 +330,8 @@ def test_duplicate_points(): # register once (should work) optimizer.register(params=next_point_to_probe, target=target) # register twice (should throw error) - try: + with pytest.raises(NotUniqueError): optimizer.register(params=next_point_to_probe, target=target) - duplicate_point_error = None # should be overwritten below - except Exception as e: - duplicate_point_error = e - - assert isinstance(duplicate_point_error, NotUniqueError) # OK, now let's test that it DOESNT fail when allow_duplicate_points=True optimizer = BayesianOptimization( @@ -384,7 +380,7 @@ def test_load_state_rejects_incompatible_keys(tmp_path, saved_points, existing_p restored.probe(dict.fromkeys(pbounds, 0), lazy=False) before = restored.res - with pytest.raises(ValueError, match="parameter keys.*same order"): + with pytest.raises(ValueError, match=re.escape("parameter keys.*same order")): restored.load_state(state_path) assert restored.res == before diff --git a/tests/test_notebooks_run.py b/tests/test_notebooks_run.py index f1fbf6ea..c42509da 100644 --- a/tests/test_notebooks_run.py +++ b/tests/test_notebooks_run.py @@ -19,7 +19,7 @@ @pytest.mark.parametrize("notebook", sorted(this_file_loc.with_name("examples").glob("*.ipynb"))) def test_all_notebooks_run(notebook: Path): as_string = str(notebook) - if any([nb in as_string for nb in _NOTEBOOKS_NOT_TO_RUN]): + if any(nb in as_string for nb in _NOTEBOOKS_NOT_TO_RUN): pytest.skip(f"skipping [{notebook!s}]") print(f"running: {notebook}...") From 7bf16c18a486e8337648a89371fefdc373e9912b Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 22:19:49 +0900 Subject: [PATCH 6/8] chore: fix ruff version --- .pre-commit-config.yaml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d86185de..47397c58 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,4 +6,4 @@ repos: name: ruff-format args: [--check] repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.3 \ No newline at end of file + rev: v0.17.1 \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index abbac641..34273510 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ dev = [ "pre-commit>=3.7.1", "pytest>=8.0.0", "pytest-cov>=4.1.0", - "ruff>=0.15.6", + "ruff==0.17.1", "sphinx-immaterial>=0.12.0", "sphinx>=8.0.0", "sphinx-autodoc-typehints>=2.4.0", From 3096ff8d311b9f4721316284bc47c2fa197d1dac Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 22:20:28 +0900 Subject: [PATCH 7/8] fix: ruff errors --- .github/ISSUE_TEMPLATE/bug_report.md | 9 +++------ README.md | 15 ++++----------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 8132ec16..9ba74a92 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -20,14 +20,11 @@ Ex: ```python from bayes_opt import BayesianOptimization -black_box_function = lambda x, y: -x ** 2 - (y - 1) ** 2 + 1 +black_box_function = lambda x, y: -(x**2) - (y - 1) ** 2 + 1 -pbounds = {'x': (2, 4), 'y': (-3, 3)} +pbounds = {"x": (2, 4), "y": (-3, 3)} -optimizer = BayesianOptimization( - f=black_box_function, - pbounds=pbounds -) +optimizer = BayesianOptimization(f=black_box_function, pbounds=pbounds) optimizer.maximize() ``` diff --git a/README.md b/README.md index c485d11c..17daa9a4 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ def black_box_function(x, y): purposes think of the internals of this function, i.e.: the process which generates its output values, as unknown. """ - return -x ** 2 - (y - 1) ** 2 + 1 + return -(x**2) - (y - 1) ** 2 + 1 ``` ### 2. Getting Started @@ -82,13 +82,9 @@ All we need to get started is to instantiate a `BayesianOptimization` object spe from bayes_opt import BayesianOptimization # Bounded region of parameter space -pbounds = {'x': (2, 4), 'y': (-3, 3)} +pbounds = {"x": (2, 4), "y": (-3, 3)} -optimizer = BayesianOptimization( - f=black_box_function, - pbounds=pbounds, - random_state=1, -) +optimizer = BayesianOptimization(f=black_box_function, pbounds=pbounds, random_state=1) ``` The BayesianOptimization object will work out of the box without much tuning needed. The main method you should be aware of is `maximize`, which does exactly what you think it does. @@ -99,10 +95,7 @@ There are many parameters you can pass to maximize, nonetheless, the most import ```python -optimizer.maximize( - init_points=2, - n_iter=3, -) +optimizer.maximize(init_points=2, n_iter=3) ``` | iter | target | x | y | From ebfb5c9c973be08f0b8f3c6c85ff25ae82fe774b Mon Sep 17 00:00:00 2001 From: phi Date: Fri, 16 Oct 2026 22:24:50 +0900 Subject: [PATCH 8/8] fix: test errors --- tests/test_bayesian_optimization.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_bayesian_optimization.py b/tests/test_bayesian_optimization.py index 5a25093c..29b7a79c 100644 --- a/tests/test_bayesian_optimization.py +++ b/tests/test_bayesian_optimization.py @@ -1,7 +1,6 @@ from __future__ import annotations import pickle -import re import warnings from pathlib import Path @@ -380,7 +379,7 @@ def test_load_state_rejects_incompatible_keys(tmp_path, saved_points, existing_p restored.probe(dict.fromkeys(pbounds, 0), lazy=False) before = restored.res - with pytest.raises(ValueError, match=re.escape("parameter keys.*same order")): + with pytest.raises(ValueError, match=r"parameter keys.*same order"): restored.load_state(state_path) assert restored.res == before