
    Q3jO                        d dl Z d dlmZ d dlmZ d dlZd dlmZ d dl	m
Z
mZmZmZmZmZ d dlmZmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZmZmZ d dlmZ d5dZ  e!       fdZ" ee d      Z#d6dZ$d Z% G d de&      Z' G d dee
      Z( G d dee
      Z) G d dee
      Z* G d dee
      Z+ G d de+      Z, G d de+      Z- G d  d!e+      Z. G d" d#ee
      Z/ G d$ d%e
      Z0d6d&Z1 G d' d(e      Z2 G d) d*ee      Z3 G d+ d,e3e      Z4 G d- d.eee
      Z5 G d/ d0eee
      Z6 G d1 d2eee
      Z7 G d3 d4eee
      Z8y)7    N)defaultdict)partial)assert_array_equal)BaseEstimatorClassifierMixinMetaEstimatorMixinRegressorMixinTransformerMixinclone)_Scorermean_squared_error)BaseCrossValidator)
GroupKFoldGroupsConsumerMixin)SIMPLE_METHODS)MetadataRouterMethodMappingprocess_routing)_check_partial_fit_first_callc                 d   t        j                         }|d   j                  }|d   j                  }t        | d      st	        d       | _        |s8|j                         D ci c]  \  }}t        |t              r|dk7  r|| }}}| j
                  |   |   j                  |       yc c}}w )zUtility function to store passed metadata to a method of obj.

    If record_default is False, kwargs whose values are "default" are skipped.
    This is so that checks on keyword arguments whose default was not changed
    are skipped.

          _recordsc                       t        t              S N)r   list     R/DATA/.local/lib/python3.12/site-packages/sklearn/tests/metadata_routing_common.py<lambda>z!record_metadata.<locals>.<lambda>*   s	    ;t+<r   defaultN)
inspectstackfunctionhasattrr   r   items
isinstancestrappend)objrecord_defaultkwargsr#   calleecallerkeyvals           r   record_metadatar1      s     MMOE1XF1XF3
#"#<= #LLN
*Sc3'C9,< H* 	 

 LL ''/
s   %"B,c           	      ^   t        | dt                     j                  |t                     j                  |t                     }|D ]  }t	        |j                               t	        |j                               k(  s)J d|j                          d|j                                 |j                         D ]r  \  }}||   }	||v r)|	't        j                  |	|      j                         r6J t        |	t        j                        rt        |	|       _|	|u rdJ d|	 d| d|          y)a  Check whether the expected metadata is passed to the object's method.

    Parameters
    ----------
    obj : estimator object
        sub-estimator to check routed params for
    method : str
        sub-estimator's method where metadata is routed to, or otherwise in
        the context of metadata routing referred to as 'callee'
    parent : str
        the parent method which should have called `method`, or otherwise in
        the context of metadata routing referred to as 'caller'
    split_params : tuple, default=empty
        specifies any parameters which are to be checked as being a subset
        of the original values
    **kwargs : dict
        passed metadata
    r   z	Expected z vs Nz
. Method: )getattrdictgetr   setkeysr&   npisinallr'   ndarrayr   )
r*   methodparentsplit_paramsr,   all_recordsrecordr/   valuerecorded_values
             r   check_recorded_metadatarC   4   s   ( 	Z(,,VTV<@@P   6;;=!S%77 	
d6;;=/:	
7 !,,.JC#C[N l"~'Aww~u599;;;nbjj9&~u=)U2 #N#34wjQ2 ) r   F)r+   c           	      X   t        | t              r0| D ]*  \  }}|
||v r||   }nd}t        |j                  |       , y|g n|}t        D ]U  }||v rt        | |      }|j                  j                         D cg c]  \  }}t        |t              s|| }	}}|	sUJ  yc c}}w )a  Check if a metadata request dict is empty.

    One can exclude a method or a list of methods from the check using the
    ``exclude`` parameter. If metadata_request is a MetadataRouter, then
    ``exclude`` can be of the form ``{"object" : [method, ...]}``.
    N)exclude)	r'   r   assert_request_is_emptyrouterr   r3   requestsr&   r(   )
metadata_requestrE   nameroute_mapping_excluder<   mmrpropaliaspropss
             r   rF   rF   b   s     "N3#3D-"tw"4=#M$8$8(K $4 	ObG W&/  #||113
3e%%): 3 	 

 y !
s   >B&c                     |j                         D ]"  \  }}t        | |      }|j                  |k(  r"J  t        D cg c]	  }||vs| }}|D ]#  }t	        t        | |      j                        s#J  y c c}w r   )r&   r3   rH   r   len)request
dictionaryr<   rH   rM   empty_methodss         r   assert_request_equalrV      s    &,,.gv&||x''' / +9U.F*<TV.MUww/88999   Vs   	A7A7c                       e Zd Zd Zd Zy)	_Registryc                     | S r   r   )selfmemos     r   __deepcopy__z_Registry.__deepcopy__       r   c                     | S r   r   rZ   s    r   __copy__z_Registry.__copy__   r]   r   N)__name__
__module____qualname__r\   r`   r   r   r   rX   rX      s    r   rX   c                   8    e Zd ZdZddZd	dZd	dZd
dZd	dZy)ConsumingRegressorac  A regressor consuming metadata.

    Parameters
    ----------
    registry : list, default=None
        If a list, the estimator will append itself to the list in order to have
        a reference to the estimator later on. Since that reference is not
        required in all tests, registration can be skipped by leaving this value
        as None.
    Nc                     || _         y r   registryrZ   rh   s     r   __init__zConsumingRegressor.__init__   	     r   c                 p    | j                   | j                   j                  |        t        | ||       | S Nsample_weightmetadatarh   r)   record_metadata_not_defaultrZ   Xyro   rp   s        r   partial_fitzConsumingRegressor.partial_fit   4    ==$MM  &#	
 r   c                 p    | j                   | j                   j                  |        t        | ||       | S rm   rq   rs   s        r   fitzConsumingRegressor.fit   rw   r   c                 ^    t        | ||       t        j                  t        |      f      S )Nrn   shape)rr   r8   zerosrR   rs   s        r   predictzConsumingRegressor.predict   s(    #	
 xxs1vi((r   c                      t        | ||       yNrn   r   rr   rs   s        r   scorezConsumingRegressor.score       #	
 r   r   r!   r!   Nr!   r!   )	ra   rb   rc   __doc__rj   rv   ry   r~   r   r   r   r   re   re      s     	!)r   re   c                   >    e Zd ZdZd
dZd ZddZd Zd Zd Z	d	 Z
y)NonConsumingClassifier5A classifier which accepts no metadata on any method.c                     || _         y r   )alpha)rZ   r   s     r   rj   zNonConsumingClassifier.__init__   s	    
r   c                 n    t        j                  |      | _        t        j                  |      | _        | S r   )r8   uniqueclasses_	ones_likecoef_rZ   rt   ru   s      r   ry   zNonConsumingClassifier.fit   s%    		!\\!_
r   Nc                     | S r   r   )rZ   rt   ru   classess       r   rv   z"NonConsumingClassifier.partial_fit   r]   r   c                 $    | j                  |      S r   )r~   rZ   rt   s     r   decision_functionz(NonConsumingClassifier.decision_function   s    ||Ar   c                     t        j                  t        |      f      }d|d t        |      dz   d|t        |      dz  d  |S )Nr{   r   r   r   )r8   emptyrR   )rZ   rt   y_preds      r   r~   zNonConsumingClassifier.predict   sC    Q	* !}Q1 !s1v{}r   c                 2   t        j                  t        |      t        | j                        ft         j                        }t         j
                  j                  t        j                  t        | j                              t        |            |d d  |S )Nr|   dtyper   size)r8   r   rR   r   float32random	dirichletones)rZ   rt   y_probas      r   predict_probaz$NonConsumingClassifier.predict_proba   sc    ((#a&#dmm*<!=RZZPYY((rwws4==7I/JQTUVQW(X
r   c                 $    | j                  |      S r   )r   r   s     r   predict_log_probaz(NonConsumingClassifier.predict_log_proba   s    !!!$$r   )        r   )ra   rb   rc   r   rj   ry   rv   r   r~   r   r   r   r   r   r   r      s(    ?
%r   r   c                   "    e Zd ZdZd Zd Zd Zy)NonConsumingRegressorr   c                     | S r   r   r   s      r   ry   zNonConsumingRegressor.fit   r]   r   c                     | S r   r   r   s      r   rv   z!NonConsumingRegressor.partial_fit   r]   r   c                 >    t        j                  t        |            S r   )r8   r   rR   r   s     r   r~   zNonConsumingRegressor.predict   s    wws1vr   N)ra   rb   rc   r   ry   rv   r~   r   r   r   r   r      s    ?r   r   c                   R    e Zd ZdZddZ	 ddZddZddZddZddZ	dd	Z
dd
Zy)ConsumingClassifiera  A classifier consuming metadata.

    Parameters
    ----------
    registry : list, default=None
        If a list, the estimator will append itself to the list in order to have
        a reference to the estimator later on. Since that reference is not
        required in all tests, registration can be skipped by leaving this value
        as None.

    alpha : float, default=0
        This parameter is only used to test the ``*SearchCV`` objects, and
        doesn't do anything.
    Nc                      || _         || _        y r   )r   rh   )rZ   rh   r   s      r   rj   zConsumingClassifier.__init__  s    
 r   c                     | j                   | j                   j                  |        t        | ||       t        | |       | S rm   )rh   r)   rr   r   )rZ   rt   ru   r   ro   rp   s         r   rv   zConsumingClassifier.partial_fit  s@     ==$MM  &#	
 	&dG4r   c                     | j                   | j                   j                  |        t        | ||       t        j                  |      | _        t        j                  |      | _        | S rm   )rh   r)   rr   r8   r   r   r   r   rs   s        r   ry   zConsumingClassifier.fit  sR    ==$MM  &#	
 		!\\!_
r   c                     t        | ||       t        j                  t        |      fd      }d|t        |      dz  d  d|d t        |      dz   |S )Nrn   int8r   r   r   r   rr   r8   r   rR   rZ   rt   ro   rp   y_scores        r   r~   zConsumingClassifier.predict   sV    #	
 ((#a&&9!"A!!"#a&A+r   c                 N   t        | ||       t        j                  t        |      t        | j                        ft        j
                        }t        j                  j                  t        j                  t        | j                              t        |            |d d  |S )Nrn   r   r   )	rr   r8   r   rR   r   r   r   r   r   )rZ   rt   ro   rp   r   s        r   r   z!ConsumingClassifier.predict_proba)  st    #	
 ((#a&#dmm*<!=RZZPYY((rwws4==7I/JQTUVQW(X
r   c                 @    t        | ||       | j                  |      S rm   )rr   r   rZ   rt   ro   rp   s       r   r   z%ConsumingClassifier.predict_log_proba2  s$    #	
 !!!$$r   c                     t        | ||       t        j                  t        |      f      }d|t        |      dz  d  d|d t        |      dz   |S )Nrn   r{   r   r   r   r   r   s        r   r   z%ConsumingClassifier.decision_function8  sT    #	
 ((#a&+!"A!!"#a&A+r   c                      t        | ||       yr   r   rs   s        r   r   zConsumingClassifier.scoreA  r   r   )Nr   r   r   )ra   rb   rc   r   rj   rv   ry   r~   r   r   r   r   r   r   r   r   r      s6    !
 EN

%r   r   c                        e Zd ZdZed        Zy)&ConsumingClassifierWithoutPredictProbazConsumingClassifier without a predict_proba method, but with predict_log_proba.

    Used to mimic dynamic method selection such as in the `_parallel_predict_proba()`
    function called by `BaggingClassifier`.
    c                     t        d      Nz-This estimator does not support predict_probaAttributeErrorr_   s    r   r   z4ConsumingClassifierWithoutPredictProba.predict_probaO      LMMr   N)ra   rb   rc   r   propertyr   r   r   r   r   r   H  s     N Nr   r   c                        e Zd ZdZed        Zy))ConsumingClassifierWithoutPredictLogProbazConsumingClassifier without a predict_log_proba method, but with predict_proba.

    Used to mimic dynamic method selection such as in
    `BaggingClassifier.predict_log_proba()`.
    c                     t        d      Nz1This estimator does not support predict_log_probar   r_   s    r   r   z;ConsumingClassifierWithoutPredictLogProba.predict_log_proba[      PQQr   N)ra   rb   rc   r   r   r   r   r   r   r   r   T  s     R Rr   r   c                   0    e Zd ZdZed        Zed        Zy)"ConsumingClassifierWithOnlyPredictzConsumingClassifier with only a predict method.

    Used to mimic dynamic method selection such as in
    `BaggingClassifier.predict_log_proba()`.
    c                     t        d      r   r   r_   s    r   r   z0ConsumingClassifierWithOnlyPredict.predict_probag  r   r   c                     t        d      r   r   r_   s    r   r   z4ConsumingClassifierWithOnlyPredict.predict_log_probak  r   r   N)ra   rb   rc   r   r   r   r   r   r   r   r   r   `  s3     N N R Rr   r   c                   8    e Zd ZdZddZd	dZd
dZd
dZddZy)ConsumingTransformera~  A transformer which accepts metadata on fit and transform.

    Parameters
    ----------
    registry : list, default=None
        If a list, the estimator will append itself to the list in order to have
        a reference to the estimator later on. Since that reference is not
        required in all tests, registration can be skipped by leaving this value
        as None.
    Nc                     || _         y r   rg   ri   s     r   rj   zConsumingTransformer.__init__|  rk   r   c                 ~    | j                   | j                   j                  |        t        | ||       d| _        | S )Nrn   T)rh   r)   rr   fitted_rs   s        r   ry   zConsumingTransformer.fit  s;    ==$MM  &#	
 r   c                 (    t        | ||       |dz   S r   r   r   s       r   	transformzConsumingTransformer.transform      #	
 1ur   c                 l    t        | ||       | j                  ||||      j                  |||      S rm   )rr   ry   r   rs   s        r   fit_transformz"ConsumingTransformer.fit_transform  sF    
 	$	
 xx1MHxMWW]X X 
 	
r   c                 (    t        | ||       |dz
  S r   r   r   s       r   inverse_transformz&ConsumingTransformer.inverse_transform  r   r   r   r   r   NN)	ra   rb   rc   r   rj   ry   r   r   r   r   r   r   r   r   p  s     	!

r   r   c                   (    e Zd ZdZddZddZddZy)	"ConsumingNoFitTransformTransformerzA metadata consuming transformer that doesn't inherit from
    TransformerMixin, and thus doesn't implement `fit_transform`. Note that
    TransformerMixin's `fit_transform` doesn't route metadata to `transform`.Nc                     || _         y r   rg   ri   s     r   rj   z+ConsumingNoFitTransformTransformer.__init__  rk   r   c                 p    | j                   | j                   j                  |        t        | ||       | S rm   )rh   r)   r1   rs   s        r   ry   z&ConsumingNoFitTransformTransformer.fit  s/    ==$MM  &MHMr   c                 "    t        | ||       |S rm   )r1   r   s       r   r   z,ConsumingNoFitTransformTransformer.transform  s    MHMr   r   NNNr   )ra   rb   rc   r   rj   ry   r   r   r   r   r   r     s    Q!r   r   c                     ||j                  t               t        t        fi | |j                  dd       }t	        | ||      S )Nro   ro   )r)   consuming_metricrr   r5   r   )r   y_truerh   r,   ro   s        r   r   r     sB    () 0;F;JJ5MffMJJr   c                         e Zd Zd fd	Z xZS )ConsumingScorerc                 \    t        t        |      }t        |   |di d       || _        y )Nrg   r   r~   )
score_funcsignr,   response_method)r   r   superrj   rh   )rZ   rh   r   	__class__s      r   rj   zConsumingScorer.__init__  s4    -A
!"i 	 	
 !r   r   )ra   rb   rc   rj   __classcell__)r   s   @r   r   r     s    ! !r   r   c                   ,    e Zd ZddZddZddZd	dZy)
ConsumingSplitterNc                     || _         y r   rg   ri   s     r   rj   zConsumingSplitter.__init__  rk   r   c              #     K   | j                   | j                   j                  |        t        | ||       t        |      dz  }t	        t        d|            }t	        t        |t        |                  }||f ||f y w)N)groupsrp   r   r   )rh   r)   rr   rR   r   range)rZ   rt   ru   r   rp   split_indextrain_indicestest_indicess           r   splitzConsumingSplitter.split  sw     ==$MM  &#D(K!fkU1k23E+s1v67M))\))s   BBc                      y)Nr   r   )rZ   rt   ru   r   rp   s        r   get_n_splitszConsumingSplitter.get_n_splits  s    r   c              #      K   t        |      dz  }t        t        d|            }t        t        |t        |                  }| | y w)Nr   r   )rR   r   r   )rZ   rt   ru   r   r   r   r   s          r   _iter_test_indicesz$ConsumingSplitter._iter_test_indices  sE     !fkU1k23E+s1v67s   AAr   r   )NNNNr   )ra   rb   rc   rj   r   r   r   r   r   r   r   r     s    !
*r   r   c                       e Zd ZdZy))ConsumingSplitterInheritingFromGroupKFoldz\Helper class that can be used to test TargetEncoder, that only takes specific
    splitters.N)ra   rb   rc   r   r   r   r   r   r     s    r   r   c                   "    e Zd ZdZd Zd Zd Zy)MetaRegressorz(A meta-regressor which is only a router.c                     || _         y r   )	estimator)rZ   r   s     r   rj   zMetaRegressor.__init__  s	    "r   c                     t        | dfi |} t        | j                        j                  ||fi |j                  j                  | _        y Nry   )r   r   r   ry   
estimator_rZ   rt   ru   
fit_paramsparamss        r   ry   zMetaRegressor.fit  sC     u;
;3%/33AqQF<L<L<P<PQr   c                     t        |       j                  | j                  t               j                  dd            }|S Nownerry   r.   r-   r   method_mapping)r   addr   r   rZ   rG   s     r   get_metadata_routingz"MetaRegressor.get_metadata_routing  s?    d+//nn(?..eE.J 0 
 r   Nra   rb   rc   r   rj   ry   r  r   r   r   r   r     s    2#Rr   r   c                   ,    e Zd ZdZddZddZd Zd Zy)WeightedMetaRegressorz*A meta-regressor which is also a consumer.Nc                      || _         || _        y r   r   rh   rZ   r   rh   s      r   rj   zWeightedMetaRegressor.__init__      " r   c                    | j                   | j                   j                  |        t        | |       t        | dfd|i|} t	        | j
                        j                  ||fi |j
                  j                  | _        | S Nr   ry   ro   rh   r)   r1   r   r   r   ry   r  )rZ   rt   ru   ro   r  r  s         r   ry   zWeightedMetaRegressor.fit  ss    ==$MM  &M: uXMXZX3%/33AqQF<L<L<P<PQr   c                 ~    t        | dfi |} | j                  j                  |fi |j                  j                  S )Nr~   )r   r  r~   r   )rZ   rt   predict_paramsr  s       r   r~   zWeightedMetaRegressor.predict
  s;     yCNC&t&&qEF,<,<,D,DEEr   c                     t        |       j                  |       j                  | j                  t	               j                  dd      j                  dd            }|S )Nr	  ry   r  r~   r  r   add_self_requestr  r   r   r  s     r   r  z*WeightedMetaRegressor.get_metadata_routing  sX    &d#S..,E%0Ii8	   	 r   r   )ra   rb   rc   r   rj   ry   r~   r  r   r   r   r  r    s    4!Fr   r  c                   &    e Zd ZdZddZddZd Zy)WeightedMetaClassifierzEA meta-estimator which also consumes sample_weight itself in ``fit``.Nc                      || _         || _        y r   r  r  s      r   rj   zWeightedMetaClassifier.__init__  r  r   c                    | j                   | j                   j                  |        t        | |       t        | dfd|i|} t	        | j
                        j                  ||fi |j
                  j                  | _        | S r  r  )rZ   rt   ru   ro   r,   r  s         r   ry   zWeightedMetaClassifier.fit#  ss    ==$MM  &M: uTMTVT3%/33AqQF<L<L<P<PQr   c                     t        |       j                  |       j                  | j                  t	               j                  dd            }|S r  r  r  s     r   r  z+WeightedMetaClassifier.get_metadata_routing,  sL    &d#S..,22%2N   	 r   r   r  r   r   r   r!  r!    s    O!	r   r!  c                   ,    e Zd ZdZd ZddZddZd Zy)MetaTransformerzA simple meta-transformer.c                     || _         y r   )transformer)rZ   r(  s     r   rj   zMetaTransformer.__init__;  s
    &r   Nc                     t        | dfi |} t        | j                        j                  ||fi |j                  j                  | _        | S r  )r   r   r(  ry   transformer_r  s        r   ry   zMetaTransformer.fit>  sK     u;
;7E$"2"23771W@R@R@V@VWr   c                 ~    t        | dfi |} | j                  j                  |fi |j                  j                  S )Nr   )r   r*  r   r(  )rZ   rt   ru   transform_paramsr  s        r   r   zMetaTransformer.transformC  s>     {G6FG*t  **1M0B0B0L0LMMr   c                     t        |       j                  | j                  t               j                  dd      j                  dd            S )Nr	  ry   r  r   )r(  r  )r   r  r(  r   r_   s    r   r  z$MetaTransformer.get_metadata_routingG  sI    D)--(((?SeS,SKS8	 . 
 	
r   r   )ra   rb   rc   r   rj   ry   r   r  r   r   r   r&  r&  8  s    $'
N
r   r&  )Tr   )9r"   collectionsr   	functoolsr   numpyr8   numpy.testingr   sklearn.baser   r   r   r	   r
   r   sklearn.metrics._scorerr   r   sklearn.model_selectionr   sklearn.model_selection._splitr   r    sklearn.utils._metadata_requestsr   sklearn.utils.metadata_routingr   r   r   sklearn.utils.multiclassr   r1   tuplerC   rr   rF   rV   r   rX   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r!  r&  r   r   r   <module>r:     st    #   ,  @ 6 J 
 C0, ?Dg (V &oeL ::
 
+ +\ %_m  %F
NM 
Q/= Qh	N-@ 	N	R0C 	RR)< R /+] /d *K!g !+-? 60A: 
& $. D/- 8
(*:M 
r   