o
    $6dkD                     @   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 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	rddl&m+Z+ ddlm,Z,m-Z- edddZ.eed df Z/G dd dZ0g dZ1edZ2ej3dkr)eej4e"fdeddddddddddd
de5de5d e5d!e5d"e5d#e5d$eeee6 df d%ee5 d&ee5 d'e5d(eee2 gd)f fd*d+Z7eej4e"fdeddddddddddd
d,ee2 de5de5d e5d!e5d"e5d#e5d$eeee6 df d%ee5 d&ee5 d'e5d(d)fd-d+Z7n}eej4e"fdedddddddddd.	de5de5d e5d!e5d"e5d#e5d$eeee6 df d%ee5 d&ee5 d(eee2 gd)f fd/d+Z7eej4e"fdedddddddddd.	d,ee2 de5de5d e5d!e5d"e5d#e5d$eeee6 df d%ee5 d&ee5 d(d)fd0d+Z7eej4e"fd	dNddddddddddd
d,eee2  de5de5d e5d!e5d"e5d#e5d$eeee6 df d%ee5 d&ee5 d'e5d(eeee2 gd)f d)f fd1d+Z7ed2ed d3e5d(eed ddf fd4d5Z8G d6d dZ9d7ed d$ee d%e5d8e:d(df
d9d:Z;dOd<d=Z<d2ed d>e
d(dfd?d@Z=edfd7ed d$ee
 d8ee: d(edA fdBdCZ>dPdEdFZ?dDddGe:d3e
d(dfdHdIZ@d,ee
 d(e5fdJdKZAd7ed d$ee d(d;fdLdMZBdS )QaX  
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)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< dededd	fddZede
d  ddfddZede
d deddf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      d S N selfr/   r0   r4   r4   nC:\Users\jesus\OneDrive\Desktop\erpjis_fastapi\backend\jisbackend\Lib\site-packages\pydantic/v1/dataclasses.py__init__I   s   zDataclass.__init__clsr    c                 C   r2   r3   r4   r9   r4   r4   r7   __get_validators__L      zDataclass.__get_validators__r"   vc                 C   r2   r3   r4   r9   r=   r4   r4   r7   __validate__P   r<   zDataclass.__validate__)__name__
__module____qualname__r   r   strr   __annotations__r   boolr   r   objectr8   classmethodr;   r?   r4   r4   r4   r7   r#   ;   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_onlyrR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r1   DataclassClassOrWrapperc        
   
      C   r2   r3   r4   rQ   r4   r4   r7   rH   a      rH   _clsc       
         C   r2   r3   r4   )r^   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r4   r4   r7   rH   r   s   	rR   rS   rT   rU   rV   rW   rX   rY   rZ   c        	   	      C   r2   r3   r4   r_   r4   r4   r7   rH      s   c       	   
      C   r2   r3   r4   )
r^   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r4   r4   r7   rH      r]   c       
            sH   t |dtt ddf 	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
    r9   r1   r\   c              
      s   d urnt | o| jd tu ptt| tt| jd k}|r+d}t| }d}n&| jp/d}tjdkrCt	j
|  d}nt	j
|  d}d}	d u rW|n	}t| || |jjdi | j| i |S )	Nr    FrN   )rR   rS   rT   rU   rV   rW   r[   )rR   rS   rT   rU   rV   rW   Tr4   )rK   	__bases__rF   setdirr%   __doc__sysversion_infodataclassesrH   #_add_pydantic_validation_attributesr,   Z__try_update_forward_refs__r@   )r9   Zshould_use_proxy
dc_cls_docdc_clsZdefault_validate_on_initZshould_validate_on_init
rT   rW   rR   r[   rU   rS   Z
the_configrV   rZ   rY   r4   r7   wrap   s:   *

zdataclass.<locals>.wrapN)r   r   r   )r^   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   rl   r4   rk   r7   rH      s
   ,%r9   valuec                 c   s*    | j }z|| _ | V  W || _ d S || _ w r3   )r)   )r9   rm   Zoriginal_run_validationr4   r4   r7   rI      s   rI   c                   @   s   e Zd ZdZded ddfddZded	edefd
dZdedefddZ	dededdfddZ
dedefddZdddZdedd fddZdS )r%   __dataclass__rj   r#   r1   Nc                 C   s   t | d| d S )Nrn   )rF   __setattr__)r6   rj   r4   r4   r7   r8         zDataclassProxy.__init__r/   r0   c                 O   s@   t | jd | j|i |W  d    S 1 sw   Y  d S )NT)rI   rn   r5   r4   r4   r7   __call__   s   $zDataclassProxy.__call__namec                 C   s   t | j|S r3   )getattrrn   )r6   rr   r4   r4   r7   __getattr__      zDataclassProxy.__getattr___DataclassProxy__name_DataclassProxy__valuec                 C   s   t | j||S r3   )setattrrn   )r6   rv   rw   r4   r4   r7   ro     s   zDataclassProxy.__setattr__instancec                 C   s   t || jS r3   )
isinstancern   )r6   ry   r4   r4   r7   __instancecheck__  ru   z DataclassProxy.__instancecheck__c                 C   s   t t| jS r3   )r%   copyrn   r6   r4   r4   r7   __copy__  s   zDataclassProxy.__copy__memoc                 C   s   t t| j|S r3   )r%   r|   deepcopyrn   )r6   r   r4   r4   r7   __deepcopy__
  rp   zDataclassProxy.__deepcopy__)r1   r%   )r@   rA   rB   	__slots__r   r8   r   rq   rC   rt   ro   rE   r{   r~   r   r4   r4   r4   r7   r%      s    
rj   ri   c              	      sZ  | j tdddtdtddf fddt| d	rPz| jjW n ty.   | jY nw tdddtdtddf fd
d}t| d t| d	| ntdddtdtddf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st| dt dS dS 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
    r6   r#   r/   r0   r1   Nc                    s   j tjkr g|R i  fdd| D  d S j tjkrH| D ]\}} j|| q& g|R i  fdd| D  d S  g|R i | d S )Nc                        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                    r   r4   r   r   r}   r4   r7   r   #  r   )extrar   ignoreitemsZallow__dict__
setdefault)r6   r/   r0   r   r=   )rX   rR   r}   r7   handle_extra_init  s   ,,z>_add_pydantic_validation_attributes.<locals>.handle_extra_initr(   c                    sr    j dkr| g|R i | | jjr%|   t| dr%| j|i |  j dkr7| g|R i | d S d S )NZbefore_validationr*   Zafter_validation)Zpost_init_call	__class__r)   r-   hasattrr*   r5   )rX   	post_initr4   r7   new_post_init.  s   


z:_add_pydantic_validation_attributes.<locals>.new_post_initr8   c              	      s    | g|R i | | j jr|   t| drUi }t| j j D ](\}}|jtj	u rJz	|| ||j
< W q" tyI   ||j
|j||j
< Y q"w q"| jdi | d S d S )Nr*   r4   )r   r)   r-   r   	enumerater&   values_field_typerg   _FIELD_INITVARrr   
IndexErrorgetdefaultr*   )r6   r/   r0   Zinitvars_and_valuesif)r   r4   r7   new_init@  s   
z5_add_pydantic_validation_attributes.<locals>.new_initr)   r+   Fr,   r-   r?   r;   ro   )r8   r   r   r   r(   __wrapped__AttributeErrorrx   r   rJ   _dataclass_validate_valuesrG   _validate_dataclass_get_validatorsr,   
__config__Zvalidate_assignmentr'   rW   &_dataclass_validate_assignment_setattr)rj   rX   rY   ri   r   r   r4   )rX   r   rR   r   r7   rh     s2   "

" rh   r    c                 c   s    | j V  d S r3   )r?   r:   r4   r4   r7   r   d  s   r   r=   c                 C   s   t | d> t|| r|  |W  d    S t|ttfr*| | W  d    S t|tr=| di |W  d    S t| jd1 sFw   Y  d S )NT)
class_namer4   )rI   rz   r-   listtupledictr   r@   r>   r4   r4   r7   r   h  s   

	r   r   c           
      C   s   i }t | D ]:}t}d }|jt jur|j}n|jt jur!|j}nt}t|tr.|}d| _	nt
d||d|j}|j|f||j< qt| }t| jf|| j|ddid|}	|d ur`||	_|	S | jpdd|	_|	S )NT)r   default_factoryZ__resolve_forward_refs__F)r   rA   Z__validators__Z__cls_kwargs__r`   r4   )rg   fieldsr   r   MISSINGr   r   rz   r   r.   r   metadatatyperr   r   r   r@   rA   rd   )
rj   rX   ri   Zfield_definitionsfieldr   r   Z
field_infoZ
validatorsmodelr4   r4   r7   rJ   u  s:   
rJ   r6   c                 C   st   t | drd S t | ddrdd | j D }n| j}t| j|| jd\}}}|r+|| j| t| dd d S )Nr+   r.   Fc                 S   s    i | ]\}}t |ts||qS r4   )rz   r   r   r4   r4   r7   r     r   z._dataclass_validate_values.<locals>.<dictcomp>r:   T)	rs   r   r   r   r,   r   updaterF   ro   )r6   Z
input_datad_Zvalidation_errorr4   r4   r7   r     s   
r   rr   c                 C   sl   | j r-t| j}||d  | jj|d }|r-|j|||| jd\}}|r-t	|g| jt
| || d S )N)locr9   )r+   r   r   popr,   Z
__fields__r   validater   r   rF   ro   )r6   rr   rm   r   Zknown_fieldZerror_r4   r4   r7   r     s   
r   c                 C   s2   t | ot| d ot| 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,   rD   )rg   is_dataclassr   rb   r&   
issupersetrs   )r^   r4   r4   r7   rK     s
   

rK   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)rX   rZ   N)r   rH   )rj   rX   r4   r4   r7   rL     s   rL   r3   )r9   r\   r1   r    )r6   r#   r1   N)Crd   r|   rg   re   
contextlibr   	functoolsr   typingr   r   r   r   r   r	   r
   r   r   r   r   Ztyping_extensionsr   Zclass_validatorsr   rX   r   r   r   r   Zerror_wrappersr   errorsr   r   r   r   r   r   mainr   r   utilsr   r   r    r!   r"   r\   r#   __all__rM   rf   r   rE   rF   rH   rI   r%   rC   rh   r   r   rJ   r   r   rK   rL   r4   r4   r4   r7   <module>   s   !4	
	
	
	

	
A*	

V

'"