U
    @ޫ^                 	   @   sF  d 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 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 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% dddddd d!d"d#Z&e'e(d$rLd$Z)nd%Z)d&gZ*ze+d' e*,d( W n e-k
r   Y nX ze+d) W n e-k
r   d*Z.Y nX d+Z.d,d- Z/dCd/d0Z0d1d2 Z1d3d4 Z2G d5d6 d6e3Z4G d7d8 d8e3Z5G d9d: d:e6Z7G d;d< d<e%Z8G d=d> d>e%Z9G d?d@ d@e:Z;G dAdB dBe%Z<d.S )Dz0Compiles nodes from the parser into Python code.    )
namedtupleupdate_wrapper)chain)	iskeyword)escape)Markup   )nodes)imap)	iteritems)izip)NativeStringIO)
range_type)string_types)	text_type)TemplateAssertionError)Symbols)VAR_LOAD_ALIAS)VAR_LOAD_PARAMETER)VAR_LOAD_RESOLVE)VAR_LOAD_UNDEFINED)EvalContext)	Optimizer)concat)NodeVisitorz==z!=>z>=<z<=inznot in)eqnegtZgteqltZlteqr   notinr   itemsdivisionz%from __future__ import generator_stopgenerator_stopzdef f(): yield from x()FTc                    s    fdd}t | S )Nc                    sB   | j r2|jjs2| j||j}||kr2| ||S  | ||f|S N)	optimizedeval_ctxvolatile	optimizervisit)selfnodeframekwargsZnew_nodef 3/tmp/pip-unpacked-wheel-o736f1kv/jinja2/compiler.pynew_funcC   s
    zoptimizeconst.<locals>.new_funcr   )r2   r5   r3   r1   r4   optimizeconstB   s    r6   Nc                 C   sH   t | tjstd|||||||}||  |dkrD|j S dS )z+Generate the python source for a node tree.z Can't compile non template nodesN)
isinstancer
   Template	TypeErrorZcode_generator_classr,   streamgetvalue)r.   environmentnamefilenamer:   
defer_initr(   	generatorr3   r3   r4   generateN   s         
rA   c                 C   s   | dks| t ks| tkrdS t| ttttttft	 kr<dS t| t
tttfkrl| D ]}t|sT dS qTdS t| tkrt| D ]$\}} t|s dS t| s dS qdS dS )z)Does the node have a safe representation?NTF)NotImplementedEllipsistypeboolintfloatcomplexr   r   r   tuplelistset	frozensethas_safe_reprdictr   )valueitemkeyr3   r3   r4   rM   \   s"    rM   c                 C   s<   t |}z| D ]}|| qW n tk
r4   Y nX |jS )zCheck if the names passed are accessed undeclared.  The return value
    is a set of all the undeclared names from the sequence of names found.
    )UndeclaredNameVisitorr,   VisitorExit
undeclared)r
   namesvisitorr.   r3   r3   r4   find_undeclaredq   s    rW   c                   @   s   e Zd Zdd ZdS )MacroRefc                 C   s   || _ d| _d| _d| _d S )NF)r.   accesses_calleraccesses_kwargsaccesses_varargsr-   r.   r3   r3   r4   __init__   s    zMacroRef.__init__N)__name__
__module____qualname__r]   r3   r3   r3   r4   rX   ~   s   rX   c                   @   s8   e Zd ZdZdddZdd Zddd	Zd
d ZeZdS )Framez&Holds compile time information for us.Nc                 C   sf   || _ t|r|jpd |d| _d| _d| _|o2|j| _d | _|rF|jpHd | _|| _|d k	rb|j| _d S )NlevelF)	r)   r   symbolstoplevel	rootlevelrequire_output_checkbufferblockparent)r-   r)   rj   rc   r3   r3   r4   r]      s    zFrame.__init__c                 C   s*   t | j}|j| j | j |_|S )z!Create a copy of the current one.)object__new__	__class____dict__updaterd   copyr-   rvr3   r3   r4   rp      s    z
Frame.copyFc                 C   s&   |rt | j| jjd dS t | j| S )zReturn an inner frame.r	   rb   )ra   r)   rd   rc   )r-   isolatedr3   r3   r4   inner   s    zFrame.innerc                 C   s   |   }d|_|S )a  Return a soft frame.  A soft frame may not be modified as
        standalone thing as it shares the resources with the frame it
        was created of, but it's not a rootlevel frame any longer.

        This is only used to implement if-statements.
        F)rp   rf   rq   r3   r3   r4   soft   s    z
Frame.soft)NN)F)	r^   r_   r`   __doc__r]   rp   rt   ru   __copy__r3   r3   r3   r4   ra      s   

ra   c                   @   s   e Zd ZdZdS )rS   z?Exception used by the `UndeclaredNameVisitor` to signal a stop.Nr^   r_   r`   rv   r3   r3   r3   r4   rS      s   rS   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )DependencyFinderVisitorz.A visitor that collects filter and test calls.c                 C   s   t  | _t  | _d S r'   )rK   filterstestsr-   r3   r3   r4   r]      s    z DependencyFinderVisitor.__init__c                 C   s   |  | | j|j d S r'   )generic_visitrz   addr=   r\   r3   r3   r4   visit_Filter   s    
z$DependencyFinderVisitor.visit_Filterc                 C   s   |  | | j|j d S r'   )r}   r{   r~   r=   r\   r3   r3   r4   
visit_Test   s    
z"DependencyFinderVisitor.visit_Testc                 C   s   dS )zStop visiting at blocks.Nr3   r\   r3   r3   r4   visit_Block   s    z#DependencyFinderVisitor.visit_BlockN)r^   r_   r`   rv   r]   r   r   r   r3   r3   r3   r4   ry      s
   ry   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	rR   zA visitor that checks if a name is accessed without being
    declared.  This is different from the frame visitor as it will
    not stop at closure frames.
    c                 C   s   t || _t  | _d S r'   )rK   rU   rT   )r-   rU   r3   r3   r4   r]      s    
zUndeclaredNameVisitor.__init__c                 C   sJ   |j dkr8|j| jkr8| j|j | j| jkrFt n| j|j d S )Nload)ctxr=   rU   rT   r~   rS   discardr\   r3   r3   r4   
visit_Name   s
    z UndeclaredNameVisitor.visit_Namec                 C   s   dS )zStop visiting a blocks.Nr3   r\   r3   r3   r4   r      s    z!UndeclaredNameVisitor.visit_BlockN)r^   r_   r`   rv   r]   r   r   r3   r3   r3   r4   rR      s   rR   c                   @   s   e Zd ZdZdS )CompilerExitzRaised if the compiler encountered a situation where it just
    doesn't make sense to further process the code.  Any block that
    raises such an exception is not further processed.
    Nrx   r3   r3   r3   r4   r      s   r   c                   @   s  e Zd ZdddZdd Zdd	 Zd
d ZdddZdd ZdddZ	dddZ
dd ZdddZdd Zdd ZdddZdd d!Zdd"d#Zd$d% Zd&d' Zdd(d)Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zd@dA Z dBdC Z!dDdE Z"dFdG Z#dHdI Z$dJdK Z%ddLdMZ&dNdO Z'dPdQ Z(dRdS Z)dTdU Z*dVdW Z+dXdY Z,dZd[ Z-d\d] Z.d^d_ Z/d`da Z0dbdc Z1ddde Z2e3dfdgZ4e5Z6dZ7dhdi Z8djdk Z9dldm Z:dndo Z;dpdq Z<drds Z=dtdu Z>dvdw Z?dxdy Z@dzd{ ZAd|d} ZBd~d ZCdd ZDdd ZEdd ZFdddZGdddZHeGdZIeGdZJeGdZKeGdZLeGdZMeGdZNeGdZOeGdddZPeGdddZQeHdZReHdZSeHdddZT[G[HeUdd ZVeUdd ZWdd ZXeUdd ZYeUdd ZZdd Z[eUdd Z\eUdd Z]eUdd Z^eUdddZ_dd Z`dd Zadd Zbdd Zcdd Zddd Zedd Zfdd Zgdd Zhdd Zidd Zjdd Zkdd ZlddĄ ZmddƄ ZndS )CodeGeneratorNFTc                 C   s   |d krt  }|| _|| _|| _|| _d| _|| _|| _|rFt|| _	i | _
i | _d| _d| _d| _i | _i | _g | _d | _d| _d| _d| _d| _d| _g | _g | _dg| _d S )NFr   r	   Tcontext)r   r<   r=   r>   r:   Zcreated_block_contextr?   r(   r   r+   import_aliasesblocksextends_so_farhas_known_extendscode_linenor{   rz   
debug_info_write_debug_info
_new_lines
_last_line_first_write_last_identifier_indentation_assign_stack_param_def_block_context_reference_stack)r-   r<   r=   r>   r:   r?   r(   r3   r3   r4   r]      s8    
zCodeGenerator.__init__c                 C   s   t ||| j| jdS )z*Fail with a :exc:`TemplateAssertionError`.N)r   r=   r>   )r-   msglinenor3   r3   r4   fail<  s    zCodeGenerator.failc                 C   s   |  j d7  _ d| j  S )zGet a new unique identifier.r	   zt_%d)r   r|   r3   r3   r4   temporary_identifier@  s    z"CodeGenerator.temporary_identifierc                 C   s   |   |_| d|j  dS )z7Enable buffering for the frame from that point onwards.z%s = []N)r   rh   	writeliner-   r/   r3   r3   r4   rh   E  s    
zCodeGenerator.bufferc                 C   s   |s|j jrd| d |   | d|j  |   | d |   | d|j  |   dS |j jr| d|j  dS | d|j  dS )z(Return the buffer contents of the frame.zif context.eval_ctx.autoescape:zreturn Markup(concat(%s))else:zreturn concat(%s)N)r)   r*   r   indentrh   outdent
autoescape)r-   r/   force_unescapedr3   r3   r4   return_buffer_contentsJ  s    

z$CodeGenerator.return_buffer_contentsc                 C   s   |  j d7  _ dS )zIndent by one.r	   Nr   r|   r3   r3   r4   r   \  s    zCodeGenerator.indentr	   c                 C   s   |  j |8  _ dS )zOutdent by step.Nr   )r-   stepr3   r3   r4   r   `  s    zCodeGenerator.outdentc                 C   s.   |j dkr| d| n| d|j  | dS )z%Yield or write into the frame buffer.Nyield 
%s.append()rh   r   )r-   r/   r.   r3   r3   r4   start_writed  s    
zCodeGenerator.start_writec                 C   s   |j dk	r| d dS )z1End the writing process started by `start_write`.N))rh   writer   r3   r3   r4   	end_writek  s    
zCodeGenerator.end_writec                 C   s$   |  || | | | | dS )z4Simple shortcut for start_write + write + end_write.N)r   r   r   )r-   sr/   r.   r3   r3   r4   simple_writep  s    
zCodeGenerator.simple_writec                 C   s>   z$|  d |D ]}| || qW n tk
r8   Y nX dS )zVisit a list of nodes as block in a frame.  If the current frame
        is no buffer a dummy ``if 0: yield None`` is written automatically.
        passN)r   r,   r   )r-   r
   r/   r.   r3   r3   r4   
blockvisitv  s    
zCodeGenerator.blockvisitc                 C   s   | j rp| jsR| jd| j   |  j| j 7  _| jdk	rR| j| j| jf d| _d| _| jd| j  d| _ | j| dS )z&Write a string into the output stream.
NFz    r   )	r   r   r:   r   r   r   r   appendr   )r-   xr3   r3   r4   r     s    
zCodeGenerator.writer   c                 C   s   |  || | | dS )z!Combination of newline and write.N)newliner   )r-   r   r.   extrar3   r3   r4   r     s    zCodeGenerator.writelinec                 C   s:   t | jd| | _|dk	r6|j| jkr6|j| _|j| _dS )z/Add one or more newlines before the next write.r	   N)maxr   r   r   r   )r-   r.   r   r3   r3   r4   r     s    zCodeGenerator.newlinec           	      C   s  d}t dd |jD |pdD ]}t|rd} q4q|jD ]}| d | || q:|s|jD ]}| d | || q`|dk	rt|D ]\}}| d||f  q|jr| d	 | |j| |r|jdk	r| d
 n
| d |jD ],}| d|j	  | |j
| | d q|dk	rPt|D ]\}}| d||f  q2|jdk	r| d | |j| | d n
| d n$|jdk	r| d | |j| dS )a+  Writes a function call to the stream for the current node.
        A leading comma is added automatically.  The extra keyword
        arguments may not include python keywords otherwise a syntax
        error could occur.  The extra keyword arguments should be given
        as python dict.
        Fc                 s   s   | ]}|j V  qd S r'   )rQ   .0r   r3   r3   r4   	<genexpr>  s     z*CodeGenerator.signature.<locals>.<genexpr>r3   T, Nz, %s=%sz, *z
, **dict({z, **{z%r: z%r: %s, z}, **r   }z, **)r   r0   is_python_keywordargsr   r,   r   Zdyn_argsZ
dyn_kwargsrQ   rO   )	r-   r.   r/   extra_kwargsZkwarg_workaroundkwargargrQ   rO   r3   r3   r4   	signature  sJ    	










zCodeGenerator.signaturec                 C   sn   t  }|D ]}|| q
dD ]J}t| |}t||D ]0}||krN|  ||< | d|| ||f  q6qdS )zPull all the dependencies.)rz   r{   z%s = environment.%s[%r]N)ry   r,   getattrr   r   )r-   r
   rV   r.   
dependencymappingr=   r3   r3   r4   pull_dependencies  s    
zCodeGenerator.pull_dependenciesc                 C   s   g }t |jjD ]p\}\}}|tkr&q|tkrH| d||  |f  q|tkrd| d||f  q|tkrx|	| qt
dq|r| dd|  d S )Nz%s = %s(%r)%s = %szunknown load instruction%s = missing = )r   rd   loadsr   r   r   get_resolve_funcr   r   r   NotImplementedErrorjoin)r-   r/   undefstargetactionparamr3   r3   r4   enter_frame  s    
zCodeGenerator.enter_framec                 C   sD   |s@g }t |jjD ]\}}|| q|r@| dd|  d S )Nr   r   )r   rd   r   r   r   r   )r-   r/   with_python_scoper   r   _r3   r3   r4   leave_frame  s    zCodeGenerator.leave_framec                 C   s   | j jrd| S d| S )Nzasync def %szdef %s)r<   is_async)r-   r=   r3   r3   r4   func  s    zCodeGenerator.funcc              
   C   s  |  }|j| t|}d}t }g }t|jD ]@\}}|jdkrJ|}|jdkr`||j |	|j
|j q4t|jd}	d|	kr|dk	rz|j|t|j   W q tk
r   | d|j Y qX n|	|jd d|_d|	krd|kr|	|jd d|_d|	kr@d|kr@|	|jd d|_d	|_|j| | d
| dd|f | |   | | | | | | t|jD ]\}}|j
|j}
| d|
  |   z|j|t|j  }W n2 tk
r   | d|
d|j |jf  Y nX | d|
  | || | |
 |    q| !  | "|j| | j#|dd | j$|dd |    ||fS )z/Dump the function def of a macro or call block.Ncaller)r0   varargs)r   r0   r   zhWhen defining macros or call blocks the special "caller" argument must be omitted or be given a default.Tr0   r   Fz%s(%s):macror   if %s is missing:z%s = undefined(%r, name=%r)zparameter %r was not provided%s = )r   r   )%rt   rd   analyze_noderX   rK   	enumerater   r=   r~   r   refrW   bodydefaultslen
IndexErrorr   r   declare_parameterrY   rZ   r[   rg   r   r   r   r   rh   r   push_parameter_definitionsr,   mark_parameter_storedr   pop_parameter_definitionsr   r   r   )r-   r.   r/   	macro_refZexplicit_callerZskip_special_paramsr   idxr   rT   r   defaultr3   r3   r4   
macro_body  sv    

 




zCodeGenerator.macro_bodyc                 C   s`   d dd |jjD }t|jdd}t|jjdkr>|d7 }| d|||j|j|jf  dS )	z<Dump the macro definition for the def created by macro_body.r   c                 s   s   | ]}t |jV  qd S r'   )reprr=   r   r3   r3   r4   r   M  s     z*CodeGenerator.macro_def.<locals>.<genexpr>r=   Nr	   ,zLMacro(environment, macro, %r, (%s), %r, %r, %r, context.eval_ctx.autoescape))	r   r.   r   r   r   r   rZ   r[   rY   )r-   r   r/   Z	arg_tupler=   r3   r3   r4   	macro_defK  s    zCodeGenerator.macro_defc                 C   s*   d|j  }| jdk	r&|dt| j 7 }|S )z.Return a human readable position for the node.zline %dN in )r   r=   r   )r-   r.   rr   r3   r3   r4   position]  s    

zCodeGenerator.positionc                 C   s"   dd dd t|j D  S )Nz{%s}r   c                 s   s   | ]\}}d ||f V  qdS %r: %sNr3   )r   r=   r   r3   r3   r4   r   e  s   z3CodeGenerator.dump_local_context.<locals>.<genexpr>)r   r   rd   Zdump_storesr   r3   r3   r4   dump_local_contextd  s    z CodeGenerator.dump_local_contextc                 C   s,   |  d |  d |  d |  d dS )zWrites a common preamble that is used by root and block functions.
        Primarily this sets up common local helpers and enforces a generator
        through a dead branch.
        z$resolve = context.resolve_or_missingz!undefined = environment.undefinedzcond_expr_undefined = Undefinedzif 0: yield NoneNr   r|   r3   r3   r4   write_commonsj  s    


zCodeGenerator.write_commonsc                 C   s   | j |j  dS )aQ  Pushes all parameter targets from the given frame into a local
        stack that permits tracking of yet to be assigned parameters.  In
        particular this enables the optimization from `visit_Name` to skip
        undefined expressions for parameters in macros as macros can reference
        otherwise unbound parameters.
        N)r   r   rd   Zdump_param_targetsr   r3   r3   r4   r   v  s    z(CodeGenerator.push_parameter_definitionsc                 C   s   | j   dS )z+Pops the current parameter definitions set.N)r   popr|   r3   r3   r4   r     s    z'CodeGenerator.pop_parameter_definitionsc                 C   s   | j r| j d | dS )zMarks a parameter in the current parameter definitions as stored.
        This will skip the enforced undefined checks.
        N)r   r   r-   r   r3   r3   r4   r     s    z#CodeGenerator.mark_parameter_storedc                 C   s   | j | d S r'   )r   r   r   r3   r3   r4   push_context_reference  s    z$CodeGenerator.push_context_referencec                 C   s   | j   d S r'   )r   r   r|   r3   r3   r4   pop_context_reference  s    z#CodeGenerator.pop_context_referencec                 C   s
   | j d S )Nr   r   r|   r3   r3   r4   get_context_ref  s    zCodeGenerator.get_context_refc                 C   s   | j d }|dkrdS d| S )Nr   r   resolvez
%s.resolver   r   r3   r3   r4   r     s    
zCodeGenerator.get_resolve_funcc                 C   s   d|   | |f S )Nz%s.derived(%s))r   r   r   r3   r3   r4   derive_context  s    zCodeGenerator.derive_contextc                 C   s   | j s
dS || j d kS )z4Checks if a given target is an undeclared parameter.Fr   )r   r   r3   r3   r4   parameter_is_undeclared  s    z%CodeGenerator.parameter_is_undeclaredc                 C   s   | j t  dS )z+Pushes a new layer for assignment tracking.N)r   r   rK   r|   r3   r3   r4   push_assign_tracking  s    z"CodeGenerator.push_assign_trackingc                 C   s   | j  }|jr|sdS dd |D }t|dkr^tt|}|j|}| d||f  nR| d t	|D ]4\}}|r| 
d |j|}| 
d||f  qp| 
d	 |rt|dkr| d
|d   n| ddtt|  dS )zoPops the topmost level for assignment tracking and updates the
        context variables if necessary.
        Nc                 S   s    g | ]}|d d dkr|qS )Nr	   r   r3   r   r3   r3   r4   
<listcomp>  s      z5CodeGenerator.pop_assign_tracking.<locals>.<listcomp>r	   context.vars[%r] = %szcontext.vars.update({r   r   z})context.exported_vars.add(%r)r   z"context.exported_vars.update((%s)))r   r   re   r   nextiterrd   r   r   r   r   r   r   r   )r-   r/   varsZpublic_namesr=   r   r   r3   r3   r4   pop_assign_tracking  s.    




z!CodeGenerator.pop_assign_trackingc                 C   s  |d kst dt| j| j}ddlm} | ddt  | dd|  | jj	rd| d | j
 rpdprd	}|tjd k	}|tjD ]0}|j| jkr| d
|j |j || j|j< q|tjD ]j}|j| jkr|j}	|   | j|	< }
d|	kr&|	dd\}}| d|||
f  q| d|	|
f  q| d| j  | jd| d|f dd |   |   t|}dt|jdkr|jd}| d|  |j | d |_!|_"|o| j# |_$|r| d | %| | &|j | '|j| | j(|dd | )  |r| j#s<|   | d |   t*r`| jj	s`| d n8| d| jj	rvdpxd	  |   | d | )  | )d| j#   t+| jD ]\}}| d| d| |f |d |   |   t|}t|jd}d|kr$|jd}| d|  d|krN|jd}| d |||f  |j | ||_,| %| | &|j | '|j| | j(|dd | )  q| jd!dd"d# | jD  dd | d$d%d&d# | j-D   d S )'Nzno root frame allowedr	   )exportedzfrom __future__ import %sr   zfrom jinja2.runtime import zHfrom jinja2.asyncsupport import auto_await, auto_aiter, AsyncLoopContextz, environment=environment zblock %r defined twice.zfrom %s import %s as %szimport %s as %sz	name = %rz%s(context, missing=missing%s):root)r   r-   r|   z%s = TemplateReference(context)Tzparent_template = Noner   if parent_template is not None:z4yield from parent_template.root_render_func(context)z9%sfor event in parent_template.root_render_func(context):zasync zyield eventZblock_)r-   superr  z %s = context.super(%r, block_%s)zblocks = {%s}c                 s   s   | ]}d ||f V  qdS )z%r: block_%sNr3   r   r3   r3   r4   r   ;  s     z/CodeGenerator.visit_Template.<locals>.<genexpr>zdebug_info = %r&c                 s   s   | ]}d | V  qdS )z%s=%sNr3   r   r3   r3   r4   r   A  s     ).AssertionErrorr   r<   r=   Zruntimer  r   r   code_featuresr   r?   findr
   ZExtendsfind_allZBlockr   r   r   ZImportedName
importnamer   r   rsplitr   r   r   ra   rW   r   rd   r   r   re   rf   r   rg   r   r   r   r   r   supports_yield_fromr   ri   r   )r-   r.   r/   r)   r  ZenvenvZhave_extendsri   import_impaliasmoduleobjr   r=   block_framerT   r3   r3   r4   visit_Template  s    
 






zCodeGenerator.visit_Templatec                 C   s   d}|j r8| jrdS | jdkr8| d |   |d7 }|jrJ| |}n|  }tr| j	j
s|jdkr| d|j|f | nD| j	j
rdpd}| d||j|f | |   | d	| |   | | dS )
z.Call a block and register it for the template.r   Nif parent_template is None:r	   z$yield from context.blocks[%r][0](%s)	async forforz&%s event in context.blocks[%r][0](%s):event)re   r   r   r   r   scopedr   r   r  r<   r   rh   r=   r   r   )r-   r.   r/   rc   r   loopr3   r3   r4   r   D  s<    

 zCodeGenerator.visit_Blockc                 C   s   |j s| d|j | jdkrZ| js6| d |   | dd  | jrRt n|   | d| | 	|j
| | d| j  | dt  |   | d	 |   |jrd
| _|  jd7  _dS )zCalls the extender.z,cannot use extend from a non top-level scoper   r  raise TemplateRuntimeError(%r)zextended multiple timesz+parent_template = environment.get_template(, %r)z6for name, parent_block in parent_template.blocks.%s():z8context.blocks.setdefault(name, []).append(parent_block)Tr	   N)re   r   r   r   r   r   r   r   r   r,   templater   r=   dict_item_iterrf   r-   r.   r/   r3   r3   r4   visit_Extendsj  s,    


zCodeGenerator.visit_Extendsc                 C   s  |j r| d |   d}t|jtjrVt|jjtr>d}qnt|jjt	t
frnd}nt|jtjtjfrnd}| d| | | |j| | d| j  |j r|   | d |   | d |   | d	 |   d
}|jr| jjrdpd}| d|| |f  n6| jjr,| d n trB| d d}n
| d |sn|   | d| |   |j r~|   dS )zHandles includes.ztry:Zget_or_select_templateZget_templateZselect_templateztemplate = environment.%s(r#  zexcept TemplateNotFound:r   r   Fr  r  zY%s event in template.root_render_func(template.new_context(context.get_all(), True, %s)):zGfor event in (await template._get_default_module_async())._body_stream:z6yield from template._get_default_module()._body_streamTz9for event in template._get_default_module()._body_stream:r  N)Zignore_missingr   r   r7   r$  r
   ZConstrO   r   rI   rJ   ZTupleZListr,   r   r=   r   with_contextr<   r   r   r  r   )r-   r.   r/   	func_nameZskip_event_yieldr!  r3   r3   r4   visit_Include  s\    





zCodeGenerator.visit_Includec                 C   s   |  d|j|j | |jr0| d|j  | jjrB| d | d | |j	| | d| j
  |jr| d| jjrdpd| |f  n| jjr| d	 n
| d
 |jr|jds|  d|j  dS )zVisit regular imports.r   context.vars[%r] = await zenvironment.get_template(, %r).*make_module%s(context.get_all(), True, %s)_asyncr  _get_default_module_async()_get_default_module()r   !context.exported_vars.discard(%r)N)r   rd   r   r   re   r   r<   r   r,   r$  r=   r(  r   
startswithr&  r3   r3   r4   visit_Import  s*    


zCodeGenerator.visit_Importc              	      s  |  | | d| jjrdpd  | |j  | d| j  |jrn| d| jjrZdp\d|  f  n| jjr| d n
| d g }g }|j	D ]}t
|tr|\}}n|}| d	 j||f  | d
 j|  |   | d j|d| |t|f |f  |    jr|| |ds|| q|rt|dkr|d }| d| j|f  n"| dd fdd|D   |rt|dkr| d|d   n| ddtt|  dS )zVisit named imports.z/included_template = %senvironment.get_template(r,  r  r-  r.  r/  r0  r1  z,%s = getattr(included_template, %r, missing)r   z9%s = undefined(%r %% included_template.__name__, name=%r)zGthe template %%r (imported on %s) does not export the requested name %sr   r	   r   r  zcontext.vars.update({%s})r   c                 3   s"   | ]}d | j |f V  qdS r   )rd   r   )r   r=   r/   r3   r4   r   (  s    z1CodeGenerator.visit_FromImport.<locals>.<genexpr>r2  z-context.exported_vars.difference_update((%s))N)r   r   r<   r   r,   r$  r=   r(  r   rU   r7   rI   r   rd   r   r   r   r   r   re   r   r3  r   r   r   )r-   r.   r/   Z	var_namesZdiscarded_namesr=   r  r3   r5  r4   visit_FromImport  s    







zCodeGenerator.visit_FromImportc                 C   sN  |  }|  }|  }|jp2dt|jdddk}d }|rH|jd}|jj|dd |jrn|jj|dd |jrl| 	 }|jj|dd | 
d	| | |j |   | | | 
| jjrd
pd | |j| | d | | jjrdpd | d |   | 
d|j | |j| | d |   | 
d | |j| | d | j|dd |jr| 
d| d | |   | | |j|_|r| 
d|  |tjD ],}	|	jdkr|	jdkr| d|	j q|jr| 	 }
| 
d|
  | 
| jjr$d
p&d| | |j| |rj| jjrZ| d|  n| d|  n
| d |jr| d|  |jr| d nB| jjr|s| d | |j| | jjr|s| d |jr| d |jr| d  n| |rd!pd |   | | | |j| |jrR| 
d"|
  |   | j||jon|j d |jr| 
d#|
  |   | | | |j| | | |   |jrJ|  | |   | !|| | jjr| d$ | d% | jjr| d | |j| | jjr6| d | d& | "| d S )'Nr!  )r   )only)r!  r   )Z
for_branchelsetestz
%s(fiter):z
async for zfor r   zauto_aiter(fiter)Zfiter:if r      Tr   z'%s(reciter, loop_render_func, depth=0):r   storez8Can't assign to special loop variable in for-loop targetz%s = 1z, %s in AsyncLoopContext(z, %s in LoopContext(z%s(Zreciterzauto_aiter(r   z&, undefined, loop_render_func, depth):z, undefined):z%s = 0zif %s:r,  zloop(z, loop))#rt   	recursiverW   Ziter_child_nodesrd   r   r   else_r9  r   r   r   r   r   r<   r   r,   r   r   r   r   rh   r  r
   Namer   r=   r   r   r  r   r   r   r   r   )r-   r.   r/   Z
loop_frameZ
test_frameZ
else_frameZextended_loopZloop_refZloop_filter_funcr=   Ziteration_indicatorr3   r3   r4   	visit_For5  s    

 





 






 










zCodeGenerator.visit_Forc                 C   s   |  }| d| | |j| | d |   | |j| |   |j	D ]F}| d| | |j| | d |   | |j| |   qP|j
r| d |   | |j
| |   d S )Nr;  r:  zelif r   )ru   r   r,   r9  r   r   r   r   r   elif_r?  )r-   r.   r/   Zif_framerB  r3   r3   r4   visit_If  s&    




zCodeGenerator.visit_Ifc                 C   sr   |  ||\}}|   |jrJ|jds:| d|j  | d|j  | d|j|j  | 	|| d S )Nr   r  r+  r   )
r   r   re   r=   r3  r   r   rd   r   r   )r-   r.   r/   Zmacro_framer   r3   r3   r4   visit_Macro  s    zCodeGenerator.visit_Macroc                 C   sR   |  ||\}}| d | || | || | j|j|dd | | d S )Nz	caller = T)forward_caller)r   r   r   r   
visit_Callcallr   )r-   r.   r/   Z
call_framer   r3   r3   r4   visit_CallBlock  s    
zCodeGenerator.visit_CallBlockc                 C   sh   |  }|j| | | | | | |j| | || | |j	| | 
| | | d S r'   )rt   rd   r   r   rh   r   r   r   r   filterr   r   )r-   r.   r/   Zfilter_framer3   r3   r4   visit_FilterBlock  s    


zCodeGenerator.visit_FilterBlockc                 C   s|   |  }|j| | | t|j|jD ]2\}}|   | || | 	d | || q,| 
|j| | | d S Nr   )rt   rd   r   r   r   targetsvaluesr   r,   r   r   r   r   )r-   r.   r/   Z
with_framer   exprr3   r3   r4   
visit_With  s    

zCodeGenerator.visit_Withc                 C   s   |  | | |j| d S r'   )r   r,   r.   r&  r3   r3   r4   visit_ExprStmt  s    
zCodeGenerator.visit_ExprStmt_FinalizeInfo)constsrcc                    s   j dk	rj S j } d}jjrd}jj fdd}tdddkr^|d7 }d}nFtd	ddkr||d
7 }d}n(tdddkr|d7 } fdd}||_ j S )a  Build the finalize function to be used on constants and at
        runtime. Cached so it's only created once for all output nodes.

        Returns a ``namedtuple`` with the following attributes:

        ``const``
            A function to finalize constant data at compile time.

        ``src``
            Source code to output around nodes to be evaluated at
            runtime.
        Nzenvironment.finalize(c                    s    | S r'   r3   rO   )r   env_finalizer3   r4   finalize  s    z.CodeGenerator._make_finalize.<locals>.finalizeZcontextfunctionFT	context, Zevalcontextfunctioncontext.eval_ctx, Zenvironmentfunctionenvironment, c                    s    j | S r'   )r<   rT  r   rU  r-   r3   r4   rV  '  s    )	_finalize_default_finalizer<   rV  r   rQ  )r-   rV  rS  r3   rZ  r4   _make_finalize  s&    

zCodeGenerator._make_finalizec                 C   s   t t|S )zGiven a group of constant values converted from ``Output``
        child nodes, produce a string to write to the template module
        source.
        )r   r   )r-   groupr3   r3   r4   _output_const_repr-  s    z CodeGenerator._output_const_reprc                 C   s:   | |j}|jjrt|}t|tjr0t|S ||S )aC  Try to optimize a child of an ``Output`` node by trying to
        convert it to constant, finalized data at compile time.

        If :exc:`Impossible` is raised, the node is not constant and
        will be evaluated at runtime. Any other exception will also be
        evaluated at runtime for easier debugging.
        )	as_constr)   r   r   r7   r
   TemplateDatar   rR  )r-   r.   r/   rV  rR  r3   r3   r4   _output_child_to_const4  s    z$CodeGenerator._output_child_to_constc                 C   sL   |j jr| d n|j jr(| d n
| d |jdk	rH| |j dS )zXOutput extra source code before visiting a child of an
        ``Output`` node.
        z7(escape if context.eval_ctx.autoescape else to_string)(zescape(z
to_string(N)r)   r*   r   r   rS  r-   r.   r/   rV  r3   r3   r4   _output_child_preG  s    

zCodeGenerator._output_child_prec                 C   s"   |  d |jdk	r|  d dS )zWOutput extra source code after visiting a child of an
        ``Output`` node.
        r   N)r   rS  rc  r3   r3   r4   _output_child_postU  s    

z CodeGenerator._output_child_postc           	   
   C   s  |j r"| jrd S | d |   |  }g }|jD ]}z,|jsTt|tjsTt	 | 
|||}W n( tj	tfk
r   || Y q4Y nX |rt|d tr|d | q4||g q4|jd k	rt|dkr| d|j  n| d|j  |   |D ]}t|trH| |}|jd kr8| d|  n| |d  nb|jd krb| d| n
| | | ||| | || | ||| |jd k	r| d q|jd k	r|   | t|dkrdnd	 |j r|   d S )
Nr  r   r	   r   z%s.extend((r   r   r   )))rg   r   r   r   r]  r
   rR  r7   ra  
Impossiblerb  	Exceptionr   rJ   rh   r   r_  r   rd  r,   re  r   r   )	r-   r.   r/   rV  r   childrR  rP   valr3   r3   r4   visit_Output^  sZ    







zCodeGenerator.visit_Outputc                 C   sF   |    | | | |j| | d | |j| | | d S rK  )r   r   r,   r   r   r.   r  r&  r3   r3   r4   visit_Assign  s    

zCodeGenerator.visit_Assignc                 C   s   |    | }d|_|j| | | | | | |j| | 	| | 
|j| | d |jd k	r| |j| n| d|j  | d | | | | d S )NFz9 = (Markup if context.eval_ctx.autoescape else identity)(
concat(%s)r   )r   rt   rg   rd   r   r   rh   r   r   r   r,   r   r   rI  r   r  r   )r-   r.   r/   r  r3   r3   r4   visit_AssignBlock  s     






zCodeGenerator.visit_AssignBlockc                 C   s   |j dkr(|jr(| jr(| jd |j |j|j}|j dkr|j|}|d k	rj|d tkrj| 	|r| 
d|j||f  d S | 
| d S )Nr=  r   r   r   z-(undefined(name=%r) if %s is missing else %s))r   re   r   r~   r=   rd   r   Z	find_loadr   r   r   )r-   r.   r/   r   r   r3   r3   r4   r     s&    


zCodeGenerator.visit_Namec                 C   sR   |j |j}| d|  |   | dd  |   | d||jf  d S )Nz!if not isinstance(%s, Namespace):r"  z/cannot assign attribute on non-namespace objectz%s[%r])rd   r   r=   r   r   r   attr)r-   r.   r/   r   r3   r3   r4   visit_NSRef  s    zCodeGenerator.visit_NSRefc                 C   s8   | |j}t|tr&| t| n| t| d S r'   )r`  r)   r7   rG   r   strr   )r-   r.   r/   rj  r3   r3   r4   visit_Const  s    
zCodeGenerator.visit_Constc                 C   sF   z|  t||j W n& tjk
r@   |  d|j  Y nX d S )Nz9(Markup if context.eval_ctx.autoescape else identity)(%r))r   r   r`  r)   r
   rg  datar&  r3   r3   r4   visit_TemplateData  s    z CodeGenerator.visit_TemplateDatac                 C   sV   |  d d}t|jD ]"\}}|r.|  d | || q|  |dkrLdpNd d S )N(r   r   r   z,)r   r   r   r$   r,   r-   r.   r/   r   rP   r3   r3   r4   visit_Tuple  s    

zCodeGenerator.visit_Tuplec                 C   sF   |  d t|jD ]"\}}|r*|  d | || q|  d d S )N[r   ]rv  rw  r3   r3   r4   
visit_List  s    

zCodeGenerator.visit_Listc                 C   s`   |  d t|jD ]<\}}|r*|  d | |j| |  d | |j| q|  d d S )N{r   z: r   )r   r   r$   r,   rQ   rO   rw  r3   r3   r4   
visit_Dict  s    


zCodeGenerator.visit_Dictc                    s   t  fdd}|S )Nc                    s   | j jrJ | j jkrJ| d   | |j| | d | |j| n4| d | |j| | d   | |j| | d d S )Nz$environment.call_binop(context, %r, r   ru   %s r   )r<   	sandboxedZintercepted_binopsr   r,   leftrightr&  operatorr3   r4   rV     s    


z$CodeGenerator.binop.<locals>.visitorr6   r  interceptablerV   r3   r  r4   binop  s    zCodeGenerator.binopc                    s   t  fdd}|S )Nc                    s\   | j jr2 | j jkr2| d   | |j| n| d   | |j| | d d S )Nz#environment.call_unop(context, %r, ru  r   )r<   r  Zintercepted_unopsr   r,   r.   r&  r  r3   r4   rV   2  s    
z#CodeGenerator.uaop.<locals>.visitorr  r  r3   r  r4   uaop1  s    zCodeGenerator.uaop+-*/z//z**%and)r  orznot c                 C   s^   |j jrd}n|j jrd}nd}| d|  |jD ]}| || | d q4| d d S )Nz;(context.eval_ctx.volatile and markup_join or unicode_join)Zmarkup_joinZunicode_joinz%s((r   rf  )r)   r*   r   r   r
   r,   )r-   r.   r/   r)  r   r3   r3   r4   visit_ConcatO  s    
zCodeGenerator.visit_Concatc                 C   s>   |  d | |j| |jD ]}| || q|  d d S )Nru  r   )r   r,   rN  ops)r-   r.   r/   opr3   r3   r4   visit_Compare]  s
    

zCodeGenerator.visit_Comparec                 C   s&   |  dt|j   | |j| d S )Nr~  )r   	operatorsr  r,   rN  r&  r3   r3   r4   visit_Operande  s    zCodeGenerator.visit_Operandc                 C   sP   | j jr| d | d | |j| | d|j  | j jrL| d d S )N(await auto_await(zenvironment.getattr(r#  rf  )r<   r   r   r,   r.   ro  r&  r3   r3   r4   visit_Getattri  s    

zCodeGenerator.visit_Getattrc                 C   s   t |jtjr@| |j| | d | |j| | d n^| jjrR| d | d | |j| | d | |j| | d | jjr| d d S )Nry  rz  r  zenvironment.getitem(r   r   rf  )	r7   r   r
   ZSlicer,   r.   r   r<   r   r&  r3   r3   r4   visit_Getitemu  s    




zCodeGenerator.visit_Getitemc                 C   s`   |j d k	r| |j | | d |jd k	r:| |j| |jd k	r\| d | |j| d S )Nr:  )startr,   r   stopr   r&  r3   r3   r4   visit_Slice  s    




zCodeGenerator.visit_Slicec                 C   s8  | j jr| d | | j|j d  | j j|j}|d krT| d|j |j t|dddkrp| d n6t|dddkr| d	 nt|d
ddkr| d |j	d k	r| 
|j	| nJ|jjr| d|j|jf  n*|jjr| d|j  n| d|j  | || | d | j jr4| d d S )Nawait auto_await(ru  zno filter named %rZcontextfilterFTrW  ZevalcontextfilterrX  ZenvironmentfilterrY  zB(context.eval_ctx.autoescape and Markup(concat(%s)) or concat(%s))zMarkup(concat(%s))rm  r   )r<   r   r   rz   r=   getr   r   r   r.   r,   r)   r*   rh   r   r   )r-   r.   r/   r   r3   r3   r4   r     s6    





zCodeGenerator.visit_Filterc                 C   s`   |  | j|j d  |j| jjkr8| d|j |j | |j| | || |  d d S )Nru  zno test named %rr   )	r   r{   r=   r<   r   r   r,   r.   r   r&  r3   r3   r4   r     s    zCodeGenerator.visit_Testc                    s^    fdd} d j   d j   d |   d d S )Nc                      s4   j d k	rj  S dd   d S )Nzcond_expr_undefined(%r)zRthe inline if-expression on %s evaluated to false and no else section was defined.)Zexpr2r,   r   r   r3   r/   r.   r-   r3   r4   write_expr2  s    
z1CodeGenerator.visit_CondExpr.<locals>.write_expr2ru  z if z else r   )r   r,   expr1r9  )r-   r.   r/   r  r3   r  r4   visit_CondExpr  s    


zCodeGenerator.visit_CondExprc                 C   s|   | j jr| d | j jr&| d n
| d | |j| |rJddipLd }| ||| | d | j jrx| d d S )Nr  zenvironment.call(context, zcontext.call(r   r   )r<   r   r   r  r,   r.   r   )r-   r.   r/   rE  r   r3   r3   r4   rF    s    


zCodeGenerator.visit_Callc                 C   s"   |  |jd  | |j| d S )N=)r   rQ   r,   rO   r&  r3   r3   r4   visit_Keyword  s    zCodeGenerator.visit_Keywordc                 C   s&   |  d | |j| |  d d S )NzMarkup(r   r   r,   rN  r&  r3   r3   r4   visit_MarkSafe  s    
zCodeGenerator.visit_MarkSafec                 C   s&   |  d | |j| |  d d S )Nz5(context.eval_ctx.autoescape and Markup or identity)(r   r  r&  r3   r3   r4   visit_MarkSafeIfAutoescape  s    
z(CodeGenerator.visit_MarkSafeIfAutoescapec                 C   s   |  d|j  d S )Nzenvironment.r   r=   r&  r3   r3   r4   visit_EnvironmentAttribute  s    z(CodeGenerator.visit_EnvironmentAttributec                 C   s   |  d|j|jf  d S )Nzenvironment.extensions[%r].%s)r   
identifierr=   r&  r3   r3   r4   visit_ExtensionAttribute  s    z&CodeGenerator.visit_ExtensionAttributec                 C   s   |  | j|j  d S r'   )r   r   r  r&  r3   r3   r4   visit_ImportedName  s    z CodeGenerator.visit_ImportedNamec                 C   s   |  |j d S r'   r  r&  r3   r3   r4   visit_InternalName  s    z CodeGenerator.visit_InternalNamec                 C   s   |  d d S )Nr   )r   r&  r3   r3   r4   visit_ContextReference  s    z$CodeGenerator.visit_ContextReferencec                 C   s   |  | | d S r'   )r   r   r&  r3   r3   r4   visit_DerivedContextReference  s    z+CodeGenerator.visit_DerivedContextReferencec                 C   s   |  d| d S )Ncontinuer   r&  r3   r3   r4   visit_Continue  s    zCodeGenerator.visit_Continuec                 C   s   |  d| d S )Nbreakr   r&  r3   r3   r4   visit_Break  s    zCodeGenerator.visit_Breakc                 C   s:   |  }|j| | | | |j| | | d S r'   )rt   rd   r   r   r   r   r   )r-   r.   r/   scope_framer3   r3   r4   visit_Scope  s
    
zCodeGenerator.visit_Scopec                 C   s   |   }| d|| |f  | d|  | |j| | | |jdd}|j| | 	| | 
|j| | | |   d S )Nr   z
%s.vars = T)rs   )r   r   r   r,   r   r   rt   rd   r   r   r   r   r   r   )r-   r.   r/   r   r  r3   r3   r4   visit_OverlayScope  s    


z CodeGenerator.visit_OverlayScopec              	   C   sp   |j D ]d}| d|j  | |j| z|j|j}W n tjk
rX   d|j_	Y qX t
|j|j| qd S )Nzcontext.eval_ctx.%s = T)optionsr   rQ   r,   rO   r`  r)   r
   rg  r*   setattr)r-   r.   r/   keywordrj  r3   r3   r4   visit_EvalContextModifier   s    
z'CodeGenerator.visit_EvalContextModifierc                 C   sb   |   }|j }| d|  | || |jD ]}| || q2|j| | d|  d S )Nz%s = context.eval_ctx.save()zcontext.eval_ctx.revert(%s))r   r)   saver   r  r   r,   revert)r-   r.   r/   Zold_ctx_nameZ	saved_ctxri  r3   r3   r4   visit_ScopedEvalContextModifier+  s    

z-CodeGenerator.visit_ScopedEvalContextModifier)NFT)F)r	   )N)N)Nr   )Nr   )N)F)N)T)T)F)or^   r_   r`   r]   r   r   rh   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r'  r*  r4  r6  rA  rC  rD  rH  rJ  rO  rP  r   rQ  r   r\  r[  r]  r_  rb  rd  re  rk  rl  rn  r   rp  rr  rt  rx  r{  r}  r  r  Z	visit_AddZ	visit_SubZ	visit_MulZ	visit_DivZvisit_FloorDivZ	visit_PowZ	visit_ModZ	visit_AndZvisit_OrZ	visit_PosZ	visit_NegZ	visit_Notr6   r  r  r  r  r  r  r   r   r  rF  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r3   r3   r3   r4   r      s        
D






5
P	
|&-:K 

)	O	








 

r   )NFT)=rv   collectionsr   	functoolsr   	itertoolsr   r  r   r   Z
markupsafer   r   r  r
   _compatr   r   r   r   r   r   r   
exceptionsr   Z
idtrackingr   r   r   r   r   r   r+   r   utilsr   rV   r   r  hasattrrN   r%  r  execr   SyntaxErrorr  r6   rA   rM   rW   rk   rX   ra   RuntimeErrorrS   ry   rR   rh  r   r   r3   r3   r3   r4   <module>   sz   
     
=