3
Ah`k                 @   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| j 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	   H/tmp/pip-build-9m32_hle/djangorestframework/rest_framework/exceptions.py
<listcomp>   s    z&_get_error_details.<locals>.<listcomp>)
serializerc                s   i | ]\}}t | |qS r	   )r
   )r   keyvalue)r   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 | j D S | jS )Nc             S   s   g | ]}t |qS r	   )
_get_codes)r   r   r	   r	   r   r   .   s    z_get_codes.<locals>.<listcomp>c             S   s   i | ]\}}t ||qS r	   )r   )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 | j D S | | jdS )Nc             S   s   g | ]}t |qS r	   )_get_full_details)r   r   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	   r   r   8   s    z%_get_full_details.<locals>.<dictcomp>)messager   )r   r   r   r   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  j| |}||_|S )N)super__new__r   )clsstringr   self)	__class__r	   r   r$   E   s    zErrorDetail.__new__c                sB   t  j|}|tkrtS y|o(| j|jkS  tk
r<   |S X d S )N)r#   __eq__NotImplementedr   AttributeError)r'   otherr)r(   r	   r   r)   J   s    zErrorDetail.__eq__c             C   s   | j | S )N)r)   )r'   r,   r	   r	   r   __ne__S   s    zErrorDetail.__ne__c             C   s   dt | | jf S )NzErrorDetail(string=%r, code=%r))strr   )r'   r	   r	   r   __repr__V   s    zErrorDetail.__repr__c             C   s   t t| S )N)hashr/   )r'   r	   r	   r   __hash__\   s    zErrorDetail.__hash__)N)__name__
__module____qualname____doc__r   r$   r)   r.   r0   r2   __classcell__r	   r	   )r(   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 )N)default_detailr   r
   r    )r'   r    r   r	   r	   r   __init__i   s
    zAPIException.__init__c             C   s
   t | jS )N)r/   r    )r'   r	   r	   r   __str__q   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_codest   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)r3   r4   r5   r6   r   HTTP_500_INTERNAL_SERVER_ERRORstatus_code_r:   r   r;   r<   r=   r>   r	   r	   r	   r   r8   `   s   
r8   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   s^   |d kr| j }|d kr| j}t|tr0t|}nt|t rNt|t rN|g}t||| _d S )N)r:   r   r   r   r   r   r
   r    )r'   r    r   r	   r	   r   r;      s    

zValidationError.__init__)NN)
r3   r4   r5   r   HTTP_400_BAD_REQUESTr@   rA   r:   r   r;   r	   r	   r	   r   rB      s   rB   c               @   s   e Zd ZejZedZdZdS )
ParseErrorzMalformed request.Zparse_errorN)	r3   r4   r5   r   rD   r@   rA   r:   r   r	   r	   r	   r   rE      s   rE   c               @   s   e Zd ZejZedZdZdS )AuthenticationFailedz%Incorrect authentication credentials.Zauthentication_failedN)	r3   r4   r5   r   HTTP_401_UNAUTHORIZEDr@   rA   r:   r   r	   r	   r	   r   rF      s   rF   c               @   s   e Zd ZejZedZdZdS )NotAuthenticatedz-Authentication credentials were not provided.Znot_authenticatedN)	r3   r4   r5   r   rG   r@   rA   r:   r   r	   r	   r	   r   rH      s   rH   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)	r3   r4   r5   r   ZHTTP_403_FORBIDDENr@   rA   r:   r   r	   r	   r	   r   rI      s   rI   c               @   s   e Zd ZejZedZdZdS )NotFoundz
Not found.	not_foundN)	r3   r4   r5   r   ZHTTP_404_NOT_FOUNDr@   rA   r:   r   r	   r	   r	   r   rJ      s   rJ   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 j|| d S )N)method)r   r:   formatr#   r;   )r'   rN   r    r   )r(   r	   r   r;      s    zMethodNotAllowed.__init__)NN)r3   r4   r5   r   ZHTTP_405_METHOD_NOT_ALLOWEDr@   rA   r:   r   r;   r7   r	   r	   )r(   r   rL      s   rL   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 j|| d S )N)available_renderersr#   r;   )r'   r    r   rR   )r(   r	   r   r;      s    zNotAcceptable.__init__)NNN)r3   r4   r5   r   ZHTTP_406_NOT_ACCEPTABLEr@   rA   r:   r   r;   r7   r	   r	   )r(   r   rP      s   rP   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 j|| d S )N)
media_type)r   r:   rO   r#   r;   )r'   rU   r    r   )r(   r	   r   r;      s    zUnsupportedMediaType.__init__)NN)r3   r4   r5   r   ZHTTP_415_UNSUPPORTED_MEDIA_TYPEr@   rA   r:   r   r;   r7   r	   r	   )r(   r   rS      s   rS   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j|}dj|t t| jj|d| jj|d|f}|| _	t
 j|| d S )N )wait)r   r:   mathceiljoinr   extra_detail_singularrO   extra_detail_pluralrX   r#   r;   )r'   rX   r    r   )r(   r	   r   r;      s    

zThrottled.__init__)NNN)r3   r4   r5   r   ZHTTP_429_TOO_MANY_REQUESTSr@   rA   r:   r\   r]   r   r;   r7   r	   r	   )r(   r   rV      s   rV   c             O   s   ddi}t |tjdS )z$
    Generic 500 error handler.
    r9   zServer Error (500))r   )r   r   r?   )requestargskwargsr   r	   r	   r   server_error   s    ra   c             O   s   ddi}t |tjdS )z$
    Generic 400 error handler.
    r9   zBad Request (400))r   )r   r   rD   )r^   	exceptionr_   r`   r   r	   r	   r   bad_request   s    rc   )N)"r6   rY   Zdjango.httpr   Zdjango.utils.encodingr   Zdjango.utils.translationr   rA   r   Zrest_frameworkr   Z'rest_framework.utils.serializer_helpersr   r   r
   r   r!   r/   r   	Exceptionr8   rB   rE   rF   rH   rI   rJ   rL   rP   rS   rV   ra   rc   r	   r	   r	   r   <module>   s0   
!,

