Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
834d13e
Treat warnings as errors during tests
AdrianSosic Apr 20, 2026
ccb9661
Ignore torch.jit.script warning
AdrianSosic Apr 20, 2026
058522d
Ignore legacy target warning for test parametrization
AdrianSosic Apr 20, 2026
f9a4f9a
Ignore legacy target warnings in test bodies
AdrianSosic Apr 20, 2026
9704318
Ignore pandas FutureWarning
AdrianSosic Apr 20, 2026
7050dca
Ignore linear_operator NumericalWarning
AdrianSosic Apr 20, 2026
b8acbfa
Ignore BoTorch failed optimization RuntimeWarning
AdrianSosic Apr 20, 2026
eb8b21b
Avoid expected warning being converted into error
AdrianSosic Apr 20, 2026
0704191
Ignore BoTorch log-acquisition warnings
AdrianSosic Apr 20, 2026
24e8d89
Fix target tensor layout
AdrianSosic Apr 21, 2026
6475402
Temporarily ignore linear_operator DeprecationWarning
AdrianSosic Apr 21, 2026
018902e
Ignore scipy optimization termination warning (reraised by BoTorch)
AdrianSosic Apr 20, 2026
e67feae
Drop tenacity warning
AdrianSosic Apr 22, 2026
9c2a17c
Extend regex for linear_operator warning
AdrianSosic Apr 22, 2026
1158cff
Replace stable_cumsum with np.cumulative_sum
AdrianSosic Apr 20, 2026
ba3e59c
Avoid acquisition value degeneracy by adding more data
AdrianSosic Apr 22, 2026
b397234
Add missing detach() call to numpy surrogates
AdrianSosic Apr 22, 2026
4f7d1d4
Activate pytest's strict mode
AdrianSosic Apr 22, 2026
5aa81af
Fix some duplicate parametrization IDs
AdrianSosic Apr 22, 2026
75c0aec
Temporarily disable strict parametrization requirement
AdrianSosic Apr 22, 2026
2c8c70e
Register filterwarnings marker for strict mode
AdrianSosic Apr 22, 2026
6fda0db
Skip test in CORETEST environment
AdrianSosic Apr 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions baybe/constraints/discrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import gc
import warnings
from collections.abc import Callable
from functools import reduce
from typing import TYPE_CHECKING, Any, ClassVar, cast
Expand Down Expand Up @@ -233,13 +234,18 @@ def get_invalid(self, data: pd.DataFrame) -> pd.Index:
# Create data copy and mark entries where the dependency conditions are negative
# with a dummy value to cause degeneracy.
censored_data = data.copy()
for k, _ in enumerate(self.parameters):
# .loc assignments are not supported by mypy + pandas-stubs yet
# See https://github.com/pandas-dev/pandas-stubs/issues/572
censored_data.loc[ # type: ignore[call-overload]
~self.conditions[k].evaluate(data[self.parameters[k]]),
self.affected_parameters[k],
] = Dummy()
with warnings.catch_warnings():
# Suppress pandas FutureWarning about setting incompatible dtype.
# TODO: Needs proper fix for pandas 3.0 compatibility.
warnings.simplefilter("ignore", FutureWarning)

for k, _ in enumerate(self.parameters):
# .loc assignments are not supported by mypy + pandas-stubs yet
# See https://github.com/pandas-dev/pandas-stubs/issues/572
censored_data.loc[ # type: ignore[call-overload]
~self.conditions[k].evaluate(data[self.parameters[k]]),
self.affected_parameters[k],
] = Dummy()

Comment on lines +237 to 249
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warnings.simplefilter("ignore", FutureWarning) inside get_invalid suppresses all FutureWarnings raised in this block, which can mask unrelated warnings and make it harder to spot new pandas deprecations. Prefer narrowing the filter to the specific pandas warning message (or module) you're targeting, or proactively adjust the dataframe/column dtypes before assignment to avoid emitting the warning in the first place.

Suggested change
with warnings.catch_warnings():
# Suppress pandas FutureWarning about setting incompatible dtype.
# TODO: Needs proper fix for pandas 3.0 compatibility.
warnings.simplefilter("ignore", FutureWarning)
for k, _ in enumerate(self.parameters):
# .loc assignments are not supported by mypy + pandas-stubs yet
# See https://github.com/pandas-dev/pandas-stubs/issues/572
censored_data.loc[ # type: ignore[call-overload]
~self.conditions[k].evaluate(data[self.parameters[k]]),
self.affected_parameters[k],
] = Dummy()
# Cast affected columns to object before assigning Dummy() values to avoid
# pandas FutureWarning about setting incompatible dtypes.
all_affected_params = list(
dict.fromkeys(
affected_param
for affected_params in self.affected_parameters
for affected_param in affected_params
)
)
if all_affected_params:
censored_data[all_affected_params] = censored_data[
all_affected_params
].astype(object)
for k, _ in enumerate(self.parameters):
# .loc assignments are not supported by mypy + pandas-stubs yet
# See https://github.com/pandas-dev/pandas-stubs/issues/572
censored_data.loc[ # type: ignore[call-overload]
~self.conditions[k].evaluate(data[self.parameters[k]]),
self.affected_parameters[k],
] = Dummy()

Copilot uses AI. Check for mistakes.
# Create an invariant indicator: pair each value of an affected parameter with
# the corresponding value of the parameter it depends on. These indicators
Expand Down
4 changes: 3 additions & 1 deletion baybe/surrogates/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ def _estimate_moments(
import torch

# Get predictions
dists = self._model.predict(candidates_comp_scaled.numpy(), return_std=True)
dists = self._model.predict(
candidates_comp_scaled.detach().numpy(), return_std=True
)

# Split into posterior mean and variance
mean = torch.from_numpy(dists[0])
Expand Down
2 changes: 1 addition & 1 deletion baybe/surrogates/ngboost.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def _estimate_moments(
import torch

# Get predictions
dists = self._model.pred_dist(candidates_comp_scaled)
dists = self._model.pred_dist(candidates_comp_scaled.detach().numpy())

# Split into posterior mean and variance
mean = torch.from_numpy(dists.mean())
Expand Down
2 changes: 1 addition & 1 deletion baybe/surrogates/random_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def predict(candidates_comp_scaled: Tensor) -> Tensor:

return torch.from_numpy(
self._predict_ensemble(
self._model.estimators_, candidates_comp_scaled.numpy()
self._model.estimators_, candidates_comp_scaled.detach().numpy()
)
)

Expand Down
5 changes: 3 additions & 2 deletions baybe/utils/clustering_algorithms/third_party/kmedoids.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
pairwise_distances_argmin,
)
from sklearn.utils import check_array, check_random_state
from sklearn.utils.extmath import stable_cumsum
from sklearn.utils.validation import check_is_fitted

from baybe.settings import active_settings
Expand Down Expand Up @@ -485,7 +484,9 @@ def _kpp_init(self, D, n_clusters, random_state_, n_local_trials=None):
# pick the remaining n_clusters-1 points
for cluster_index in range(1, n_clusters):
rand_vals = random_state_.random_sample(n_local_trials) * current_pot
candidate_ids = np.searchsorted(stable_cumsum(closest_dist_sq), rand_vals)
candidate_ids = np.searchsorted(
np.cumulative_sum(closest_dist_sq), rand_vals
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np.cumulative_sum is not a NumPy API, so this will raise AttributeError at runtime. If the goal is to remove the scikit-learn stable_cumsum import, replace this with a valid cumulative sum implementation (e.g., np.cumsum) or inline a numerically-stable cumulative sum equivalent to stable_cumsum to preserve behavior.

Suggested change
np.cumulative_sum(closest_dist_sq), rand_vals
np.cumsum(closest_dist_sq), rand_vals

Copilot uses AI. Check for mistakes.
)

# Compute distances to center candidates
distance_to_candidates = D[candidate_ids, :] ** 2
Expand Down
24 changes: 23 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
[pytest]
strict = true

markers =
filterwarnings: Apply warning filters to a test

# Currently blocked by test_iterations.py. Should be activated once that test module
# has been properly refactored.
strict_parametrization_ids=false

addopts =
--doctest-modules
--ignore=examples
--ignore=docs

; Avoids import errors due to optional dependencies
--doctest-ignore-import-errors

testpaths =
baybe
tests
xfail_strict=true

filterwarnings =
error
; Numerics/optimization
ignore:.*add(ed|ing) jitter.*:linear_operator.utils.warnings.NumericalWarning
ignore:Optimization failed.*:RuntimeWarning:botorch.optim.optimize
; Note: File format instead of module format needed due to BoTorch reraising using `warn_explicit` without `module` argument
ignore:`scipy_minimize` terminated with status .*:botorch.exceptions.warnings.OptimizationWarning:.*botorch/fit
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filterwarnings rule on this line has trailing whitespace after the .*botorch/fit regex. Depending on how the config is parsed, this can accidentally become part of the regex and prevent the ignore from matching. Please remove the trailing spaces to make the rule unambiguous.

Suggested change
ignore:`scipy_minimize` terminated with status .*:botorch.exceptions.warnings.OptimizationWarning:.*botorch/fit
ignore:`scipy_minimize` terminated with status .*:botorch.exceptions.warnings.OptimizationWarning:.*botorch/fit

Copilot uses AI. Check for mistakes.
; BoTorch warning recommending to switch to log-versions of acquisition functions
ignore:.*has known numerical issues that lead to suboptimal optimization performance.*:botorch.exceptions.warnings.NumericsWarning:botorch.acquisition
; Temporary ignores
; https://github.com/meta-pytorch/botorch/pull/3279
ignore:chol argument to CholLinearOperator should be a TriangularLinearOperator.*:DeprecationWarning:linear_operator.operators.chol_linear_operator
12 changes: 8 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@
create_fake_input,
)

# TODO: Remove when https://github.com/cornellius-gp/linear_operator/pull/129 is ready
warnings.filterwarnings(
"ignore",
message=".*torch.jit.script.*is deprecated",
category=DeprecationWarning,
)

# Hypothesis settings
hypothesis_settings.register_profile("ci", deadline=500, max_examples=100)
if strtobool(os.getenv("CI", "false")):
Expand Down Expand Up @@ -918,7 +925,7 @@ def fixture_default_onnx_str() -> bytes:

# Train sklearn model
train_x = torch.arange(10).view(-1, 1)
train_y = torch.arange(10).view(-1, 1)
train_y = torch.arange(10)
model = BayesianRidge()
model.fit(train_x, train_y)

Expand Down Expand Up @@ -951,9 +958,6 @@ def fixture_default_onnx_surrogate(onnx_str) -> CustomONNXSurrogate:
match=r".*Expected value argument.*to be within the support.*"
),
),
before_sleep=lambda x: warnings.warn(
f"Retrying iteration test due to '{x.outcome.exception()}'"
),
)
def run_iterations(
campaign: Campaign, n_iterations: int, batch_size: int, add_noise: bool = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ def prepare_measurements() -> pd.DataFrame:
)

with warnings.catch_warnings(record=True) as captured_warnings:
warnings.filterwarnings("always", category=MinimumCardinalityViolatedWarning)
BotorchRecommender().recommend(
BATCH_SIZE, searchspace, objective, prepare_measurements()
)
Expand Down
2 changes: 1 addition & 1 deletion tests/constraints/test_constraints_continuous.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def test_hybridspace_ineq(campaign, n_iterations, batch_size):
param(["A", "B"], [1.0, 2.0, 3.0], 0.0, ">=", id="ineq_too_many_coeffs"),
param(["A", "B"], [1.0, 2.0], "bla", ">=", id="ineq_invalid_rhs"),
param(["A", "B"], [1.0, 2.0], 0.0, "invalid", id="ineq_invalid_operator1"),
param(["A", "B"], [1.0, 2.0], 0.0, 2.0, id="ineq_invalid_operator1"),
param(["A", "B"], [1.0, 2.0], 0.0, 2.0, id="ineq_invalid_operator2"),
],
)
def test_invalid_constraints(parameters, coefficients, rhs, op):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
from baybe.recommenders import BotorchRecommender
from baybe.utils.basic import get_subclasses

abbreviation_list = [
abbreviations = [
cl.abbreviation
for cl in get_subclasses(AcquisitionFunction)
if hasattr(cl, "abbreviation")
]
fullnames = [cl.__name__ for cl in get_subclasses(AcquisitionFunction)]
combined = set(abbreviations + fullnames)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a set for pytest.mark.parametrize makes test collection order non-deterministic (hash-randomized), which can lead to flaky ordering/IDs across runs and platforms. Consider keeping the de-duplication but switching to a deterministic sequence (e.g., sorted(set(...))) before passing it to parametrize.

Suggested change
combined = set(abbreviations + fullnames)
combined = sorted(set(abbreviations + fullnames))

Copilot uses AI. Check for mistakes.

fullname_list = [cl.__name__ for cl in get_subclasses(AcquisitionFunction)]


@pytest.mark.parametrize("acqf", abbreviation_list + fullname_list)
@pytest.mark.parametrize("acqf", combined)
def test_creation_from_string(acqf):
"""Tests the creation from strings."""
AcquisitionFunction.from_dict({"type": acqf})


@pytest.mark.parametrize("acqf", abbreviation_list + fullname_list)
@pytest.mark.parametrize("acqf", combined)
def test_string_usage_in_recommender(acqf):
"""Tests the recommender initialization with acqfs as string."""
BotorchRecommender(acquisition_function=acqf)
21 changes: 17 additions & 4 deletions tests/test_deprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ def test_target_deprecation_helpers():
NumericalTarget.from_modern_interface("t", minimize=True)


@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_target_legacy_deserialization():
"""Deserialization also works from legacy arguments."""
actual = NumericalTarget.from_dict({"name": "t", "mode": "MATCH", "bounds": (1, 2)})
Expand All @@ -259,6 +260,7 @@ def series() -> pd.Series:
return sample_input()


@pytest.mark.filterwarnings("ignore::DeprecationWarning")
@pytest.mark.parametrize("mode", ["MAX", "MIN"])
def test_constructor_equivalence_min_max(mode):
"""
Expand Down Expand Up @@ -300,6 +302,7 @@ def test_constructor_equivalence_min_max(mode):
assert t1 == t2


@pytest.mark.filterwarnings("ignore::DeprecationWarning")
@pytest.mark.parametrize("transformation", ["TRIANGULAR", "BELL"])
def test_constructor_equivalence_match(transformation):
"""
Expand Down Expand Up @@ -340,9 +343,13 @@ def test_constructor_equivalence_match(transformation):
assert t1 == t2


@pytest.mark.parametrize(
("legacy", "deprecation", "modern", "expected"),
[
# NOTE: The parametrize values below use the deprecated legacy interface of
# ModernTarget (e.g. ModernTarget("t", "MAX")), which emits DeprecationWarning.
# Since these are evaluated at module/collection time, we suppress the warning here
# to avoid failures when running with `-W error`.
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
_target_transformation_params = [
param(
LegacyTarget("t", "MAX"),
ModernTarget("t", "MAX"),
Expand Down Expand Up @@ -464,7 +471,12 @@ def test_constructor_equivalence_match(transformation):
triangular_transform(sample_input(), 2, 6),
id="match_triangular_scaled_shifted",
),
],
]


@pytest.mark.parametrize(
("legacy", "deprecation", "modern", "expected"),
_target_transformation_params,
)
def test_target_transformation(
series,
Expand All @@ -482,6 +494,7 @@ def test_target_transformation(
assert_series_equal(modern.transform(series), expected)


@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_deserialization_using_constructor():
"""Deserialization using the 'constructor' field works despite having other
deprecation mechanisms in place.""" # noqa
Expand Down
6 changes: 5 additions & 1 deletion tests/test_surrogate.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ def test_invalid_model_params(model_cls, params):
model_cls(model_params=params)


@pytest.mark.skipif(
os.environ.get("BAYBE_TEST_ENV") != "FULLTEST",
reason="Most surrogates are only available in FULLTEST environment.",
)
@pytest.mark.parametrize(
"target_names",
[["Target_max"], ["Target_max_bounded", "Target_min_bounded"]],
Expand All @@ -185,7 +189,7 @@ def test_invalid_model_params(model_cls, params):
)
def test_continuous_incompatibility(campaign):
"""Using surrogates without gradients on continuous spaces fails expectedly."""
data = create_fake_input(campaign.parameters, campaign.targets)
data = create_fake_input(campaign.parameters, campaign.targets, n_rows=3)
campaign.add_measurements(data)

skip = False
Expand Down
Loading