a
    _gF                     @   s  d Z ddlZddlZddlZddlmZ ddlmZ zddlmZ W n e	yV   Y n0 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 ddlmZ ddlmZ dd	lmZmZmZmZ dd
lm Z  ddl!m"Z" ddl#m$Z$m%Z%m&Z&m'Z' ddl(m)Z)m*Z* ddl+m,Z, erTddl(m-Z- ddl.m/Z/m0Z0 edddZ1eed df Z2G dd dZ3g dZ4edZ5ej6dkrNeej7e$fdeddddddddddd
e8e8e8e8e8e8eeee9 df ee8 ee8 e8eee5 gdf dd d!Z:eej7e$fdeddddddddddd
ee5 e8e8e8e8e8e8eeee9 df ee8 ee8 e8dd"d#d!Z:neej7e$fdedddddddddd$	e8e8e8e8e8e8eeee9 df ee8 ee8 eee5 gdf d%
d&d!Z:eej7e$fdedddddddddd$	ee5 e8e8e8e8e8e8eeee9 df ee8 ee8 dd'd(d!Z:eej7e$fddMddddddddddd
eee5  e8e8e8e8e8e8eeee9 df ee8 ee8 e8eeee5 gdf df d"d)d!Z:eed e8eed ddf d*d+d,Z;G d-d dZ<ed ee e8e=dd.d/d0Z>dd1d2d3d4Z?ed edd5d6d7Z@edfed ee ee= ed8 d9d:d;ZAej6d<krhde=e8d=d>d?ZBnde=e8d=d@d?ZBdddAdBdCZCde=eddDdEdFZDee e8dGdHdIZEed ee d1dJdKdLZFdS )NaX  
The main purpose is to enhance stdlib dataclasses by adding validation
A pydantic dataclass can be generated from scratch or from a stdlib one.

Behind the scene, a pydantic dataclass is just like a regular one on which we attach
a `BaseModel` and magic methods to trigger the validation of the data.
`__init__` and `__post_init__` are hence overridden and have extra logic to be
able to validate input data.

When a pydantic dataclass is generated from scratch, it's just a plain dataclass
with validation triggered at initialization

The tricky part if for stdlib dataclasses that are converted after into pydantic ones e.g.

```py
@dataclasses.dataclass
class M:
    x: int

ValidatedM = pydantic.dataclasses.dataclass(M)
```

We indeed still want to support equality, hashing, repr, ... as if it was the stdlib one!

```py
assert isinstance(ValidatedM(x=1), M)
assert ValidatedM(x=1) == M(x=1)
```

This means we **don't want to create a new dataclass that inherits from it**
The trick is to create a wrapper around `M` that will act as a proxy to trigger
validation without altering default `M` behaviour.
    N)contextmanager)wraps)cached_property)TYPE_CHECKINGAnyCallableClassVarDict	GeneratorOptionalTypeTypeVarUnionoverload)dataclass_transform)gather_all_validators)
BaseConfig
ConfigDictExtra
get_config)ValidationError)DataclassTypeError)Field	FieldInfoRequired	Undefined)create_modelvalidate_model)ClassAttribute)	BaseModel)CallableGeneratorNoArgAnyCallable
DataclassT	Dataclass)boundDataclassProxyc                   @   s   e Zd ZU eeeef  ed< ee ed< eed  ed< ee	 ed< eed  ed< ee	 ed< ee
e  ed< eed gd	f  ed
< ee	 ed< eed	dddZee
d  ddddZee
d eddddZd	S )r#   __dataclass_fields____dataclass_params__).N__post_init____pydantic_run_validation____post_init_post_parse____pydantic_initialised____pydantic_model__N__pydantic_validate_values__#__pydantic_has_field_info_default__argskwargsreturnc                 O   s   d S N selfr0   r1   r4   r4   e/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/pydantic/v1/dataclasses.py__init__P   s    zDataclass.__init__r    clsr2   c                 C   s   d S r3   r4   r:   r4   r4   r7   __get_validators__S   s    zDataclass.__get_validators__r"   r:   vr2   c                 C   s   d S r3   r4   r:   r>   r4   r4   r7   __validate__W   s    zDataclass.__validate__)__name__
__module____qualname__r   r	   strr   __annotations__r   boolr   r   objectr8   classmethodr<   r@   r4   r4   r4   r7   r#   B   s   
)	dataclassset_validation$create_pydantic_model_from_dataclassis_builtin_dataclassmake_dataclass_validator_T   
   )Zfield_specifiersTF.
initrepreqorderunsafe_hashfrozenconfigvalidate_on_init	use_proxykw_onlyDataclassClassOrWrapper)rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r2   c        
   
      C   s   d S r3   r4   rR   r4   r4   r7   rI   h   s    rI   )_clsrS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r2   c       
         C   s   d S r3   r4   )r^   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r4   r4   r7   rI   y   s    	rS   rT   rU   rV   rW   rX   rY   rZ   r[   )
rS   rT   rU   rV   rW   rX   rY   rZ   r[   r2   c        	   	      C   s   d S r3   r4   r_   r4   r4   r7   rI      s    )r^   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r2   c       	   
      C   s   d S r3   r4   )
r^   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r4   r4   r7   rI      s    c       
            sF   t |tt dd 	f
dd}| du r>|S || S )a  
    Like the python standard lib dataclasses but with type validation.
    The result is either a pydantic dataclass that will validate input data
    or a wrapper that will trigger validation around a stdlib dataclass
    to avoid modifying it directly
    r]   r9   c              
      s   d urn2t | o>| jd tu p>tt| tt| jd k}|rVd}t| }d}nL| jp^d}tjdkrt	j
|  d}nt	j
|  d}d}	d u r|n	}t| || |jjf i | j| i |S )Nr    FrO   )rS   rT   rU   rV   rW   rX   r\   )rS   rT   rU   rV   rW   rX   T)rL   	__bases__rG   setdirr%   __doc__sysversion_infodataclassesrI   #_add_pydantic_validation_attributesr,   Z__try_update_forward_refs__rA   )r:   Zshould_use_proxy
dc_cls_docdc_clsZdefault_validate_on_initZshould_validate_on_init
rU   rX   rS   r\   rV   rT   Z
the_configrW   r[   rZ   r4   r7   wrap   s:    *

zdataclass.<locals>.wrapN)r   r   r   )r^   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   rl   r4   rk   r7   rI      s
    *%)r:   valuer2   c                 c   s*   | j }z|| _ | V  W || _ n|| _ 0 d S r3   )r)   )r:   rm   Zoriginal_run_validationr4   r4   r7   rJ      s
    rJ   c                   @   s   e Zd ZdZed ddddZeeeddd	Zeed
ddZ	eeddddZ
eedddZd dddZed dddZdS )r%   __dataclass__r#   N)rj   r2   c                 C   s   t | d| d S )Nrn   )rG   __setattr__)r6   rj   r4   r4   r7   r8      s    zDataclassProxy.__init__r/   c                 O   s@   t | jd  | j|i |W  d    S 1 s20    Y  d S )NT)rJ   rn   r5   r4   r4   r7   __call__  s    zDataclassProxy.__call__)namer2   c                 C   s   t | j|S r3   )getattrrn   )r6   rq   r4   r4   r7   __getattr__  s    zDataclassProxy.__getattr__)_DataclassProxy__name_DataclassProxy__valuer2   c                 C   s   t | j||S r3   )setattrrn   )r6   rt   ru   r4   r4   r7   ro     s    zDataclassProxy.__setattr__)instancer2   c                 C   s   t || jS r3   )
isinstancern   )r6   rw   r4   r4   r7   __instancecheck__  s    z DataclassProxy.__instancecheck__)r2   c                 C   s   t t| jS r3   )r%   copyrn   r6   r4   r4   r7   __copy__  s    zDataclassProxy.__copy__)memor2   c                 C   s   t t| j|S r3   )r%   rz   deepcopyrn   )r6   r}   r4   r4   r7   __deepcopy__  s    zDataclassProxy.__deepcopy__)rA   rB   rC   	__slots__r   r8   r   rp   rD   rs   ro   rF   ry   r|   r   r4   r4   r4   r7   r%      s   )rj   rY   rZ   ri   r2   c                    sD  | j tdttdd fddt| drz| jjW n tyV   | jY n0 tdttdd fdd}t| d	 t| d| n,tdttddfd
d}t| d	| t| dtd| t| dd t| dt	|  | t| dt
 t| dtt t| dtt | jjjr@| jjs@t| dt dS )a  
    We need to replace the right method. If no `__post_init__` has been set in the stdlib dataclass
    it won't even exist (code is generated on the fly by `dataclasses`)
    By default, we run validation after `__init__` or `__post_init__` if defined
    r#   N)r6   r0   r1   r2   c                    s   j tjkr6 g|R i  fdd| D  nlj tjkr| D ]\}} j|| qJ g|R i  fdd| D  n g|R i | d S )Nc                    s    i | ]\}}| j v r||qS r4   r&   .0kr>   r{   r4   r7   
<dictcomp>%      zR_add_pydantic_validation_attributes.<locals>.handle_extra_init.<locals>.<dictcomp>c                    s    i | ]\}}| j v r||qS r4   r   r   r{   r4   r7   r   *  r   )extrar   ignoreitemsZallow__dict__
setdefault)r6   r0   r1   r   r>   )rY   rS   r{   r7   handle_extra_init"  s    **z>_add_pydantic_validation_attributes.<locals>.handle_extra_initr(   c                    sn    j dkr | g|R i | | jjrJ|   t| drJ| j|i |  j dkrj| g|R i | d S )NZbefore_validationr*   Zafter_validation)Zpost_init_call	__class__r)   r-   hasattrr*   r5   )rY   	post_initr4   r7   new_post_init5  s    


z:_add_pydantic_validation_attributes.<locals>.new_post_initr8   c              	      s    | g|R i | | j jr&|   t| dri }t| j j D ]P\}}|jtj	u rDz|| ||j
< W qD ty   ||j
|j||j
< Y qD0 qD| jf i | d S )Nr*   )r   r)   r-   r   	enumerater&   values_field_typerg   _FIELD_INITVARrq   
IndexErrorgetdefaultr*   )r6   r0   r1   Zinitvars_and_valuesif)r   r4   r7   new_initG  s    
z5_add_pydantic_validation_attributes.<locals>.new_initr)   r+   Fr,   r-   r@   r<   ro   )r8   r   r   r   r(   __wrapped__AttributeErrorrv   r   rK   _dataclass_validate_valuesrH   _validate_dataclass_get_validatorsr,   
__config__Zvalidate_assignmentr'   rX   &_dataclass_validate_assignment_setattr)rj   rY   rZ   ri   r   r   r4   )rY   r   rS   r   r7   rh     s.    
rh   r    r9   c                 c   s   | j V  d S r3   )r@   r;   r4   r4   r7   r   k  s    r   r=   c                 C   s   t | d t|| r0|  |W  d    S t|ttfrT| | W  d    S t|trz| f i |W  d    S t| jdW d    n1 s0    Y  d S )NT)
class_name)rJ   rx   r-   listtupledictr   rA   r?   r4   r4   r7   r   o  s    

r   r   )rj   rY   ri   r2   c           
      C   s   i }t | D ]t}t}d }|jt jur.|j}n|jt jurB|j}nt}t|tr\|}d| _	nt
f ||d|j}|j|f||j< qt| }t| jf|| j|ddid|}	|d ur|n| jpd|	_|	S )NT)r   default_factoryZ__resolve_forward_refs__F)r   rB   Z__validators__Z__cls_kwargs__r`   )rg   fieldsr   r   MISSINGr   r   rx   r   r.   r   metadatatyperq   r   r   rA   rB   rd   )
rj   rY   ri   Zfield_definitionsfieldr   r   Z
field_infoZ
validatorsmodelr4   r4   r7   rK   |  s6    
rK   )rP      )objr   r2   c                 C   s   t tt| |d tS r3   )rx   rr   r   r   r   r   r4   r4   r7   _is_field_cached_property  s    r   c                 C   s   dS )NFr4   r   r4   r4   r7   r     s    )r6   r2   c                    s   t  drd S t  ddr4 fdd j D }n fdd j D }t j| jd\}}}|rl| j| t dd d S )	Nr+   r.   Fc                    s*   i | ]"\}}t |tst |s||qS r4   )rx   r   r   r   r{   r4   r7   r     s   z._dataclass_validate_values.<locals>.<dictcomp>c                    s    i | ]\}}t  |s||qS r4   )r   r   r{   r4   r7   r     r   r;   T)	rr   r   r   r   r,   r   updaterG   ro   )r6   Z
input_datad_Zvalidation_errorr4   r{   r7   r     s    

r   )r6   rq   rm   r2   c                 C   sl   | j rZt| j}||d  | jj|d }|rZ|j|||| jd\}}|rZt	|g| jt
| || d S )N)locr:   )r+   r   r   popr,   Z
__fields__r   validater   r   rG   ro   )r6   rq   rm   r   Zknown_fieldZerror_r4   r4   r7   r     s    
r   )r^   r2   c                 C   s2   t | o0t| d o0t| jtt| di S )a  
    Whether a class is a stdlib dataclass
    (useful to discriminated a pydantic dataclass that is actually a wrapper around a stdlib dataclass)

    we check that
    - `_cls` is a dataclass
    - `_cls` is not a processed pydantic dataclass (with a basemodel attached)
    - `_cls` is not a pydantic dataclass inheriting directly from a stdlib dataclass
    e.g.
    ```
    @dataclasses.dataclass
    class A:
        x: int

    @pydantic.dataclasses.dataclass
    class B(A):
        y: int
    ```
    In this case, when we first check `B`, we make an extra check and look at the annotations ('y'),
    which won't be a superset of all the dataclass fields (only the stdlib fields i.e. 'x')
    r,   rE   )rg   is_dataclassr   rb   r&   
issupersetrr   )r^   r4   r4   r7   rL     s
    

rL   )rj   rY   r2   c                 c   s   t t| |ddE dH  dS )z
    Create a pydantic.dataclass from a builtin dataclass to add type validation
    and yield the validators
    It retrieves the parameters of the dataclass and forwards them to the newly created dataclass
    T)rY   r[   N)r   rI   )rj   rY   r4   r4   r7   rM     s    rM   )N)Grd   rz   rg   re   
contextlibr   	functoolsr   r   ImportErrortypingr   r   r   r   r	   r
   r   r   r   r   r   Ztyping_extensionsr   Zpydantic.v1.class_validatorsr   Zpydantic.v1.configr   r   r   r   Zpydantic.v1.error_wrappersr   Zpydantic.v1.errorsr   Zpydantic.v1.fieldsr   r   r   r   Zpydantic.v1.mainr   r   Zpydantic.v1.utilsr   r   Zpydantic.v1.typingr    r!   r"   r]   r#   __all__rN   rf   r   rF   rG   rI   rJ   r%   rD   rh   r   r   rK   r   r   r   rL   rM   r4   r4   r4   r7   <module>   sd  !4 
A&	V'