Skip to content

check_init_no_param_mutation

yohou.testing.check_init_no_param_mutation(estimator)

Check __init__ stores constructor arguments verbatim.

For every constructor parameter with a default, a default-constructed instance must store that exact default (e.g. metric_params=None stays None, never {}). Catches the init-mutation bug class.

Parameters

Name Type Description Default
estimator BaseEstimator

Estimator instance (used only for its type).

required

Raises

Type Description
AssertionError

If a stored attribute differs from the constructor default.

Source Code

Source code in src/yohou/testing/contract.py
def check_init_no_param_mutation(estimator) -> None:
    """Check ``__init__`` stores constructor arguments verbatim.

    For every constructor parameter with a default, a default-constructed
    instance must store that exact default (e.g. ``metric_params=None`` stays
    ``None``, never ``{}``). Catches the init-mutation bug class.

    Parameters
    ----------
    estimator : BaseEstimator
        Estimator instance (used only for its type).

    Raises
    ------
    AssertionError
        If a stored attribute differs from the constructor default.

    """
    cls = type(estimator)
    name = cls.__name__
    signature = inspect.signature(cls.__init__)

    if any(
        p.default is inspect.Parameter.empty and pname not in ("self",)
        for pname, p in signature.parameters.items()
        if p.kind in (p.POSITIONAL_OR_KEYWORD, p.KEYWORD_ONLY)
    ):
        return  # not default-constructible; skip (covered where representative instances exist)

    fresh = cls()
    for pname, param in signature.parameters.items():
        if pname == "self" or param.default is inspect.Parameter.empty:
            continue
        if not hasattr(fresh, pname):
            continue  # stored under a different name (e.g. a property); out of scope here
        stored = getattr(fresh, pname)
        default = param.default
        if default is None:
            assert stored is None, f"{name}: __init__ mutated {pname!r} from None to {stored!r}"
        else:
            assert stored == default, f"{name}: __init__ mutated {pname!r} from {default!r} to {stored!r}"