Skip to content

ENH available_if reraises inner error - #28198

Merged
glemaitre merged 2 commits into
scikit-learn:mainfrom
thomasjpfan:avaliable_if_reraise
Jan 22, 2024
Merged

ENH available_if reraises inner error#28198
glemaitre merged 2 commits into
scikit-learn:mainfrom
thomasjpfan:avaliable_if_reraise

Conversation

@thomasjpfan

Copy link
Copy Markdown
Member

Reference Issues/PRs

Related to #28108

What does this implement/fix? Explain your changes.

With this PR, available_if now reraises the inner error along with the AttributeError. That way, we get the both AttributeErrors from the meta-estimator and the sub-estimator. For example:

from sklearn.pipeline import make_pipeline
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
clf = make_pipeline(DecisionTreeClassifier()).fit(X, y)
clf.decision_function(X)

raises the following:

Exception
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~/Repos/scikit-learn-1/sklearn/utils/_available_if.py:29, in _AvailableIfDescriptor._check(self, obj, owner)
     28 try:
---> 29     check_result = self.check(obj)
     30 except Exception as e:

File ~/Repos/scikit-learn-1/sklearn/pipeline.py:53, in _final_estimator_has.<locals>.check(self)
     51 def check(self):
     52     # raise original `AttributeError` if `attr` does not exist
---> 53     getattr(self._final_estimator, attr)
     54     return True

AttributeError: 'DecisionTreeClassifier' object has no attribute 'decision_function'

The above exception was the direct cause of the following exception:

AttributeError                            Traceback (most recent call last)
Cell In[2], line 7
      5 X, y = load_iris(return_X_y=True)
      6 clf = make_pipeline(DecisionTreeClassifier()).fit(X, y)
----> 7 clf.decision_function(X)

File ~/Repos/scikit-learn-1/sklearn/utils/_available_if.py:40, in _AvailableIfDescriptor.__get__(self, obj, owner)
     36 def __get__(self, obj, owner=None):
     37     if obj is not None:
     38         # delegate only on instances, not the classes.
     39         # this is to allow access to the docstrings.
---> 40         self._check(obj, owner=owner)
     41         out = MethodType(self.fn, obj)
     43     else:
     44         # This makes it possible to use the decorated method as an unbound method,
     45         # for instance when monkeypatching.

File ~/Repos/scikit-learn-1/sklearn/utils/_available_if.py:31, in _AvailableIfDescriptor._check(self, obj, owner)
     29     check_result = self.check(obj)
     30 except Exception as e:
---> 31     raise AttributeError(attr_err_msg) from e
     33 if not check_result:
     34     raise AttributeError(attr_err_msg)

AttributeError: This 'Pipeline' has no attribute 'decision_function'

@github-actions

github-actions Bot commented Jan 20, 2024

Copy link
Copy Markdown

✔️ Linting Passed

All linting checks passed. Your pull request is in excellent shape! ☀️

Generated for commit: 6b4ee44. Link to the linter CI: here

@adrinjalali adrinjalali left a comment

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.

LGTM.

@glemaitre
glemaitre self-requested a review January 22, 2024 14:39
@glemaitre
glemaitre merged commit e1ec2cf into scikit-learn:main Jan 22, 2024
@glemaitre

Copy link
Copy Markdown
Member

Thanks @thomasjpfan

glemaitre pushed a commit to glemaitre/scikit-learn that referenced this pull request Feb 10, 2024
glemaitre pushed a commit to glemaitre/scikit-learn that referenced this pull request Feb 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants