Skip to content

check_get_set_params_round_trip

yohou.testing.check_get_set_params_round_trip(estimator)

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

Name Type Description Default
estimator BaseEstimator

Estimator instance.

required

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

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}"
        )