U
    mf                     @   sv   d Z ddlmZmZmZ G dd deZdd Zdd Zdd
dZ	dd Z
dd Zdd Zdd Zdd Zdd ZdS )zCFunctions that help with dynamically creating decorators for views.    )partialupdate_wrapperwrapsc                       s   e Zd Zd fdd	Z  ZS )classonlymethodNc                    s   |d k	rt dt ||S )Nz=This method is available only on the class, not on instances.)AttributeErrorsuper__get__)selfinstancecls	__class__ ;/tmp/pip-unpacked-wheel-siwebuq3/django/utils/decorators.pyr      s
    zclassonlymethod.__get__)N)__name__
__module____qualname__r   __classcell__r   r   r   r   r      s   r   c                 C   s   |dd }t | | d S )Nc                  _   s   d S Nr   )argskwargsr   r   r   dummy   s    z%_update_method_wrapper.<locals>.dummy)r   )_wrapper	decoratorr   r   r   r   _update_method_wrapper   s    
r   c                    sP   t  dr ddd  n g  fdd} D ]}t|| q2t| |S )z
    Decorate `method` with one or more function decorators. `decorators` can be
    a single decorator or an iterable of decorators.
    __iter__Nc                    s8   t t| t| } D ]}||}q |||S r   )r   r   r   type)r	   r   r   Zbound_methoddec
decoratorsmethodr   r   r   &   s    
z!_multi_decorate.<locals>._wrapper)hasattrr   r   )r    r!   r   r   r   r   r   _multi_decorate   s    

r#    c                    sF    fdd}t  ds"t|  t  dr0 n j}d|j |_|S )z>
    Convert a function decorator into a method decorator
    c                    sp   t | tst | S r"t| s2td| f t| }t|sVtd| |f t |}t| | | S )NzfThe keyword argument `name` must be the name of a method of the decorated class: %s. Got '%s' instead.zACannot decorate '%s' as it isn't a callable attribute of %s (%s).)	
isinstancer   r#   r"   
ValueErrorgetattrcallable	TypeErrorsetattr)objr!   r   r   namer   r   _dec@   s$    



zmethod_decorator.<locals>._decr   r   zmethod_decorator(%s))r"   r   r   r   )r   r-   r.   r+   r   r,   r   method_decorator8   s    

r/   c                 C   s   t | S )a<  
    Like decorator_from_middleware, but return a function
    that accepts the arguments to be passed to the middleware_class.
    Use like::

         cache_page = decorator_from_middleware_with_args(CacheMiddleware)
         # ...

         @cache_page(3600)
         def my_view(request):
             # ...
    make_middleware_decoratormiddleware_classr   r   r   #decorator_from_middleware_with_args\   s    r4   c                 C   s
   t |  S )z
    Given a middleware class (not an instance), return a view decorator. This
    lets you use middleware functionality on a per-view basis. The middleware
    is created with no params passed.
    r0   r2   r   r   r   decorator_from_middlewarel   s    r5   c                    s    fdd}|S )Nc                     s    fdd}|S )Nc                    s*   f t  fdd}|S )Nc              
      s  t dr  }|d k	r |S t drF ||}|d k	rF|S z f||}W nN tk
r } z0t dr |}|d k	r| W Y S  W 5 d }~X Y nX t |drt|jrt drԈ |}t dr fdd}|| nt dr	 |S |S )	Nprocess_requestprocess_viewprocess_exceptionrenderprocess_template_responseprocess_responsec                    s     | S r   )r;   )response)
middlewarerequestr   r   callback   s    zomake_middleware_decorator.<locals>._make_decorator.<locals>._decorator.<locals>._wrapped_view.<locals>.callback)
r"   r6   r7   	Exceptionr8   r(   r9   r:   Zadd_post_render_callbackr;   )r>   r   r   resultr<   er?   r=   	view_func)r>   r   _wrapped_viewz   s8    




 
z]make_middleware_decorator.<locals>._make_decorator.<locals>._decorator.<locals>._wrapped_view)r   )rD   rE   )m_argsm_kwargsr3   rC   r   
_decoratorw   s    #zFmake_middleware_decorator.<locals>._make_decorator.<locals>._decoratorr   )rF   rG   rH   r2   )rF   rG   r   _make_decoratorv   s    )z2make_middleware_decorator.<locals>._make_decoratorr   )r3   rI   r   r2   r   r1   u   s    ,r1   c                 C   s   d| _ d| _| S )zj
    Mark a middleware factory as returning a hybrid middleware supporting both
    types of request.
    TZsync_capableZasync_capablefuncr   r   r   sync_and_async_middleware   s    rM   c                 C   s   d| _ d| _| S )z\
    Mark a middleware factory as returning a sync middleware.
    This is the default.
    TFrJ   rK   r   r   r   sync_only_middleware   s    rN   c                 C   s   d| _ d| _| S )z;Mark a middleware factory as returning an async middleware.FTrJ   rK   r   r   r   async_only_middleware   s    rO   N)r$   )__doc__	functoolsr   r   r   classmethodr   r   r#   r/   r4   r5   r1   rM   rN   rO   r   r   r   r   <module>   s   	

$	0

