B
    ind                 @   sh  U 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 d dlmZ d dlZd dlmZmZ d dlmZ d dlmZmZmZ d d	lmZ d d
lmZm Z m!Z! d dl"m#Z# d dl$m%Z% erddl&m'Z' e Z(e
ee ee f e)d< ee*e+df e,dddZ-eeee ee f  e	eee ee f e+f e	e+ef dddZ.e+ee+ dddZ/dddeddfe+ee ee	e+ef  ee ee,e!f ee ee ee+ e d	ddZ0dde ee
ee ee f  e ddd Z1e+e+e+e+d!d"d#Z2d$e+d%d&d'Z3e	eef e	eef dd(d)d*Z4eeef eeef eeef d+d,d-Z5dS ).    N)is_dataclass)Enum)	TYPE_CHECKINGAnyDictMutableMappingOptionalSetTypeUnioncast)WeakKeyDictionary)DefaultPlaceholderDefaultType)
REF_PREFIX)
BaseConfig	BaseModelcreate_model)	Validator)	FieldInfo
ModelFieldUndefinedType)model_process_schema)lenient_issubclass   )APIRoute_CLONED_TYPES_CACHE)status_codereturnc             C   s2   | d krdS | dkrdS t | }|dk p.|dk S )NT>   1XX5XX2XX4XXdefault3XX   >   0     )int)r   Zcurrent_status_code r)   1/tmp/pip-unpacked-wheel-x7mu4my2/fastapi/utils.pyis_body_allowed_for_status_code$   s    r+   )flat_modelsmodel_name_mapr   c             C   sb   i }xX| D ]P}t ||td\}}}|| || }d|krR|d dd |d< |||< q
W |S )N)r-   Z
ref_prefixdescriptionr   )r   r   updatesplit)r,   r-   ZdefinitionsmodelZm_schemaZm_definitionsZm_nested_modelsZ
model_namer)   r)   r*   get_model_definitions5   s    

r3   )pathr   c             C   s   t td| S )Nz{(.*?)})setrefindall)r4   r)   r)   r*   get_path_param_namesG   s    r8   T)	nametype_class_validatorsr#   requiredmodel_config
field_infoaliasr   c          
   C   sZ   |pi }|pt  }yt| |||||||dS  tk
rT   tjd| ddY nX dS )zB
    Create a new response field. Raises if type_ is invalid.
    )r9   r:   r;   r#   r<   r=   r?   r>   z2Invalid args for response field! Hint: check that aY   is a valid Pydantic field type. If you are using a return type annotation that is not a valid Pydantic field (e.g. Union[Response, dict, None]) you can disable generating the response model from the type annotation with the path operation decorator parameter response_model=None. Read more: https://fastapi.tiangolo.com/tutorial/response-model/N)r   r   RuntimeErrorfastapi
exceptionsZFastAPIError)r9   r:   r;   r#   r<   r=   r>   r?   r)   r)   r*   create_response_fieldK   s     
rC   )cloned_types)fieldrD   r   c               sV   d krt  | j}t|r*t|dr*|j}|}t|trttt |} 	|}|d krt
|j|d}| |< x&|j D ]}t| d|j|j< qzW t| j|d}| j|_| j|_| j|_| j|_| j|_| j|_| j|_| j|_| j|_| jr
 fdd| jD |_| jr"t| j d|_| j|_| j|_| j|_| j|_| j |_ |!  |S )N__pydantic_model__)__base__)rD   )r9   r:   c                s   g | ]}t | d qS ))rD   )create_cloned_field).0Z	sub_field)rD   r)   r*   
<listcomp>   s   z'create_cloned_field.<locals>.<listcomp>)"r   r:   r   hasattrrF   r   r   r   r
   getr   __name__Z
__fields__valuesrH   r9   rC   Z	has_aliasr?   r;   r#   r<   r=   r>   
allow_noneZvalidate_alwaysZ
sub_fieldsZ	key_fieldZ
validatorsZpre_validatorsZpost_validatorsZ
parse_jsonshapeZpopulate_validators)rE   rD   original_typeZuse_typefZ	new_fieldr)   )rD   r*   rH   r   sL    


rH   )r9   r4   methodr   c             C   s:   t jdtdd | | }tdd|}|d |  }|S )Nzrfastapi.utils.generate_operation_id_for_path() was deprecated, it is not used internally, and will be removed soon   )
stacklevelz\W_)warningswarnDeprecationWarningr6   sublower)r9   r4   rS   operation_idr)   r)   r*   generate_operation_id_for_path   s    r]   r   )router   c             C   sB   | j | j }tdd|}| js$t|d t| jd   }|S )Nz\WrV   r   )r9   Zpath_formatr6   rZ   methodsAssertionErrorlistr[   )r^   r\   r)   r)   r*   generate_unique_id   s
    
rb   )	main_dictupdate_dictr   c             C   s   x|  D ]z\}}|| krBt| | trBt|trBt| | | q
|| kr|t| | tr|t|| tr|| | ||  | |< q
|| |< q
W d S )N)items
isinstancedictdeep_dict_updatera   )rc   rd   keyvaluer)   r)   r*   rh      s    
rh   )
first_itemextra_itemsr   c             G   s*   | f| }x|D ]}t |ts|S qW | S )z
    Pass items or `DefaultPlaceholder`s by descending priority.

    The first one to _not_ be a `DefaultPlaceholder` will be returned.

    Otherwise, the first item (a `DefaultPlaceholder`) will be returned.
    )rf   r   )rk   rl   re   itemr)   r)   r*   get_value_or_default   s
    


rn   )6r6   rW   Zdataclassesr   enumr   typingr   r   r   r   r   r	   r
   r   r   weakrefr   rA   Zfastapi.datastructuresr   r   Zfastapi.openapi.constantsr   Zpydanticr   r   r   Zpydantic.class_validatorsr   Zpydantic.fieldsr   r   r   Zpydantic.schemar   Zpydantic.utilsr   Zroutingr   r   __annotations__r(   strboolr+   r3   r8   rC   rH   r]   rb   rh   rn   r)   r)   r)   r*   <module>   sL    ,<!1"

