o
    RhHC                     @   s  d dl Z d dlmZmZmZmZmZ d dlmZ d dl	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZmZ ee
gdf ZedZedee d	ee fd
dZeddded	eee gee f fddZ	d:dddeee  ded	eee eee gee f f fddZeedddddfdeee ef dee
ef deeg e
f ef dededee dedee de
d	e
fddZdefddZ de!d e
d!e
d	dfd"d#Z"de!d e
d$ee
d%f d	dfd&d'Z#de!d e
d$ee
d%f d	dfd(d)Z$de!d e
d$ee
d%f d	dfd*d+Z%de!d e
d$ee
d%f d	dfd,d-Z&de!d e
d$ee
d%f d	dfd.d/Z'de!d e
d$ee
d%f d	dfd0d1Z(de!d e
d!e)d	dfd2d3Z*d4ed	efd5d6Z+de
d	efd7d8Z,ee#ee$e-e%e.e&e/e'e0e(iZ1g d9Z2dS );    N)_MISSING_TYPEMISSINGFieldfieldfields)wraps)AnyCallableDictListLiteralOptionalTupleTypeTypeVarUnionget_args
get_originoverload   )#StrictDataclassClassValidationErrorStrictDataclassDefinitionError#StrictDataclassFieldValidationErrorTclsreturnc                 C      d S N r   r   r   ]/home/air/sanwanet/backup_V2/venv/lib/python3.10/site-packages/huggingface_hub/dataclasses.pystrict       r!   Faccept_kwargsr$   c                 C   r   r   r   r#   r   r   r    r!   $   r"   c                   s2   dt t dt t f fdd}| dur|| S |S )a  
    Decorator to add strict validation to a dataclass.

    This decorator must be used on top of `@dataclass` to ensure IDEs and static typing tools
    recognize the class as a dataclass.

    Can be used with or without arguments:
    - `@strict`
    - `@strict(accept_kwargs=True)`

    Args:
        cls:
            The class to convert to a strict dataclass.
        accept_kwargs (`bool`, *optional*):
            If True, allows arbitrary keyword arguments in `__init__`. Defaults to False.

    Returns:
        The enhanced dataclass with strict validation on field assignment.

    Example:
    ```py
    >>> from dataclasses import dataclass
    >>> from huggingface_hub.dataclasses import as_validated_field, strict, validated_field

    >>> @as_validated_field
    >>> def positive_int(value: int):
    ...     if not value >= 0:
    ...         raise ValueError(f"Value must be positive, got {value}")

    >>> @strict(accept_kwargs=True)
    ... @dataclass
    ... class User:
    ...     name: str
    ...     age: int = positive_int(default=10)

    # Initialize
    >>> User(name="John")
    User(name='John', age=10)

    # Extra kwargs are accepted
    >>> User(name="John", age=30, lastname="Doe")
    User(name='John', age=30, *lastname='Doe')

    # Invalid type => raises
    >>> User(name="John", age="30")
    huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age':
        TypeError: Field 'age' expected int, got str (value: '30')

    # Invalid value => raises
    >>> User(name="John", age=-1)
    huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age':
        ValueError: Value must be positive, got -1
    ```
    r   r   c                    s  t  dstd j di }t D ]<}g }|t| |jd}|d urKt|t	s1|g}|D ]}t
|sEtd|j d| dq3|| |||j< q| _ jdtd	td
tdd ffdd}| _r jtdtdd f fdd}| _ jtdtf fdd}| _g }	t D ]-}
|
dsqt |
}t|sqtt|jdkrtd j d|
 d|	| q|	 _dtdd f fdd}d|_t  drt jddstd j d| _ jtd! fdd}t  d |  S )"N__dataclass_fields__zClass 'z.' must be a dataclass before applying @strict.	validatorzInvalid validator for field '': z.. Must be a callable taking a single argument.selfnamevaluer   c                    sZ   | j |g D ]}z|| W q ttfy$ } zt||d|d}~ww  | || dS )z1Custom __setattr__ method for strict dataclasses.)r   causeN)__validators__get
ValueError	TypeErrorr   )r(   r)   r*   r&   e)original_setattrr   r    __strict_setattr__}   s   z0strict.<locals>.wrap.<locals>.__strict_setattr__kwargsc                    sb   dd t D   fdd| D }| fi | | D ]\}}| vr.| || q d S )Nc                 S   s   h | ]}|j qS r   )r)   ).0fr   r   r    	<setcomp>   s    z9strict.<locals>.wrap.<locals>.__init__.<locals>.<setcomp>c                    s   i | ]\}}| v r||qS r   r   r4   kvdataclass_fieldsr   r    
<dictcomp>   s    z:strict.<locals>.wrap.<locals>.__init__.<locals>.<dictcomp>)r   items__setattr__)r(   r3   standard_kwargsr)   r*   )r   original_initr:   r    __init__   s   z&strict.<locals>.wrap.<locals>.__init__c                    sJ   | } fdd| j  D }d|}|r#|d d  d| dS |S )Nc                    s*   g | ]\}}| j vrd | d|qS )*=)r%   r7   r   r   r    
<listcomp>   s
    
z:strict.<locals>.wrap.<locals>.__repr__.<locals>.<listcomp>z, ))__dict__r=   join)r(   standard_repradditional_kwargsadditional_repr)r   original_reprr   r    __repr__   s   

 z&strict.<locals>.wrap.<locals>.__repr__	validate_r   z' has a class validator 'z' that takes more than one argument. Class validators must take only 'self' as an argument. Methods starting with 'validate_' are considered to be class validators.c                    sH    j D ]}z||  W q ttfy! } zt|j|d|d}~ww dS )z%Run class validators on the instance.)r&   r+   N)__class_validators__r.   r/   r   __name__)r(   r&   r0   r   r   r    validate   s   
z&strict.<locals>.wrap.<locals>.validateTrQ   "__is_defined_by_strict_decorator__Fz' already implements a method called 'validate'. This method name is reserved when using the @strict decorator on a dataclass. If you want to keep your own method, please rename it.c                    s$   | g|R i |   |  dS )z*Run class validators after initialization.N)rQ   )r(   argsr3   )r   initial_initr   r    init_with_validate   s   z0strict.<locals>.wrap.<locals>.init_with_validaterA   )r   N)!hasattrr   rP   r   append_create_type_validatormetadatar-   
isinstancelist_is_validatorr)   extendr,   r>   r   strrA   r   rM   dir
startswithgetattrcallableleninspect	signature
parametersrO   r   rR   rQ   setattr)r   field_validatorsr5   
validatorscustom_validatorr&   r2   rA   rM   class_validatorsr)   methodrQ   rU   r#   )r   rT   r@   rL   r1   r    wrapb   sv   






zstrict.<locals>.wrapN)r   r   )r   r$   rm   r   r#   r    r!   (   s   : Tr&   defaultdefault_factoryinitreprhashcomparerY   r3   c           	   
   K   sB   t | ts| g} |du ri }| |d< td|||||||d|S )a<  
    Create a dataclass field with a custom validator.

    Useful to apply several checks to a field. If only applying one rule, check out the [`as_validated_field`] decorator.

    Args:
        validator (`Callable` or `List[Callable]`):
            A method that takes a value as input and raises ValueError/TypeError if the value is invalid.
            Can be a list of validators to apply multiple checks.
        **kwargs:
            Additional arguments to pass to `dataclasses.field()`.

    Returns:
        A field with the validator attached in metadata
    Nr&   rn   ro   rp   rq   rr   rs   rY   r   )rZ   r[   r   )	r&   rn   ro   rp   rq   rr   rs   rY   r3   r   r   r    validated_field   s    
ru   c                    sb   t t dddddfdtttf dttg tf tf dtdtdtt dtd	tt d
tf fdd}|S )a  
    Decorates a validator function as a [`validated_field`] (i.e. a dataclass field with a custom validator).

    Args:
        validator (`Callable`):
            A method that takes a value as input and raises ValueError/TypeError if the value is invalid.
    TNrn   ro   rp   rq   rr   rs   rY   r3   c              
      s    t  f| ||||||d|S )Nrt   )ru   )rn   ro   rp   rq   rr   rs   rY   r3   r&   r   r    _inner$  s   
	z"as_validated_field.<locals>._inner)r   r   r   r   r	   boolr   r
   )r&   rw   r   rv   r    as_validated_field  s2   

ry   r)   r*   expected_typec                 C   sh   t |}t|}|tu rdS t| }r|| || dS t|tr*t| || dS td|  d| )z.Validate that 'value' matches 'expected_type'.NzUnsupported type for field 'r'   )	r   r   r   _BASIC_TYPE_VALIDATORSr-   rZ   type_validate_simple_typer/   )r)   r*   rz   originrS   r&   r   r   r    type_validator=  s   
r   rS   .c                 C   s~   g }|D ]%}z
t | || W  dS  ty) } z|t| W Y d}~qd}~ww td|  dt| d| dd| )z8Validate that value matches one of the types in a Union.NField 'z' with value z doesn't match any type in z
. Errors: z; )r   r/   rW   r^   rq   rH   )r)   r*   rS   errorstr0   r   r   r    _validate_unionL  s   $r   c                 C   s&   ||vrt d|  d| d| dS )zValidate Literal type.r   z' expected one of , got N)r/   )r)   r*   rS   r   r   r    _validate_literal[  s   r   c                 C   s   t |tstd|  dt|j |d }t|D ]*\}}zt|  d| d|| W q tyD } ztd| d|  d|d	}~ww d	S )
zValidate List[T] type.r   z' expected a list, got r   []Invalid item at index z
 in list ''N)rZ   r[   r/   r|   rP   	enumerater   r)   r*   rS   	item_typeiitemr0   r   r   r    _validate_lista  s   
r   c                 C   s   t |tstd|  dt|j |\}}| D ]0\}}zt|  d|| t|  d|d|| W q tyJ } z	td|  d|d}~ww dS )	zValidate Dict[K, V] type.r   z' expected a dict, got z.keyr   r   zInvalid key or value in dict 'r   N)rZ   dictr/   r|   rP   r=   r   )r)   r*   rS   key_type
value_typer8   r9   r0   r   r   r    _validate_dicto  s   
r   c                 C   s@  t |tstd|  dt|j t|dkrQ|d tu rQt|D ],\}}zt|  d| d||d  W q" tyN } ztd| d	|  d
|d}~ww dS t|t|krjtd|  dt| dt| tt	||D ],\}\}}zt|  d| d|| W qq ty } ztd| d	|  d
|d}~ww dS )zValidate Tuple type.r   z' expected a tuple, got    r   r   r   r   r   z in tuple 'r   Nz' expected a tuple of length r   )
rZ   tupler/   r|   rP   rc   Ellipsisr   r   zip)r)   r*   rS   r   r   r0   expectedr   r   r    _validate_tuple~  s*   
 "r   c                 C   s   t |tstd|  dt|j |d }t|D ]$\}}zt|  d|| W q ty> } z	td|  d|d}~ww dS )zValidate Set[T] type.r   z' expected a set, got r   z itemzInvalid item in set 'r   N)rZ   setr/   r|   rP   r   r   r   r   r   r    _validate_set  s   
r   c              
   C   s<   t ||std|  d|j dt|j dt| d	dS )z&Validate simple type (int, str, etc.).r   z' expected r   z	 (value: rF   N)rZ   r/   rP   r|   rq   )r)   r*   rz   r   r   r    r}     s
   
(r}   r   c                    s   dt ddf fdd}|S )z-Create a type validator function for a field.r*   r   Nc                    s   t  j|  j d S r   )r   r)   r|   )r*   r   r   r    r&     s   z)_create_type_validator.<locals>.validator)r   )r   r&   r   r   r    rX     s   rX   c                 C   s   t | sdS t| }t|j }t|dkrdS |d jtjj	tjj
tjjfvr,dS |dd D ]}|jtjjkr> dS q2dS )zCheck if a function is a validator.

    A validator is a Callable that can be called with a single positional argument.
    The validator can have more arguments with default values.

    Basically, returns True if `validator(value)` is possible.
    Fr   r   NT)rb   rd   re   r[   rf   valuesrc   kind	ParameterPOSITIONAL_OR_KEYWORDPOSITIONAL_ONLYVAR_POSITIONALrn   empty)r&   re   rf   	parameterr   r   r    r\     s"   
r\   )r!   ru   Validator_Tr   r   r   r   )3rd   dataclassesr   r   r   r   r   	functoolsr   typingr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   rx   ru   ry   r^   r   r   r   r   r   r   r   r|   r}   rX   r\   r[   r   r   r   r{   __all__r   r   r   r    <module>   s    <,
 
 K
	

+"""""""

