U
    [+d,#                     @   s   d dl mZ d dlmZ dZG dd deZG dd deZG dd	 d	ZG d
d deZ	G dd deZ
G dd de	ZdddZdS )    )contextmanager)copy)z'django.template.context_processors.csrfc                   @   s   e Zd ZdZdS )ContextPopExceptionz,pop() has been called more times than push()N)__name__
__module____qualname____doc__ r	   r	   ;/tmp/pip-unpacked-wheel-n7e__lmp/django/template/context.pyr      s   r   c                       s,   e Zd Z fddZdd Zdd Z  ZS )ContextDictc                    s$   t  j|| |j|  || _d S N)super__init__dictsappendcontext)selfr   argskwargs	__class__r	   r
   r      s    zContextDict.__init__c                 C   s   | S r   r	   r   r	   r	   r
   	__enter__   s    zContextDict.__enter__c                 O   s   | j   d S r   )r   pop)r   r   r   r	   r	   r
   __exit__   s    zContextDict.__exit__)r   r   r   r   r   r   __classcell__r	   r	   r   r
   r      s   r   c                       s   e Zd Zd$ddZd%ddZ fddZdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zd&ddZd'ddZd(ddZd d! Zd"d# Z  ZS ))BaseContextNc                 C   s   |  | d S r   )_reset_dicts)r   dict_r	   r	   r
   r      s    zBaseContext.__init__c                 C   s,   ddd d}|g| _ |d k	r(| j | d S )NTF)TrueFalseNone)r   r   )r   valuebuiltinsr	   r	   r
   r      s    zBaseContext._reset_dictsc                    s   t t }| jd d  |_|S r   )r   r   r   r   Z	duplicater   r	   r
   __copy__%   s    
zBaseContext.__copy__c                 C   s
   t | jS r   )reprr   r   r	   r	   r
   __repr__*   s    zBaseContext.__repr__c                 C   s
   t | jS r   reversedr   r   r	   r	   r
   __iter__-   s    zBaseContext.__iter__c                 O   sF   g }|D ],}t |tr*||jdd  7 }q|| qt| f||S N   )
isinstancer   r   r   r   )r   r   r   r   dr	   r	   r
   push0   s    
zBaseContext.pushc                 C   s   t | jdkrt| j S r+   )lenr   r   r   r   r	   r	   r
   r   9   s    zBaseContext.popc                 C   s   || j d |< dS )z%Set a variable in the current contextNr   )r   keyr"   r	   r	   r
   __setitem__>   s    zBaseContext.__setitem__c                 C   s6   | j d }t| j D ]}||kr|} q*q|||< dS )z|
        Set a variable in one of the higher contexts if it exists there,
        otherwise in the current context.
        r1   N)r   r)   )r   r3   r"   r   r.   r	   r	   r
   
set_upwardB   s    
zBaseContext.set_upwardc                 C   s0   t | jD ]}||kr
||   S q
t|dS )zHGet a variable's value, starting at the current context and going upwardN)r)   r   KeyError)r   r3   r.   r	   r	   r
   __getitem__N   s    zBaseContext.__getitem__c                 C   s   | j d |= dS )z*Delete a variable from the current contextr1   Nr2   r   r3   r	   r	   r
   __delitem__U   s    zBaseContext.__delitem__c                    s   t  fdd| jD S )Nc                 3   s   | ]} |kV  qd S r   r	   ).0r.   r3   r	   r
   	<genexpr>Z   s     z+BaseContext.__contains__.<locals>.<genexpr>)anyr   r8   r	   r;   r
   __contains__Y   s    zBaseContext.__contains__c                 C   s(   t | jD ]}||kr
||   S q
|S r   r(   )r   r3   	otherwiser.   r	   r	   r
   get\   s    zBaseContext.getc                 C   s,   z
| | W S  t k
r&   || |< Y nX |S r   )r6   )r   r3   defaultr	   r	   r
   
setdefaultb   s
    
zBaseContext.setdefaultc                 C   s   t | }|| |S )z{
        Return a new context with the same properties, but with only the
        values given in 'values' stored.
        )r   r   r   valuesZnew_contextr	   r	   r
   newi   s    
zBaseContext.newc                 C   s   i }| j D ]}|| q
|S )z6
        Return self.dicts as one dictionary.
        )r   update)r   Zflatr.   r	   r	   r
   flattenr   s    
zBaseContext.flattenc                 C   s   t |tstS |  | kS )zN
        Compare two contexts by comparing theirs 'dicts' attributes.
        )r-   r   NotImplementedrG   )r   otherr	   r	   r
   __eq__{   s    
zBaseContext.__eq__)N)N)N)N)N)r   r   r   r   r   r%   r'   r*   r/   r   r4   r5   r7   r9   r>   r@   rB   rE   rG   rJ   r   r	   r	   r   r
   r      s"   

	


		r   c                       sB   e Zd ZdZd fdd	Zedd Z fdd	Zd
d Z  Z	S )Contextz&A stack container for variable contextNTc                    s6   || _ || _|| _d| _t | _d | _t | d S )Nunknown)	
autoescapeuse_l10nuse_tzZtemplate_nameRenderContextrender_contexttemplater   r   )r   r   rM   rN   rO   r   r	   r
   r      s    zContext.__init__c                 c   s0   | j d k	rtd|| _ z
d V  W 5 d | _ X d S Nz&Context is already bound to a template)rR   RuntimeError)r   rR   r	   r	   r
   bind_template   s    

zContext.bind_templatec                    s   t   }t| j|_|S r   )r   r%   r   rQ   r$   r   r	   r
   r%      s    
zContext.__copy__c                 C   s8   t |dstdt|tr.|jdd  }t| |S )z;Push other_dict to the stack of dictionaries in the Contextr7   z6other_dict must be a mapping (dictionary-like) object.r,   N)hasattr	TypeErrorr-   r   r   r   r   )r   
other_dictr	   r	   r
   rF      s
    

zContext.update)NTNN)
r   r   r   r   r   r   rU   r%   rF   r   r	   r	   r   r
   rK      s   
	rK   c                   @   sD   e Zd ZdZdZdd Zdd ZdddZd	d
 Ze	dddZ
dS )rP   a  
    A stack container for storing Template state.

    RenderContext simplifies the implementation of template Nodes by providing a
    safe place to store state between invocations of a node's `render` method.

    The RenderContext also provides scoping rules that are more sensible for
    'template local' variables. The render context stack is pushed before each
    template is rendered, creating a fresh scope with nothing in it. Name
    resolution fails if a variable is not found at the top of the RequestContext
    stack. Thus, variables are local to a specific template and don't affect the
    rendering of other templates as they would if they were stored in the normal
    template context.
    Nc                 c   s   | j d E d H  d S Nr1   r2   r   r	   r	   r
   r*      s    zRenderContext.__iter__c                 C   s   || j d kS rY   r2   r8   r	   r	   r
   r>      s    zRenderContext.__contains__c                 C   s   | j d ||S rY   )r   r@   )r   r3   r?   r	   r	   r
   r@      s    zRenderContext.getc                 C   s   | j d | S rY   r2   r8   r	   r	   r
   r7      s    zRenderContext.__getitem__Tc                 c   s<   | j }|| _ |r|   z
d V  W 5 || _ |r6|   X d S r   )rR   r/   r   )r   rR   Zisolated_contextinitialr	   r	   r
   
push_state   s    
zRenderContext.push_state)N)T)r   r   r   r   rR   r*   r>   r@   r7   r   r[   r	   r	   r	   r
   rP      s   
rP   c                       s<   e Zd ZdZd
 fdd	Zedd Zd fdd		Z  ZS )RequestContextz
    This subclass of template.Context automatically populates itself using
    the processors defined in the engine's configuration.
    Additional processors can be specified as a list of callables
    using the "processors" keyword argument.
    NTc                    sT   t  j||||d || _|d kr&dnt|| _t| j| _| i  | i  d S )N)rN   rO   rM   r	   )	r   r   requesttuple_processorsr0   r   _processors_indexrF   )r   r]   r   
processorsrN   rO   rM   r   r	   r
   r      s    	
zRequestContext.__init__c              	   c   st   | j d k	rtd|| _ |jj| j }i }|D ]}||| j q.|| j| j< z
d V  W 5 d | _ i | j| j< X d S rS   )	rR   rT   ZengineZtemplate_context_processorsr_   rF   r]   r   r`   )r   rR   ra   Zupdates	processorr	   r	   r
   rU      s    

zRequestContext.bind_templatec                    s   t  |}t|dr|`|S )Nr`   )r   rE   rV   r`   rC   r   r	   r
   rE     s    
zRequestContext.new)NNNNT)N)	r   r   r   r   r   r   rU   rE   r   r	   r	   r   r
   r\      s   
     
r\   Nc                 K   sZ   | dk	r"t | ts"td| jj |dkr8t| f|} n| }t|f|} |rV| | | S )zT
    Create a suitable Context from a plain dict and optionally an HttpRequest.
    Nz&context must be a dict rather than %s.)r-   dictrW   r   r   rK   r\   r/   )r   r]   r   Zoriginal_contextr	   r	   r
   make_context  s    

rd   )N)
contextlibr   r   Z_builtin_context_processors	Exceptionr   rc   r   r   rK   rP   r\   rd   r	   r	   r	   r
   <module>   s   j&,: