Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
dfacaf9
MNT refactoring in routing _MetadataRequester
adrinjalali Jun 12, 2025
2ce9536
use custom repr method
adrinjalali Jun 14, 2025
97b95b0
revert test changes
adrinjalali Jun 14, 2025
3b8a725
fix tests
adrinjalali Jun 14, 2025
4615419
Merge remote-tracking branch 'upstream/main' into slep6/refactor
adrinjalali Jun 14, 2025
7552eb8
Update sklearn/utils/_metadata_requests.py
adrinjalali Jun 19, 2025
84f9373
reviews
adrinjalali Jul 2, 2025
3082872
reviews
adrinjalali Jul 2, 2025
eeac756
Merge remote-tracking branch 'upstream/main' into slep6/refactor
adrinjalali Jul 2, 2025
0880b95
Merge branch 'slep6/refactor' of github.com:adrinjalali/scikit-learn …
adrinjalali Jul 2, 2025
d59b242
Stefanie's comments
adrinjalali Aug 5, 2025
de827d6
Merge remote-tracking branch 'upstream/main' into slep6/refactor
adrinjalali Aug 5, 2025
a9969cd
change owner=self.__class__.__name__ instances
adrinjalali Aug 6, 2025
bdad400
Merge remote-tracking branch 'upstream/main' into slep6/refactor
adrinjalali Aug 7, 2025
63569a6
FIX make sure _PassthroughScorer works with meta-estimators
adrinjalali Aug 8, 2025
d6218f7
changelog
adrinjalali Aug 8, 2025
1ac76e2
Merge remote-tracking branch 'upstream/main' into slep6/pipeline/score
adrinjalali Aug 8, 2025
c8057b5
Merge remote-tracking branch 'upstream/main' into slep6/pipeline/score
adrinjalali Aug 11, 2025
7282883
Apply suggestions from code review
adrinjalali Aug 12, 2025
efdb799
Update sklearn/metrics/_scorer.py
adrinjalali Aug 12, 2025
e2debd9
no need to override method
adrinjalali Aug 21, 2025
dcbe700
Merge remote-tracking branch 'upstream/main' into slep6/pipeline/score
adrinjalali Aug 21, 2025
3a7f7ab
Merge branch 'slep6/pipeline/score' of github.com:adrinjalali/scikit-…
adrinjalali Aug 21, 2025
ed94f72
simplify
adrinjalali Aug 22, 2025
729b29b
Merge remote-tracking branch 'upstream/main' into slep6/refactor
adrinjalali Aug 22, 2025
5d654b8
Merge remote-tracking branch 'upstream/main' into slep6/refactor
adrinjalali Sep 4, 2025
b0c85dc
Update sklearn/utils/_metadata_requests.py
adrinjalali Sep 4, 2025
223054c
FIX descriptor shouldn't override method
adrinjalali Sep 5, 2025
6e3bb6d
Apply suggestions from code review
adrinjalali Sep 5, 2025
74287a3
Merge branch 'main' into slep6/refactor
OmarManzoor Sep 5, 2025
3eb2188
Merge branch 'slep6/refactor' into slep6/override
adrinjalali Sep 5, 2025
2666a5d
Merge remote-tracking branch 'upstream/main' into slep6/override
adrinjalali Sep 5, 2025
1c9d7cf
add changelog
adrinjalali Sep 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/whats_new/upcoming_changes/metadata-routing/32111.fix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- If a class explicitly defines a `set_{method}_request` method, it will not be
overridden by the metadata routing machinery.
By `Adrin Jalali`_
39 changes: 39 additions & 0 deletions sklearn/tests/test_metadata_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1162,3 +1162,42 @@ def fit(self, X, y, sample_weight=None):
# Test positional arguments error after making the descriptor method unbound.
with pytest.raises(TypeError, match=error_message):
A().set_fit_request(True)


@config_context(enable_metadata_routing=True)
def test_removing_metadata_in_subclass_correctly_works():
"""Test that removing a metadata with UNUSED marker affects child's method."""

class A(ConsumingClassifier):
__metadata_request__score = {
"sample_weight": metadata_routing.UNUSED,
"metadata": metadata_routing.UNUSED,
}

# Here we make sure that the parent class has the method as usual
assert hasattr(ConsumingClassifier(), "set_score_request")
# And that the child class doesn't have it since all metadata for the score method
# are removed.
with pytest.raises(
TypeError,
match=re.escape(
"Unexpected args: {'sample_weight'} in score. Accepted arguments are: set()"
),
):
A().set_score_request(sample_weight=True)


@config_context(enable_metadata_routing=True)
def test_explicitly_defined_set_method_request_is_not_overriden():
"""Test that explicitly defined set_{method}_request is not overridden."""

class A(BaseEstimator):
def set_score_request(self, sample_weight=None, metadata=None):
return self # pragma: no cover

class B(A):
def score(self, X, y=None):
pass # pragma: no cover

# This should work as usual since the method is explicitly defined.
B().set_score_request(sample_weight=True)
25 changes: 23 additions & 2 deletions sklearn/utils/_metadata_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1438,14 +1438,35 @@ def __init_subclass__(cls, **kwargs):
----------
.. [1] https://www.python.org/dev/peps/pep-0487
"""

def is_RequestMethod(obj, name: str):
value = inspect.getattr_static(obj, name)
return isinstance(value, RequestMethod)

try:
for method in SIMPLE_METHODS:
set_method_name = f"set_{method}_request"
requests = cls._get_class_level_metadata_request_values(method)
if not requests:
if hasattr(cls, set_method_name) and not is_RequestMethod(
cls, set_method_name
):
# The method is not a descriptor, which means it's explicitly\
# defined in the class, therefore we skip overriding it with a
# descriptor here.
# This happens, for instance in Scorers where the
# `set_score_request` method is defined in the class.
continue

if not requests and not hasattr(cls, set_method_name):
# It can be the case that requests here is empty due to removing
# metadata with an UNUSED marker, and that the parent class has
# the method already. In this case, we cannot remove the method
# since it exists in the parent class, and instead we set it with
# an empty set of requests.
continue
setattr(
cls,
f"set_{method}_request",
set_method_name,
RequestMethod(method, sorted(requests)),
)
except Exception:
Expand Down
Loading