Skip to content

Commit b58da1a

Browse files
authored
Reject incompatible parameter keys when loading optimizer state (#629)
* Fix load-state parameter key validation * Document incompatible-state regression coverage
1 parent 16132b0 commit b58da1a

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

‎bayes_opt/bayesian_optimization.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,10 @@ def _load_state_dict(self, state: dict[str, Any]) -> None:
456456
state : dict
457457
Dictionary containing the optimizer state.
458458
"""
459+
if state["keys"] != self._space.keys:
460+
msg = "Saved state must have the same parameter keys in the same order as the optimizer."
461+
raise ValueError(msg)
462+
459463
params_array = np.asarray(state["params"], dtype=np.float64)
460464
target_array = np.asarray(state["target"], dtype=np.float64)
461465
constraint_array = (

‎tests/test_bayesian_optimization.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,30 @@ def test_save_load_state(tmp_path):
368368
np.testing.assert_array_equal(optimizer.space.target, new_optimizer.space.target)
369369

370370

371+
@pytest.mark.parametrize("saved_points", [False, True])
372+
@pytest.mark.parametrize("existing_points", [False, True])
373+
@pytest.mark.parametrize("pbounds", [{"p2": (0, 10), "p1": (0, 10)}, {"width": (0, 10), "height": (0, 10)}])
374+
def test_load_state_rejects_incompatible_keys(tmp_path, saved_points, existing_points, pbounds):
375+
"""Reject incompatible keys without changing results or random-state progression."""
376+
original = BayesianOptimization(target_func, PBOUNDS, random_state=1, verbose=0)
377+
if saved_points:
378+
original.probe({"p1": 1, "p2": 2}, lazy=False)
379+
state_path = tmp_path / "optimizer_state.json"
380+
original.save_state(state_path)
381+
382+
restored = BayesianOptimization(target_func, pbounds, random_state=7, verbose=0)
383+
if existing_points:
384+
restored.probe(dict.fromkeys(pbounds, 0), lazy=False)
385+
before = restored.res
386+
387+
with pytest.raises(ValueError, match="parameter keys.*same order"):
388+
restored.load_state(state_path)
389+
390+
assert restored.res == before
391+
control = BayesianOptimization(target_func, pbounds, random_state=7, verbose=0)
392+
assert restored.random_sample(2) == control.random_sample(2)
393+
394+
371395
def test_save_load_w_categorical_params(tmp_path):
372396
"""Test saving and loading optimizer state with categorical parameters."""
373397

0 commit comments

Comments
 (0)