Check set_params(**get_params(deep=True)) is a no-op.
Also asserts every get_params(deep=False) key is a constructor
parameter (the sklearn get_params contract).
Parameters
Raises
| Type |
Description |
AssertionError
|
If a get_params(deep=False) key is absent from the constructor
parameters.
|
AssertionError
|
If set_params(**get_params(deep=True)) mutates any shallow
parameter value.
|
Source Code
View on GitHub
Source code in src/yohou/testing/contract.py
| def check_get_set_params_round_trip(estimator) -> None:
"""Check ``set_params(**get_params(deep=True))`` is a no-op.
Also asserts every ``get_params(deep=False)`` key is a constructor
parameter (the sklearn ``get_params`` contract).
Parameters
----------
estimator : BaseEstimator
Estimator instance.
Raises
------
AssertionError
If a ``get_params(deep=False)`` key is absent from the constructor
parameters.
AssertionError
If ``set_params(**get_params(deep=True))`` mutates any shallow
parameter value.
"""
name = type(estimator).__name__
init_params = {p for p in inspect.signature(type(estimator).__init__).parameters if p != "self"}
shallow = estimator.get_params(deep=False)
for key in shallow:
assert key in init_params, f"{name}: get_params key {key!r} is not a constructor parameter"
before = estimator.get_params(deep=False)
estimator.set_params(**estimator.get_params(deep=True))
after = estimator.get_params(deep=False)
assert set(before.keys()) == set(after.keys()), f"{name}: set_params round-trip changed parameter keys"
for key, before_val in before.items():
after_val = after[key]
if isinstance(before_val, BaseEstimator) or (
isinstance(before_val, list) and before_val and isinstance(before_val[0], tuple)
):
continue # nested estimators compare by identity/structure, not equality
assert _safe_equal(before_val, after_val), (
f"{name}: set_params round-trip changed {key!r}: {before_val!r} -> {after_val!r}"
)
|