Repository: scikit-learn/scikit-learn
File: sklearn/semi_supervised/tests/test_self_training.py (Python)

Code before:
        ],
        final_estimator=SVC(probability=True),
        cv=2,
    )

    assert hasattr(estimator, "predict_proba")
    clf = SelfTrainingClassifier(estimator=estimator)
    clf.fit(X_train, y_train_missing_labels)
    clf.predict_proba(X_test)

    estimator = StackingClassifier(
        estimators=[
            ("svc_1", SVC(probability=False)),
            ("svc_2", SVC(probability=False)),
        ],
        final_estimator=SVC(probability=False),
        cv=2,
    )

    assert not hasattr(estimator, "predict_proba")
    clf = SelfTrainingClassifier(estimator=estimator)
    with pytest.raises(AttributeError):
        clf.fit(X_train, y_train_missing_labels)


@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_self_training_estimator_attribute_error():
    """Check that we raise the proper AttributeErrors when the `estimator`
    does not implement the `predict_proba` method, which is called from within
    `fit`, or `decision_function`, which is decorated with `available_if`.

    Non-regression test for:
    https://github.com/scikit-learn/scikit-learn/issues/28108
    """
    # `SVC` with `probability=False` does not implement 'predict_proba' that
    # is required internally in `fit` of `SelfTrainingClassifier`. We expect
    # an AttributeError to be raised.
    estimator = SVC(probability=False, gamma="scale")
    self_training = SelfTrainingClassifier(estimator)

    with pytest.raises(AttributeError, match="has no attribute 'predict_proba'"):
        self_training.fit(X_train, y_train_missing_labels)

    # `DecisionTreeClassifier` does not implement 'decision_function' and
    # should raise an AttributeError
    self_training = SelfTrainingClassifier(estimator=DecisionTreeClassifier())

    outer_msg = "This 'SelfTrainingClassifier' has no attribute 'decision_function'"
    inner_msg = "'DecisionTreeClassifier' object has no attribute 'decision_function'"
    with pytest.raises(AttributeError, match=outer_msg) as exec_info:
        self_training.fit(X_train, y_train_missing_labels).decision_function(X_train)

Review comment (suggestion):
Here again we should update the test to remove the explicit `probability=False` constructor parameter and rely on the default non-probabilistic behavior of the `SVC` class instead of hiding the warning.

Code after:
        cv=2,
    )

    assert hasattr(estimator, "predict_proba")
    clf = SelfTrainingClassifier(estimator=estimator)
    clf.fit(X_train, y_train_missing_labels)
    clf.predict_proba(X_test)

    estimator = StackingClassifier(
        estimators=[
            ("svc_1", SVC()),
            ("svc_2", SVC()),
        ],
        final_estimator=SVC(),
        cv=2,
    )

    assert not hasattr(estimator, "predict_proba")
    clf = SelfTrainingClassifier(estimator=estimator)
    with pytest.raises(AttributeError):
        clf.fit(X_train, y_train_missing_labels)


def test_self_training_estimator_attribute_error():
    """Check that we raise the proper AttributeErrors when the `estimator`
    does not implement the `predict_proba` method, which is called from within
    `fit`, or `decision_function`, which is decorated with `available_if`.

    Non-regression test for:
    https://github.com/scikit-learn/scikit-learn/issues/28108
    """
    # `SVC` with `probability=False` does not implement 'predict_proba' that
    # is required internally in `fit` of `SelfTrainingClassifier`. We expect
    # an AttributeError to be raised.
    estimator = SVC(gamma="scale")
    self_training = SelfTrainingClassifier(estimator)

    with pytest.raises(AttributeError, match="has no attribute 'predict_proba'"):
        self_training.fit(X_train, y_train_missing_labels)

    # `DecisionTreeClassifier` does not implement 'decision_function' and
    # should raise an AttributeError
    self_training = SelfTrainingClassifier(estimator=DecisionTreeClassifier())

    outer_msg = "This 'SelfTrainingClassifier' has no attribute 'decision_function'"
    inner_msg = "'DecisionTreeClassifier' object has no attribute 'decision_function'"
    with pytest.raises(AttributeError, match=outer_msg) as exec_info:
        self_training.fit(X_train, y_train_missing_labels).decision_function(X_train)
    assert isinstance(exec_info.value.__cause__, AttributeError)
    assert inner_msg in str(exec_info.value.__cause__)