o
    0iUb                     @   sZ  U d dl Zd dlZd dlZd dl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mZmZmZmZmZmZmZmZmZmZmZ z
d dlmZmZ W n) eyx   z
d dlmZmZ W n eyu   e ddi Ze ddi ZY nw Y nw d	d
l!m"Z"m#Z#m$Z$ eegdf Z%edZ&ede'e(ef dZ)e* 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,	dOdddeee&  de-deee& eee& gee& f f fddZ,de e) de'ddfddZ.ede e) defddZ/de e) de'e(ef fddZ0eedddddfd ee1e% 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*Z2d e%fd+d,Z3d-e(d.ed/eddfd0d1Z4d-e(d.ed2e5ed3f ddfd4d5Z6d-e(d.ed2e5ed3f ddfd6d7Z7d-e(d.ed2e5ed3f ddfd8d9Z8d-e(d.ed2e5ed3f ddfd:d;Z9d-e(d.ed2e5ed3f ddfd<d=Z:d-e(d.ed2e5ed3f ddfd>d?Z;d-e(d.ed2e5ed3f ddfd@dAZ<d-e(d.ed/e ddfdBdCZ=dDede%fdEdFZ>d ede-fdGdHZ?dIede-fdJdKZ@ee6ee7e1e8e'e9e5e:eAe;ejBjCe<iZDe'eee(ee5ed3f gdf f eEdL< ejFdMkr'e6eDejG< g dNZHdS )P    N)_MISSING_TYPEMISSINGFieldfieldfieldsmake_dataclass)	lru_cachewraps)	AnnotatedAnyCallable
ForwardRefLiteralOptionalTypeTypeVarUnionget_args
get_originoverload)NotRequiredRequiredr    r      )#StrictDataclassClassValidationErrorStrictDataclassDefinitionError#StrictDataclassFieldValidationErrorTTypedDictType)boundclsreturnc                 C      d S Nr   r    r   r   U/home/kim/smarthome/.venv/lib/python3.10/site-packages/huggingface_hub/dataclasses.pystrict2      r&   Faccept_kwargsr)   c                 C   r"   r#   r   r(   r   r   r%   r&   6   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                    sB  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}| _t  dsdtdd fdd}	|	 _ jtdtf fdd}
 jjdu r|
 _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rt j"ddst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                    s  dd t D   fdd| D }t|dkr(tdj dt| dt D ]7}|j|v r>t| |j||j  q,|jturLt| |j|j q,|j	tur[t| |j|	  q,t
d	|j d
i }| D ]\}}| vrv|||< qj| jdi | 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   r9   kvZdataclass_fieldsr   r%   
<dictcomp>   s    z:strict.<locals>.wrap.<locals>.__init__.<locals>.<dictcomp>r   zWhen `accept_kwargs=True`, z, accepts only keyword arguments, but found `z` positional args.zMissing required field - ''r   )r   itemslenr3   __name__r.   setattrdefaultr   default_factoryr4   __post_init__)r-   argsr8   Zstandard_kwargsr:   additional_kwargsr.   r/   r$   r?   r%   __init__   s,   



z&strict.<locals>.wrap.<locals>.__init__rH   c                 [   s"   |  D ]
\}}t| || qdS )z2Default __post_init__ to accept additional kwargs.N)rB   rE   )r-   r8   r.   r/   r   r   r%   rH      s   z+strict.<locals>.wrap.<locals>.__post_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*   r<   r$   r   r%   
<listcomp>   s
    
z:strict.<locals>.wrap.<locals>.__repr__.<locals>.<listcomp>z, ))__dict__rB   join)r-   Zstandard_reprrJ   Zadditional_repr)r    original_reprr   r%   __repr__   s   

 z&strict.<locals>.wrap.<locals>.__repr__TZ	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+   r0   N)__class_validators__r3   r4   r   rD   )r-   r+   r5   r$   r   r%   validate   s   
z&strict.<locals>.wrap.<locals>.validaterV   "__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)rV   )r-   rI   r8   )r    initial_initr   r%   init_with_validate  s   z0strict.<locals>.wrap.<locals>.init_with_validaterK   )r!   N)$hasattrr   rD   r   append_create_type_validatormetadatar2   
isinstancelist_is_validatorr.   extendr1   __setattr__r   strrK   r	   rH   rT   __dataclass_params__reprdir
startswithgetattrcallablerC   inspect	signature
parametersrU   r   rW   rV   rE   )r    Zfield_validatorsr:   
validatorsZcustom_validatorr+   r7   Zoriginal_initrK   rH   rT   Zclass_validatorsr.   methodrV   rY   r(   )r    rX   rS   r6   r%   wrapt   s~   


"



zstrict.<locals>.wrapN)r   r   )r    r)   ro   r   r(   r%   r&   :   s   : ,schemadatac                 C   s   t | }|di | dS )a  
    Validate that a dictionary conforms to the types defined in a TypedDict class.

    Under the hood, the typed dict is converted to a strict dataclass and validated using the `@strict` decorator.

    Args:
        schema (`type[TypedDictType]`):
            The TypedDict class defining the expected structure and types.
        data (`dict`):
            The dictionary to validate.

    Raises:
        `StrictDataclassFieldValidationError`:
            If any field in the dictionary does not conform to the expected type.

    Example:
    ```py
    >>> from typing import Annotated, TypedDict
    >>> from huggingface_hub.dataclasses import validate_typed_dict

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

    >>> class User(TypedDict):
    ...     name: str
    ...     age: Annotated[int, positive_int]

    >>> # Valid data
    >>> validate_typed_dict(User, {"name": "John", "age": 30})

    >>> # Invalid type for age
    >>> validate_typed_dict(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 for age
    >>> validate_typed_dict(User, {"name": "John", "age": -1})
    huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age':
        ValueError: Value must be positive, got -1
    ```
    Nr   )!_build_strict_cls_from_typed_dict)rp   rq   Z
strict_clsr   r   r%   validate_typed_dict"  s   ,rs   c              
   C   s   t | }t| ddsA| D ]2\}}t|}|tu r6t|^}}t|s(t| }tt|gt	|  ||< qt|s@t| ||< qg }| D ],\}}t|tu rht|^}}|
||ttd|d idf qG|
||ttdf qGtt| j|S )N	__total__Tr+   r   )rF   r]   )rF   )_get_typed_dict_annotationsrh   rB   r   r
   r   _is_required_or_notrequiredr   tupler_   r[   r   _TYPED_DICT_DEFAULT_VALUEr&   r   rD   )rp   Z
type_hintskeyr/   originbasemetar   r   r   r%   rr   T  s&   "rr   c                 C   sD   z
ddl }|| W S  ty!   dd | jdi  D  Y S w )z0Extract type annotations from a TypedDict class.r   Nc                 S   s&   i | ]\}}||d ur|nt d qS r#   )type)r9   r.   r/   r   r   r%   r@   {  s    z/_get_typed_dict_annotations.<locals>.<dictcomp>__annotations__)annotationlibget_annotationsImportErrorrQ   r2   rB   )rp   r   r   r   r%   ru   s  s   
ru   Tr+   rF   rG   initre   hashcomparer]   r8   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+   rF   rG   r   re   r   r   r]   r   )r^   r_   r   )	r+   rF   rG   r   re   r   r   r]   r8   r   r   r%   validated_field  s    
r   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.
    TNrF   rG   r   re   r   r   r]   r8   c              
      s    t  f| ||||||d|S )Nr   )r   )rF   rG   r   re   r   r   r]   r8   r+   r   r%   _inner  s   
	z"as_validated_field.<locals>._inner)r   r   r   r   r   boolr   dict)r+   r   r   r   r%   as_validated_field  s2   

r   r.   r/   expected_typec                 C   s   t |}t|}|tu rdS t| }r|| || dS t|tr*t| || dS t|ts4t|t	r6dS |t
u rP|tu rFtd|  dt| ||d  dS |tu rd|tu rZdS t| ||d  dS td|  d| )z.Validate that 'value' matches 'expected_type'.NField 'z' is required but missing.r   zUnsupported type for field 'r,   )r   r   r   _BASIC_TYPE_VALIDATORSr2   r^   r}   _validate_simple_typer   rc   r   rx   r4   type_validatorr   )r.   r/   r   rz   rI   r+   r   r   r%   r     s&   
r   rI   .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.Nr   z' with value z doesn't match any type in z
. Errors: z; )r   r4   r[   rc   re   rR   )r.   r/   rI   errorstr5   r   r   r%   _validate_union  s   $r   c                 C   s&   ||vrt d|  d| d| dS )zValidate Literal type.r   z' expected one of , got N)r4   )r.   r/   rI   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 'rA   N)r^   r_   r4   r}   rD   	enumerater   r.   r/   rI   Z	item_typeiitemr5   r   r   r%   _validate_list  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 'rA   N)r^   r   r4   r}   rD   rB   r   )r.   r/   rI   Zkey_type
value_typer=   r>   r5   r   r   r%   _validate_dict  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 'rA   Nz' expected a tuple of length r   )
r^   rw   r4   r}   rD   rC   Ellipsisr   r   zip)r.   r/   rI   r   r   r5   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 'rA   N)r^   setr4   r}   rD   r   r   r   r   r   r%   _validate_set2  s   
r   c                 C   s   t |tjjstd|  dt|j |sdS |d }t|D ]*\}}zt|  d| d|| W q  tyJ } ztd| d|  d	|d}~ww dS )
z&Validate Sequence or Sequence[T] type.r   z' expected a Sequence, got Nr   r   r   r   z in sequence 'rA   )	r^   collectionsabcSequencer4   r}   rD   r   r   r   r   r   r%   _validate_sequence@  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: rP   N)r^   r4   rD   r}   re   )r.   r/   r   r   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%   r\   Z  s   r\   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)ri   rj   rk   r_   rl   valuesrC   kind	ParameterPOSITIONAL_OR_KEYWORDPOSITIONAL_ONLYVAR_POSITIONALrF   empty)r+   rk   rl   Z	parameterr   r   r%   r`   d  s"   
r`   	type_hintc                 C   s   | t tfv pt| t tfv S )z2Helper to check if a type is Required/NotRequired.)r   r   r   )r   r   r   r%   rv     s   rv   r   )   
   )r&   rs   r   Validator_Tr   r   r   r#   )Icollections.abcr   rj   systypesdataclassesr   r   r   r   r   r   	functoolsr   r	   typingr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Ztyping_extensionsr}   r   r   r   r   r   r   r   rc   r   objectrx   r&   r   rs   rr   ru   r_   r   r   r   rw   r   r   r   r   r   r   r   r   r\   r`   rv   r   r   r   r   r~   version_info	UnionType__all__r   r   r   r%   <module>   s   
  8	,
 
 i2
	

+""""""""
*

