3
=^                 @   sl  d Z ddlm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 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j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`)
    )unicode_literalsN)JsonResponse)six)
force_text)ugettext_lazy)	ungettext)status)unicode_to_repr)
ReturnDict
ReturnListc                s   t | tr8 fdd| D }t | tr4t|| jdS |S t | trt fdd| j D }t | trpt|| 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-8app2_gc/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listr   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   2   s    z_get_codes.<locals>.<listcomp>c             S   s   i | ]\}}t ||qS r   )r!   )r   r   r   r   r   r   r   4   s    z_get_codes.<locals>.<dictcomp>)r   r   r   r   r   )detailr   r   r   r!   0   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   :   s    z%_get_full_details.<locals>.<listcomp>c             S   s   i | ]\}}t ||qS r   )r#   )r   r   r   r   r   r   r   <   s    z%_get_full_details.<locals>.<dictcomp>)messager   )r   r   r   r   r   )r"   r   r   r   r#   8   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 t| j| |}||_|S )N)superr   __new__r   )clsstringr   self)	__class__r   r   r&   I   s    zErrorDetail.__new__c                s:   t t| j|}y|o | j|jkS  tk
r4   |S X d S )N)r%   r   __eq__r   AttributeError)r)   otherr)r*   r   r   r+   N   s
    zErrorDetail.__eq__c             C   s   | j | S )N)r+   )r)   r-   r   r   r   __ne__U   s    zErrorDetail.__ne__c             C   s   t dtj| | jf S )NzErrorDetail(string=%r, code=%r))r	   r   	text_typer   )r)   r   r   r   __repr__X   s    zErrorDetail.__repr__c             C   s   t t| S )N)hashstr)r)   r   r   r   __hash__^   s    zErrorDetail.__hash__)N)__name__
__module____qualname____doc__r   r&   r+   r/   r1   r4   __classcell__r   r   )r*   r   r   C   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__k   s
    zAPIException.__init__c             C   s   t j| jS )N)r   r0   r"   )r)   r   r   r   __str__s   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_codesv   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)r5   r6   r7   r8   r   HTTP_500_INTERNAL_SERVER_ERRORstatus_code_r<   r   r=   r>   r?   r@   r   r   r   r   r:   b   s   
r:   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   sJ   |d kr| j }|d kr| j}t|t r:t|t r:|g}t||| _d S )N)r<   r   r   r   r   r   r"   )r)   r"   r   r   r   r   r=      s    zValidationError.__init__)NN)
r5   r6   r7   r   HTTP_400_BAD_REQUESTrB   rC   r<   r   r=   r   r   r   r   rD      s   rD   c               @   s   e Zd ZejZedZdZdS )
ParseErrorzMalformed request.Zparse_errorN)	r5   r6   r7   r   rF   rB   rC   r<   r   r   r   r   r   rG      s   rG   c               @   s   e Zd ZejZedZdZdS )AuthenticationFailedz%Incorrect authentication credentials.Zauthentication_failedN)	r5   r6   r7   r   HTTP_401_UNAUTHORIZEDrB   rC   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 )NotAuthenticatedz-Authentication credentials were not provided.Znot_authenticatedN)	r5   r6   r7   r   rI   rB   rC   r<   r   r   r   r   r   rJ      s   rJ   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)	r5   r6   r7   r   ZHTTP_403_FORBIDDENrB   rC   r<   r   r   r   r   r   rK      s   rK   c               @   s   e Zd ZejZedZdZdS )NotFoundz
Not found.	not_foundN)	r5   r6   r7   r   ZHTTP_404_NOT_FOUNDrB   rC   r<   r   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 )MethodNotAllowedzMethod "{method}" not allowed.method_not_allowedNc                s0   |d krt | jj|d}tt| j|| d S )N)method)r   r<   formatr%   rN   r=   )r)   rP   r"   r   )r*   r   r   r=      s    zMethodNotAllowed.__init__)NN)r5   r6   r7   r   ZHTTP_405_METHOD_NOT_ALLOWEDrB   rC   r<   r   r=   r9   r   r   )r*   r   rN      s   rN   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t| j|| d S )N)available_renderersr%   rR   r=   )r)   r"   r   rT   )r*   r   r   r=      s    zNotAcceptable.__init__)NNN)r5   r6   r7   r   ZHTTP_406_NOT_ACCEPTABLErB   rC   r<   r   r=   r9   r   r   )r*   r   rR      s   rR   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                s0   |d krt | jj|d}tt| j|| d S )N)
media_type)r   r<   rQ   r%   rU   r=   )r)   rW   r"   r   )r*   r   r   r=      s    zUnsupportedMediaType.__init__)NN)r5   r6   r7   r   ZHTTP_415_UNSUPPORTED_MEDIA_TYPErB   rC   r<   r   r=   r9   r   r   )r*   r   rU      s   rU   c                   s8   e Zd ZejZedZdZ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                sn   |d krt | j}|d k	rRtj|}dj|t t| jj|d| jj|d|f}|| _	t
t| j|| d S )N )wait)r   r<   mathceiljoinr   extra_detail_singularrQ   extra_detail_pluralrZ   r%   rX   r=   )r)   rZ   r"   r   )r*   r   r   r=      s    

zThrottled.__init__)NNN)r5   r6   r7   r   ZHTTP_429_TOO_MANY_REQUESTSrB   rC   r<   r^   r_   r   r=   r9   r   r   )r*   r   rX      s   rX   c             O   s   ddi}t |tjdS )z$
    Generic 500 error handler.
    r;   zServer Error (500))r   )r   r   rA   )requestargskwargsr   r   r   r   server_error   s    rc   c             O   s   ddi}t |tjdS )z$
    Generic 400 error handler.
    r;   zBad Request (400))r   )r   r   rF   )r`   	exceptionra   rb   r   r   r   r   bad_request   s    re   )N)(r8   
__future__r   r[   Zdjango.httpr   Zdjango.utilsr   Zdjango.utils.encodingr   Zdjango.utils.translationr   rC   r   Zrest_frameworkr   Zrest_framework.compatr	   Z'rest_framework.utils.serializer_helpersr
   r   r   r!   r#   r0   r   	Exceptionr:   rD   rG   rH   rJ   rK   rL   rN   rR   rU   rX   rc   re   r   r   r   r   <module>   s6   
,

