o
    tBh0*                     @   s   d Z ddlmZmZ ddlmZ ddlZddlmZ ddl	m
Z
m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 d
dlmZ d
dlmZ ddgZG dd dee
dZG dd dZdd ZG dd deZdd ZdddZdS )zUtilities for meta-estimators    )ListAny)
MethodTypeN)wraps)ABCMetaabstractmethod)
attrgetter)update_wrapper)suppress   )_safe_indexing)
_safe_tags)BaseEstimatoravailable_ifif_delegate_has_methodc                       sX   e Zd ZU dZee ed< edd Zd fdd	Z	 fdd	Z
d
d Zdd Z  ZS )_BaseCompositionzJHandles parameter management for classifiers composed of named estimators.stepsc                 C   s   d S N )selfr   r   s/var/www/html/riverr-enterprise-integrations-main/venv/lib/python3.10/site-packages/sklearn/utils/metaestimators.py__init__   s   z_BaseComposition.__init__Tc           	   	      s   t  j|d}|s|S t| |}z|| W n ttfy$   | Y S w |D ]\}}t|drE|jdd D ]\}}||d||f < q8q'|S )Ndeep
get_paramsTz%s__%s)superr   getattrupdate	TypeError
ValueErrorhasattritems)	r   attrr   out
estimatorsname	estimatorkeyvalue	__class__r   r   _get_params    s   

z_BaseComposition._get_paramsc              	      s   ||v rt | ||| t| |}t|trN|rNtt) t| \}}t| D ]}d|vr>||v r>| 	|||| q*W d    n1 sIw   Y  t
 jdi | | S )N__r   )setattrpopr   
isinstancelistr
   r   zipkeys_replace_estimatorr   
set_params)r   r"   paramsr!   
item_names_r%   r)   r   r   _set_params6   s   

z_BaseComposition._set_paramsc                 C   sL   t t| |}t|D ]\}\}}||kr||f||<  nqt| || d S r   )r0   r   	enumerater-   )r   r"   r%   new_valnew_estimatorsiestimator_namer7   r   r   r   r3   K   s   z#_BaseComposition._replace_estimatorc                 C   sv   t t|t |krtdt|t|| jdd}|r)tdt|dd |D }|r9td|d S )Nz$Names provided are not unique: {0!r}Fr   z:Estimator names conflict with constructor arguments: {0!r}c                 S   s   g | ]}d |v r|qS )r,   r   ).0r%   r   r   r   
<listcomp>^   s    z4_BaseComposition._validate_names.<locals>.<listcomp>z.Estimator names must not contain __: got {0!r})lensetr   formatr0   intersectionr   sorted)r   namesinvalid_namesr   r   r   _validate_namesT   s   z _BaseComposition._validate_names)T)__name__
__module____qualname____doc__r   r   __annotations__r   r   r+   r8   r3   rG   __classcell__r   r   r)   r   r      s   
 
	r   )	metaclassc                   @   s"   e Zd ZdZdd ZdddZdS )_AvailableIfDescriptorav  Implements a conditional property using the descriptor protocol.

    Using this class to create a decorator will raise an ``AttributeError``
    if check(self) returns a falsey value. Note that if check raises an error
    this will also result in hasattr returning false.

    See https://docs.python.org/3/howto/descriptor.html for an explanation of
    descriptors.
    c                 C   s    || _ || _|| _t| | d S r   )fncheckattribute_namer	   )r   rP   rQ   rR   r   r   r   r   p   s   z_AvailableIfDescriptor.__init__Nc                    sb   t dt|j dtj  |d ur#|s tj|}|S tj fdd}|S )NzThis z has no attribute c                     s"    | d s	 j| i |S )Nr   )rQ   rP   )argskwargsattr_errr   r   r   r#      s   z+_AvailableIfDescriptor.__get__.<locals>.out)AttributeErrorreprrH   rR   rQ   r   rP   r   )r   objownerr#   r   rU   r   __get__x   s   
z_AvailableIfDescriptor.__get__r   )rH   rI   rJ   rK   r   r[   r   r   r   r   rO   e   s    
rO   c                    s    fddS )af  An attribute that is available only if check returns a truthy value

    Parameters
    ----------
    check : callable
        When passed the object with the decorated method, this should return
        a truthy value if the attribute is available, and either return False
        or raise an AttributeError if not available.

    Examples
    --------
    >>> from sklearn.utils.metaestimators import available_if
    >>> class HelloIfEven:
    ...    def __init__(self, x):
    ...        self.x = x
    ...
    ...    def _x_is_even(self):
    ...        return self.x % 2 == 0
    ...
    ...    @available_if(_x_is_even)
    ...    def say_hello(self):
    ...        print("Hello")
    ...
    >>> obj = HelloIfEven(1)
    >>> hasattr(obj, "say_hello")
    False
    >>> obj.x = 2
    >>> hasattr(obj, "say_hello")
    True
    >>> obj.say_hello()
    Hello
    c                       t |  | jdS N)rR   )rO   rH   rP   rQ   r   r   <lambda>       zavailable_if.<locals>.<lambda>r   r_   r   r_   r   r      s   !c                       s(   e Zd ZdZ fddZdd Z  ZS )_IffHasAttrDescriptorat  Implements a conditional property using the descriptor protocol.

    Using this class to create a decorator will raise an ``AttributeError``
    if none of the delegates (specified in ``delegate_names``) is an attribute
    of the base object or the first found delegate does not have an attribute
    ``attribute_name``.

    This allows ducktyping of the decorated method based on
    ``delegate.attribute_name``. Here ``delegate`` is the first item in
    ``delegate_names`` for which ``hasattr(object, delegate) is True``.

    See https://docs.python.org/3/howto/descriptor.html for an explanation of
    descriptors.
    c                    s   t  || j| || _d S r   )r   r   _checkdelegate_names)r   rP   rd   rR   r)   r   r   r      s   
z_IffHasAttrDescriptor.__init__c              	   C   s\   t dt d }| jD ]}z	t||}W  n	 ty   Y qw |d u r&dS t|| j dS )Nzrif_delegate_has_method was deprecated in version 1.1 and will be removed in version 1.3. Use if_available instead.FT)warningswarnFutureWarningrd   r   rW   r   rR   )r   rY   delegatedelegate_namer   r   r   rc      s    
z_IffHasAttrDescriptor._check)rH   rI   rJ   rK   r   rc   rM   r   r   r)   r   rb      s    rb   c                    s.   t  tr	t  t  ts f  fddS )ax  Create a decorator for methods that are delegated to a sub-estimator

    This enables ducktyping by hasattr returning True according to the
    sub-estimator.

    .. deprecated:: 1.3
        `if_delegate_has_method` is deprecated in version 1.1 and will be removed in
        version 1.3. Use `available_if` instead.

    Parameters
    ----------
    delegate : str, list of str or tuple of str
        Name of the sub-estimator that can be accessed as an attribute of the
        base object. If a list or a tuple of names are provided, the first
        sub-estimator that is an attribute of the base object will be used.

    c                    r\   r]   )rb   rH   r^   rh   r   r   r`      ra   z(if_delegate_has_method.<locals>.<lambda>)r/   r0   tuplerj   r   rj   r   r      s
   

c                 C   s   t | ddr3t|dstd|jd |jd krtd|du r*|t|| }n|t|| }nt||}|durEt||}||fS d}||fS )	a  Create subset of dataset and properly handle kernels.

    Slice X, y according to indices for cross-validation, but take care of
    precomputed kernel-matrices or pairwise affinities / distances.

    If ``estimator._pairwise is True``, X needs to be square and
    we slice rows and columns. If ``train_indices`` is not None,
    we slice rows using ``indices`` (assumed the test set) and columns
    using ``train_indices``, indicating the training set.

    Labels y will always be indexed only along the first axis.

    Parameters
    ----------
    estimator : object
        Estimator to determine whether we should slice only rows or rows and
        columns.

    X : array-like, sparse matrix or iterable
        Data to be indexed. If ``estimator._pairwise is True``,
        this needs to be a square array-like or sparse matrix.

    y : array-like, sparse matrix or iterable
        Targets to be indexed.

    indices : array of int
        Rows to select from X and y.
        If ``estimator._pairwise is True`` and ``train_indices is None``
        then ``indices`` will also be used to slice columns.

    train_indices : array of int or None, default=None
        If ``estimator._pairwise is True`` and ``train_indices is not None``,
        then ``train_indices`` will be use to slice the columns of X.

    Returns
    -------
    X_subset : array-like, sparse matrix or list
        Indexed data.

    y_subset : array-like, sparse matrix or list
        Indexed targets.

    pairwise)r'   shapezXPrecomputed kernels or affinity matrices have to be passed as arrays or sparse matrices.r      z"X should be a square kernel matrixN)r   r    r   rm   npix_r   )r&   Xyindicestrain_indicesX_subsety_subsetr   r   r   _safe_split   s    ,


rw   r   ) rK   typingr   r   typesr   re   	functoolsr   abcr   r   operatorr   r	   numpyro   
contextlibr
   utilsr   utils._tagsr   baser   __all__r   rO   r   rb   r   rw   r   r   r   r   <module>   s(    N*%,