3
­©Þ[2  ã               @   sº   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
mZmZ ddlm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„ Zdd„ ZdS )é    N)Úimport_module)Úgetfullargspec)Úconditional_escape)Úis_iterableé   )ÚNodeÚTemplateÚtoken_kwargs)ÚTemplateSyntaxErrorc               @   s   e Zd ZdS )ÚInvalidTemplateLibraryN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú;/tmp/pip-install-j7i95hgp/django/django/template/library.pyr      s   r   c               @   sP   e Zd ZdZdd„ Zddd„Zdd„ Zdd	d
„Zdd„ Zddd„Z	ddd„Z
dS )ÚLibrarya  
    A class for registering template tags and filters. Compiled filter and
    template tag functions are stored in the filters and tags attributes.
    The filter, simple_tag, and inclusion_tag methods provide a convenient
    way to register callables as tags.
    c             C   s   i | _ i | _d S )N)ÚfiltersÚtags)Úselfr   r   r   Ú__init__   s    zLibrary.__init__Nc                s~   ˆ d kr|d krˆj S ˆ d k	rL|d krLtˆ ƒr8ˆj ˆ ƒS ‡ ‡fdd„}|S n.ˆ d k	rj|d k	rj|ˆjˆ < |S tdˆ |f ƒ‚d S )Nc                s   ˆj ˆ | ƒS )N)Útag)Úfunc)Únamer   r   r   Údec%   s    zLibrary.tag.<locals>.decz.Unsupported arguments to Library.tag: (%r, %r))Útag_functionÚcallabler   Ú
ValueError)r   r   Zcompile_functionr   r   )r   r   r   r      s    

zLibrary.tagc             C   s   || j t|d|ƒj< |S )NÚ_decorated_function)r   Úgetattrr   )r   r   r   r   r   r   2   s    zLibrary.tag_functionc                sØ   ˆdkr"|dkr"‡ ‡fdd„}|S ˆdk	r^|dkr^t ˆƒrHˆjˆfˆ ŽS ‡ ‡‡fdd„}|S nvˆdk	rÄ|dk	rÄ|ˆjˆ< x@d
D ]8}|ˆ kr~ˆ | }t|||ƒ t|dƒr~t|j||ƒ q~W ˆ|_|S td	ˆ|f ƒ‚dS )z™
        Register a callable as a template filter. Example:

        @register.filter
        def lower(value):
            return value.lower()
        Nc                s   ˆj | fˆ ŽS )N)Úfilter_function)r   )Úflagsr   r   r   r   @   s    zLibrary.filter.<locals>.decc                s   ˆj ˆ| fˆ ŽS )N)Úfilter)r   )r    r   r   r   r   r   I   s    Úexpects_localtimeÚis_safeÚneeds_autoescaper   z1Unsupported arguments to Library.filter: (%r, %r))r"   r#   r$   )r   r   r   ÚsetattrÚhasattrr   Z_filter_namer   )r   r   Zfilter_funcr    r   ÚattrÚvaluer   )r    r   r   r   r!   6   s*    


zLibrary.filterc             K   s   t |d|ƒj}| j||f|ŽS )Nr   )r   r   r!   )r   r   r    r   r   r   r   r   `   s    zLibrary.filter_functionc                s8   ‡ ‡‡fdd„}|dkr|S t |ƒr,||ƒS tdƒ‚dS )z§
        Register a callable as a compiled template tag. Example:

        @register.simple_tag
        def hello(*args, **kwargs):
            return 'world'
        c          
      s^   t ˆƒ\‰‰‰‰ ‰‰}ˆp&tˆdˆƒj‰tjˆƒ‡ ‡‡‡‡‡‡
‡‡f	dd„ƒ}ˆ	jˆ|ƒ ˆS )Nr   c                sn   |j ƒ dd … }d }t|ƒdkr@|d dkr@|d }|d d… }t| |ˆˆˆˆ ˆˆˆˆƒ
\}}tˆˆ|||ƒS )Nr   é   Úaséþÿÿÿéÿÿÿÿr+   )Úsplit_contentsÚlenÚ
parse_bitsÚ
SimpleNode)ÚparserÚtokenÚbitsÚ
target_varÚargsÚkwargs)	Údefaultsr   Úfunction_nameÚkwonlyÚkwonly_defaultsÚparamsÚtakes_contextÚvarargsÚvarkwr   r   Úcompile_funcp   s    z5Library.simple_tag.<locals>.dec.<locals>.compile_func)r   r   r   Ú	functoolsÚwrapsr   )r   Ú_r?   )r   r   r<   )r7   r   r8   r9   r:   r;   r=   r>   r   r   l   s
    &zLibrary.simple_tag.<locals>.decNz(Invalid arguments provided to simple_tag)r   r   )r   r   r<   r   r   r   )r   r   r<   r   Ú
simple_tagd   s    zLibrary.simple_tagc                s   ‡ ‡‡‡fdd„}|S )zß
        Register a callable as an inclusion tag:

        @register.inclusion_tag('results.html')
        def show_results(poll):
            choices = poll.choice_set.all()
            return {'choices': choices}
        c                s`   t ˆƒ\‰‰‰‰ ‰‰}ˆ	p&tˆdˆƒj‰tjˆƒ‡ ‡‡‡‡‡‡‡‡‡f
dd„ƒ}ˆ
jˆ|ƒ ˆS )Nr   c                s>   |j ƒ dd … }t| |ˆˆˆ	ˆ ˆˆˆˆƒ
\}}tˆˆ||ˆƒS )Nr   )r-   r/   ÚInclusionNode)r1   r2   r3   r5   r6   )
r7   Úfilenamer   r8   r9   r:   r;   r<   r=   r>   r   r   r?   •   s    z8Library.inclusion_tag.<locals>.dec.<locals>.compile_func)r   r   r   r@   rA   r   )r   rB   r?   )rE   r   r   r<   )r7   r   r8   r9   r:   r;   r=   r>   r   r   ‘   s
    (
z"Library.inclusion_tag.<locals>.decr   )r   rE   r   r<   r   r   r   )rE   r   r   r<   r   Úinclusion_tagˆ   s    	zLibrary.inclusion_tag)NN)NN)NNN)NNN)r   r   r   Ú__doc__r   r   r   r!   r   rC   rF   r   r   r   r   r      s   

*
$r   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚTagHelperNodez¬
    Base class for tag helper nodes such as SimpleNode and InclusionNode.
    Manages the positional and keyword arguments to be passed to the decorated
    function.
    c             C   s   || _ || _|| _|| _d S )N)r   r<   r5   r6   )r   r   r<   r5   r6   r   r   r   r   ª   s    zTagHelperNode.__init__c                sD   ‡ fdd„| j D ƒ}| jr$ˆ g| }‡ fdd„| jjƒ D ƒ}||fS )Nc                s   g | ]}|j ˆ ƒ‘qS r   )Úresolve)Ú.0Úvar)Úcontextr   r   ú
<listcomp>±   s    z8TagHelperNode.get_resolved_arguments.<locals>.<listcomp>c                s   i | ]\}}|j ˆ ƒ|“qS r   )rI   )rJ   ÚkÚv)rL   r   r   ú
<dictcomp>´   s    z8TagHelperNode.get_resolved_arguments.<locals>.<dictcomp>)r5   r<   r6   Úitems)r   rL   Úresolved_argsÚresolved_kwargsr   )rL   r   Úget_resolved_arguments°   s
    
z$TagHelperNode.get_resolved_argumentsN)r   r   r   rG   r   rT   r   r   r   r   rH   ¤   s   rH   c                   s$   e Zd Z‡ fdd„Zdd„ Z‡  ZS )r0   c                s   t ƒ j||||ƒ || _d S )N)Úsuperr   r4   )r   r   r<   r5   r6   r4   )Ú	__class__r   r   r   º   s    zSimpleNode.__init__c             C   sD   | j |ƒ\}}| j||Ž}| jd k	r2||| j< dS |jr@t|ƒ}|S )NÚ )rT   r   r4   Z
autoescaper   )r   rL   rR   rS   Úoutputr   r   r   Úrender¾   s    

zSimpleNode.render)r   r   r   r   rY   Ú__classcell__r   r   )rV   r   r0   ¸   s   r0   c                   s$   e Zd Z‡ fdd„Zdd„ Z‡  ZS )rD   c                s   t ƒ j||||ƒ || _d S )N)rU   r   rE   )r   r   r<   r5   r6   rE   )rV   r   r   r   Ë   s    zInclusionNode.__init__c             C   sÒ   | j |ƒ\}}| j||Ž}|jj| ƒ}|dkr¤t| jtƒrB| j}nXtt| jddƒtƒr`| jj}n:t| jt	ƒ rŠt
| jƒrŠ|jjj| jƒ}n|jjj| jƒ}||j| < |j|ƒ}|jdƒ}|dk	rÈ||d< |j|ƒS )z°
        Render the specified template and context. Cache the template object
        in render_context to avoid reparsing and loading when used in a for
        loop.
        NÚtemplateÚ
csrf_token)rT   r   Zrender_contextÚgetÚ
isinstancerE   r   r   r[   Ústrr   ZengineZselect_templateZget_templateÚnewrY   )r   rL   rR   rS   Ú_dictÚtZnew_contextr\   r   r   r   rY   Ï   s"    



zInclusionNode.render)r   r   r   r   rY   rZ   r   r   )rV   r   rD   É   s   rD   c
                s   |r*|d dkr|dd… }nt d|	 ƒ‚g }
i }t|ƒ}‡ fdd„|D ƒ}xþ|D ]ö}t|g| ƒ}|rê|jƒ \}}||krœ||krœ|dkrœt d|	|f ƒ‚nL||kr¶t d	|	|f ƒ‚n2||t|ƒ< ||krÖ|j|ƒ n||krè|j|ƒ qR|rüt d
|	 ƒ‚qR|
j| j|ƒƒ y|jdƒ W qR t	k
rF   |dkrBt d|	 ƒ‚Y qRX qRW |dk	rh|dt
|ƒ … }|st|r˜t d|	djdd„ || D ƒƒf ƒ‚|
|fS )z°
    Parse bits for template tag helpers simple_tag and inclusion_tag, in
    particular by detecting syntax errors and by extracting positional and
    keyword arguments.
    r   rL   r   NzW'%s' is decorated with takes_context=True so it must have a first argument of 'context'c                s   g | ]}ˆ  s|ˆ kr|‘qS r   r   )rJ   Úkwarg)r:   r   r   rM   ÿ   s    zparse_bits.<locals>.<listcomp>z.'%s' received unexpected keyword argument '%s'z7'%s' received multiple values for keyword argument '%s'zH'%s' received some positional argument(s) after some keyword argument(s)z+'%s' received too many positional argumentsz5'%s' did not receive value(s) for the argument(s): %sz, c             s   s   | ]}d | V  qdS )z'%s'Nr   )rJ   Úpr   r   r   ú	<genexpr>4  s    zparse_bits.<locals>.<genexpr>)r
   Úlistr	   Úpopitemr_   ÚremoveÚappendZcompile_filterÚpopÚ
IndexErrorr.   Újoin)r1   r3   r;   r=   r>   r7   r9   r:   r<   r   r5   r6   Zunhandled_paramsZunhandled_kwargsÚbitrc   Úparamr(   r   )r:   r   r/   í   s\    



 r/   c             C   sl   yt | ƒ}W n2 tk
r> } ztd| |f ƒ‚W Y dd}~X nX y|jS  tk
rf   td|  ƒ‚Y nX dS )z;
    Load a Library object from a template tag module.
    zSInvalid template library specified. ImportError raised when trying to load '%s': %sNz4Module  %s does not have a variable named 'register')r   ÚImportErrorr   ÚregisterÚAttributeError)r   ÚmoduleÚer   r   r   Úimport_library8  s    rt   )r@   Ú	importlibr   Úinspectr   Zdjango.utils.htmlr   Zdjango.utils.itercompatr   Úbaser   r   r	   Ú
exceptionsr
   Ú	Exceptionr   r   rH   r0   rD   r/   rt   r   r   r   r   Ú<module>   s    $K