@@ -1326,21 +1326,22 @@ def compute(self, e, mode, environment):
13261326 return self .target ._skrub_impl .estimator_
13271327
13281328
1329+ def _checked_get_attr (obj , obj_value , attr_name ):
1330+ try :
1331+ return getattr (obj_value , attr_name )
1332+ except AttributeError :
1333+ if isinstance (obj , DataOp ) and hasattr (obj .skb , attr_name ):
1334+ comment = f"Did you mean `.skb.{ attr_name } ` and forget the `.skb`?"
1335+ else :
1336+ comment = None
1337+ attribute_error (obj_value , attr_name , comment )
1338+
1339+
13291340class GetAttr (DataOpImpl ):
13301341 _fields = ["source_object" , "attr_name" ]
13311342
13321343 def compute (self , e , mode , environment ):
1333- try :
1334- return getattr (e .source_object , e .attr_name )
1335- except AttributeError :
1336- pass
1337- if isinstance (self .source_object , DataOp ) and hasattr (
1338- self .source_object .skb , e .attr_name
1339- ):
1340- comment = f"Did you mean `.skb.{ e .attr_name } ` and forget the `.skb`?"
1341- else :
1342- comment = None
1343- attribute_error (e .source_object , e .attr_name , comment )
1344+ return _checked_get_attr (self .source_object , e .source_object , e .attr_name )
13441345
13451346 def __repr__ (self ):
13461347 return f"<{ self .__class__ .__name__ } { short_repr (self .attr_name )} >"
@@ -1421,8 +1422,9 @@ class CallMethod(DataOpImpl):
14211422 _fields = ["obj" , "method_name" , "args" , "kwargs" ]
14221423
14231424 def compute (self , e , mode , environment ):
1425+ method = _checked_get_attr (self .obj , e .obj , e .method_name )
14241426 try :
1425- return getattr ( e . obj , e . method_name ) (* e .args , ** e .kwargs )
1427+ return method (* e .args , ** e .kwargs )
14261428 except Exception as err :
14271429 # Better error message if we used the pandas DataFrame's `apply()`
14281430 # but we meant `.skb.apply()`
0 commit comments