U
    ڲg                     @   sF  d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZmZ d+d	d
Zdd Zdd ZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd  d eZG d!d" d"eZG d#d$ d$eZG d%d& d&eZd'd( Z d)d* Z!dS ),z
Handled exceptions raised by REST framework.

In addition, Django's built in 403 and 404 exceptions are handled.
(`django.http.Http404` and `django.core.exceptions.PermissionDenied`)
    N)JsonResponse)	force_str)gettext_lazy)ngettextstatus)
ReturnDict
ReturnListc                    s   t | ttfr< fdd| D }t | tr8t|| jdS |S t | trx fdd|  D }t | trtt|| jdS |S t| }t	| d }t
||S )zw
    Descend into a nested data structure, forcing any
    lazy translation strings or strings into `ErrorDetail`.
    c                    s   g | ]}t | qS  _get_error_details.0itemdefault_coder
   =/tmp/pip-unpacked-wheel-11h17kvo/rest_framework/exceptions.py
<listcomp>   s    z&_get_error_details.<locals>.<listcomp>)
serializerc                    s   i | ]\}}|t | qS r
   r   r   keyvaluer   r
   r   
<dictcomp>   s    z&_get_error_details.<locals>.<dictcomp>code)
isinstancelisttupler	   r   dictitemsr   r   getattrErrorDetail)datar   rettextr   r
   r   r   r      s"    




r   c                 C   s:   t | trdd | D S t | tr4dd |  D S | jS )Nc                 S   s   g | ]}t |qS r
   
_get_codesr   r
   r
   r   r   .   s     z_get_codes.<locals>.<listcomp>c                 S   s   i | ]\}}|t |qS r
   r$   r   r
   r
   r   r   0   s      z_get_codes.<locals>.<dictcomp>r   r   r   r   r   detailr
   r
   r   r%   ,   s
    

r%   c                 C   s@   t | trdd | D S t | tr4dd |  D S | | jdS )Nc                 S   s   g | ]}t |qS r
   _get_full_detailsr   r
   r
   r   r   6   s     z%_get_full_details.<locals>.<listcomp>c                 S   s   i | ]\}}|t |qS r
   r)   r   r
   r
   r   r   8   s      z%_get_full_details.<locals>.<dictcomp>)messager   r&   r'   r
   r
   r   r*   4   s    

r*   c                       sJ   e Zd ZdZdZd fdd	Z fddZdd Zd	d
 Zdd Z	  Z
S )r    zA
    A string-like object that can additionally have a code.
    Nc                    s   t  | |}||_|S N)super__new__r   )clsstringr   self	__class__r
   r   r.   E   s    zErrorDetail.__new__c                    sH   t  |}|tkrtS z|o(| j|jkW S  tk
rB   | Y S X d S r,   )r-   __eq__NotImplementedr   AttributeErrorr1   otherresultr2   r
   r   r4   J   s    zErrorDetail.__eq__c                 C   s   |  |}|tkrtS | S r,   )r4   r5   r7   r
   r
   r   __ne__S   s    
zErrorDetail.__ne__c                 C   s   dt | | jf S )NzErrorDetail(string=%r, code=%r))strr   r1   r
   r
   r   __repr__Y   s    zErrorDetail.__repr__c                 C   s   t t| S r,   )hashr;   r<   r
   r
   r   __hash___   s    zErrorDetail.__hash__)N)__name__
__module____qualname____doc__r   r.   r4   r:   r=   r?   __classcell__r
   r
   r2   r   r    ?   s   	r    c                   @   sD   e Zd ZdZejZedZdZ	dddZ
dd Zd	d
 Zdd ZdS )APIExceptionz
    Base class for REST framework exceptions.
    Subclasses should provide `.status_code` and `.default_detail` properties.
    zA server error occurred.errorNc                 C   s,   |d kr| j }|d kr| j}t||| _d S r,   )default_detailr   r   r(   r1   r(   r   r
   r
   r   __init__l   s
    zAPIException.__init__c                 C   s
   t | jS r,   )r;   r(   r<   r
   r
   r   __str__t   s    zAPIException.__str__c                 C   s
   t | jS )ze
        Return only the code part of the error details.

        Eg. {"name": ["required"]}
        )r%   r(   r<   r
   r
   r   	get_codesw   s    zAPIException.get_codesc                 C   s
   t | jS )z
        Return both the message & code parts of the error details.

        Eg. {"name": [{"message": "This field is required.", "code": "required"}]}
        )r*   r(   r<   r
   r
   r   get_full_details   s    zAPIException.get_full_details)NN)r@   rA   rB   rC   r   HTTP_500_INTERNAL_SERVER_ERRORstatus_code_rG   r   rI   rJ   rK   rL   r
   r
   r
   r   rE   c   s   
rE   c                   @   s(   e Zd ZejZedZdZdddZ	dS )ValidationErrorzInvalid input.invalidNc                 C   sZ   |d kr| j }|d kr| j}t|tr0t|}nt|tsJt|tsJ|g}t||| _d S r,   )rG   r   r   r   r   r   r   r(   rH   r
   r
   r   rI      s    

zValidationError.__init__)NN)
r@   rA   rB   r   HTTP_400_BAD_REQUESTrN   rO   rG   r   rI   r
   r
   r
   r   rP      s   rP   c                   @   s   e Zd ZejZedZdZdS )
ParseErrorzMalformed request.Zparse_errorN)	r@   rA   rB   r   rR   rN   rO   rG   r   r
   r
   r
   r   rS      s   rS   c                   @   s   e Zd ZejZedZdZdS )AuthenticationFailedz%Incorrect authentication credentials.Zauthentication_failedN	r@   rA   rB   r   ZHTTP_401_UNAUTHORIZEDrN   rO   rG   r   r
   r
   r
   r   rT      s   rT   c                   @   s   e Zd ZejZedZdZdS )NotAuthenticatedz-Authentication credentials were not provided.Znot_authenticatedNrU   r
   r
   r
   r   rV      s   rV   c                   @   s   e Zd ZejZedZdZdS )PermissionDeniedz2You do not have permission to perform this action.Zpermission_deniedN)	r@   rA   rB   r   ZHTTP_403_FORBIDDENrN   rO   rG   r   r
   r
   r
   r   rW      s   rW   c                   @   s   e Zd ZejZedZdZdS )NotFoundz
Not found.	not_foundN)	r@   rA   rB   r   ZHTTP_404_NOT_FOUNDrN   rO   rG   r   r
   r
   r
   r   rX      s   rX   c                       s0   e Zd ZejZedZdZd fdd	Z	  Z
S )MethodNotAllowedzMethod "{method}" not allowed.method_not_allowedNc                    s,   |d krt | jj|d}t || d S )N)methodr   rG   formatr-   rI   )r1   r\   r(   r   r2   r
   r   rI      s    zMethodNotAllowed.__init__)NN)r@   rA   rB   r   ZHTTP_405_METHOD_NOT_ALLOWEDrN   rO   rG   r   rI   rD   r
   r
   r2   r   rZ      s   rZ   c                       s0   e Zd ZejZedZdZd fdd	Z	  Z
S )NotAcceptablez,Could not satisfy the request Accept header.not_acceptableNc                    s   || _ t || d S r,   )available_renderersr-   rI   )r1   r(   r   ra   r2   r
   r   rI      s    zNotAcceptable.__init__)NNN)r@   rA   rB   r   ZHTTP_406_NOT_ACCEPTABLErN   rO   rG   r   rI   rD   r
   r
   r2   r   r_      s   r_   c                       s0   e Zd ZejZedZdZd fdd	Z	  Z
S )UnsupportedMediaTypez1Unsupported media type "{media_type}" in request.unsupported_media_typeNc                    s,   |d krt | jj|d}t || d S )N)
media_typer]   )r1   rd   r(   r   r2   r
   r   rI      s    zUnsupportedMediaType.__init__)NN)r@   rA   rB   r   ZHTTP_415_UNSUPPORTED_MEDIA_TYPErN   rO   rG   r   rI   rD   r
   r
   r2   r   rb      s   rb   c                       s@   e Zd ZejZedZedZedZ	dZ
d fdd	Z  ZS )		ThrottledzRequest was throttled.z$Expected available in {wait} second.z%Expected available in {wait} seconds.Z	throttledNc              	      sj   |d krt | j}|d k	rRt|}d|t t| jj|d| jj|d|f}|| _	t
 || d S )N )wait)r   rG   mathceiljoinr   extra_detail_singularr^   extra_detail_pluralrg   r-   rI   )r1   rg   r(   r   r2   r
   r   rI      s    

zThrottled.__init__)NNN)r@   rA   rB   r   ZHTTP_429_TOO_MANY_REQUESTSrN   rO   rG   rk   rl   r   rI   rD   r
   r
   r2   r   re      s   re   c                 O   s   ddi}t |tjdS )z$
    Generic 500 error handler.
    rF   zServer Error (500)r   )r   r   rM   )requestargskwargsr!   r
   r
   r   server_error   s     rp   c                 O   s   ddi}t |tjdS )z$
    Generic 400 error handler.
    rF   zBad Request (400)r   )r   r   rR   )rm   	exceptionrn   ro   r!   r
   r
   r   bad_request  s     rr   )N)"rC   rh   Zdjango.httpr   Zdjango.utils.encodingr   Zdjango.utils.translationr   rO   r   Zrest_frameworkr   Z'rest_framework.utils.serializer_helpersr   r	   r   r%   r*   r;   r    	ExceptionrE   rP   rS   rT   rV   rW   rX   rZ   r_   rb   re   rp   rr   r
   r
   r
   r   <module>   s0   
$,

