Skip to content

[Callbacks] FEA Define callback behaviour when cloning an estimator#33340

Merged
lesteve merged 31 commits intoscikit-learn:callbacksfrom
FrancoisPgm:clone_callbacks
Mar 11, 2026
Merged

[Callbacks] FEA Define callback behaviour when cloning an estimator#33340
lesteve merged 31 commits intoscikit-learn:callbacksfrom
FrancoisPgm:clone_callbacks

Conversation

@FrancoisPgm
Copy link
Copy Markdown
Contributor

Reference Issues/PRs

Towards #33323

What does this implement/fix? Explain your changes.

When used on an estimator holding callbacks, clone now discards the callbacks in the clone, raising a warning.
For callback-compatible meta estimator which need to clone sub-estimators, propagate_callbacks now offers a way to clone the sub-estimators while forwarding the callbacks to the clone and silencing the warning.

AI usage disclosure

I used AI assistance for:

  • Code generation (e.g., when writing an implementation or fixing a bug)
  • Test/benchmark generation
  • Documentation (including examples)
  • Research and understanding

Any other comments?

Copy link
Copy Markdown
Member

@jeremiedbb jeremiedbb left a comment

Choose a reason for hiding this comment

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

Thanks for the PR. A few comments.

FrancoisPgm and others added 3 commits February 23, 2026 10:59
Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai>
Copy link
Copy Markdown
Member

@jeremiedbb jeremiedbb left a comment

Choose a reason for hiding this comment

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

A few more nitpicks. Otherwise LGTM.

Ping @ogrisel for a second review is possible. As discussed in a previous call, this PR makes clone discard the callbacks such that if an estimator with callbacks is passed to a function or meta-estimator that doesn't have callback support, then nothing breaks but the callbacks have no effect.

FrancoisPgm and others added 2 commits February 23, 2026 13:43
Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai>
Copy link
Copy Markdown
Member

@jeremiedbb jeremiedbb left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks !

Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai>
Comment on lines +405 to +415
if clone_estimator:
from sklearn.base import clone

with warnings.catch_warnings():
warnings.filterwarnings(
"ignore", message="There are callbacks set on the estimator "
)
cloned_estimator = clone(sub_estimator)
if hasattr(sub_estimator, "_skl_callbacks"):
cloned_estimator.set_callbacks(sub_estimator._skl_callbacks)
sub_estimator = cloned_estimator
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nitpick: I'd put the callbacks_to_propagate right before the if not callbacks_to_propagate

@jeremiedbb jeremiedbb added the Waiting for Second Reviewer First reviewer is done, need a second one! label Feb 26, 2026
@jeremiedbb jeremiedbb added this to Labs Feb 26, 2026
@jeremiedbb jeremiedbb moved this to In progress in Labs Feb 26, 2026
Comment on lines +361 to +365
def propagate_callback_context(self, sub_estimator, clone_estimator=False):
"""Propagate the callbacks and the context to a sub-estimator.

The callbacks are propagated to a clone of the sub-estimator instead if
clone_estimator is set to True.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed in the last meeting, let's add an extra arg to clone instead to transfer the callbacks with 3 options: True/False/"warn". "warn" being the default and meaning discard the callbacks with a warning

@jeremiedbb
Copy link
Copy Markdown
Member

@ogrisel @StefanieSenger @lesteve I opened #33421 as the alternative that we discussed during last meeting, that is add an option in clone to keep the callbacks or not.

Copy link
Copy Markdown
Member

@StefanieSenger StefanieSenger left a comment

Choose a reason for hiding this comment

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

Thank you @FrancoisPgm, I have a few comments, but overall looks good to me.

FrancoisPgm and others added 2 commits March 9, 2026 15:00
Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com>
Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com>
FrancoisPgm and others added 4 commits March 9, 2026 17:35
Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com>
Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com>
Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com>
@github-actions github-actions bot added the CI:Linter failure The linter CI is failing on this PR label Mar 9, 2026
@github-actions github-actions bot removed the CI:Linter failure The linter CI is failing on this PR label Mar 9, 2026
Copy link
Copy Markdown
Member

@StefanieSenger StefanieSenger left a comment

Choose a reason for hiding this comment

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

Thanks for addressing my review comments, @FrancoisPgm.

What is lacking for me is a test against what exactly would crash / not work as expected if we do not implement these changes.

I've raised this more concretely here and in the comments before.

Copy link
Copy Markdown
Member

@ogrisel ogrisel left a comment

Choose a reason for hiding this comment

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

Thanks @FrancoisPgm. The PR LGTM besides the following:

sklearn/base.py Outdated
warnings.warn(
f"There are callbacks set on the estimator {estimator.__class__.__name__} "
"being cloned. The callbacks will be discarded in the clone."
) # TODO: add a link to some documentation for callback support.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it would be cleaner to create a dedicated warning class under sklearn.exceptions (for instance sklearn.exception.CloneWithCallbacksWarning) to catch instances of this warning explicitly in CallbackContext.clone_and_propagate_callback_context without relying on string message matching.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Very good point, thx :)

"""Test the warning when cloning an estimator with callback registered to it."""
estimator = MaxIterEstimator()
estimator.set_callbacks(TestingCallback())
with pytest.warns(UserWarning, match="There are callbacks set on the estimator "):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should also be updated to test the specific warning class.

FrancoisPgm and others added 3 commits March 10, 2026 17:55
Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
@github-actions github-actions bot added the CI:Linter failure The linter CI is failing on this PR label Mar 10, 2026
@github-actions github-actions bot removed the CI:Linter failure The linter CI is failing on this PR label Mar 10, 2026
Copy link
Copy Markdown
Member

@lesteve lesteve left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

As noted by others, it would be nice to figure out exactly what breaks when we don't discard callbacks and add a relevant test.

@lesteve lesteve merged commit 3a8ae00 into scikit-learn:callbacks Mar 11, 2026
24 checks passed
@github-project-automation github-project-automation bot moved this from In progress to Done in Labs Mar 11, 2026
@jeremiedbb jeremiedbb moved this from Done to In progress in Labs Mar 14, 2026
@jeremiedbb jeremiedbb removed the status in Labs Mar 14, 2026
@jeremiedbb jeremiedbb moved this to Done in Labs Mar 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Callbacks No Changelog Needed Waiting for Second Reviewer First reviewer is done, need a second one!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants