B ףa @srdZddlZddlmZddlmZddlmZddl m Z ddl m Z ddlmZdd lmZd d lmZd d lmZd d lmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlm Z d dl!m"Z"ej#r ddl$Z%d dl&m'Z'ej(dej)dej*fdZ+dddddd d!d"d#Z,e+e+d$d%d&Z-e.ej)d'ej/d(gdfd)d*d+Z0e.ej)d'ej1d(gdfd)d,d-Z2dFej3d0ej4e.ej4e.ej4ej5e6e6ej4e.d1d2d3Z7ej*e6d4d5d6Z8ej9ej:ej9e.ej;e.d7d8d9ZGd=d>d>e?Z@Gd?d@d@e"ZAGdAdBdBe"ZBGdCdDdDeCZDGdEd'd'e"ZEdS)Gz0Compiles nodes from the parser into Python code.N)contextmanager)update_wrapper)StringIO)chain) iskeyword)escape)Markup)nodes)TemplateAssertionError)Symbols)VAR_LOAD_ALIAS)VAR_LOAD_PARAMETER)VAR_LOAD_RESOLVE)VAR_LOAD_UNDEFINED) EvalContext) Optimizer)_PassArg)concat) NodeVisitor) EnvironmentF.)boundz==z!=>z>=.new_func)r ExprtAnyrcastr)r r/r-)r r. optimizeconst+s  r4r"r#)opr!cs"tdtjtddfdd }|S)Nr")r$r%r&r!cs|jjrN|jjkrN|dd||j||d||j|n8|d||j||dd||j||ddS)Nz environment.call_binop(context, z, ( )) environment sandboxedZintercepted_binopswriter+leftright)r$r%r&)r5r-r.visitor<s   z_make_binop..visitor)r4r BinExprr#)r5r>r-)r5r. _make_binop;sr@cs"tdtjtddfdd }|S)Nr")r$r%r&r!cs`|jjr6|jjkr6|dd||j|n|d||j||ddS)Nzenvironment.call_unop(context, z, r6r8)r9r:Zintercepted_unopsr;r+r%)r$r%r&)r5r-r.r>Ts z_make_unop..visitor)r4r UnaryExprr#)r5r>r-)r5r. _make_unopQs rBFTr)r%r9namefilenamestream defer_init optimizedr!cCsHt|tjstd|||||||}|||dkrD|jSdS)z+Generate the python source for a node tree.z Can't compile non template nodesN) isinstancer Template TypeErrorZcode_generator_classr+rEgetvalue)r%r9rCrDrErFrG generatorr-r-r.generatees   rM)valuer!cCs|dks|tks|tkrdSt|ttttttt hkr:dSt|t t t t hkr`tdd|DSt|tkrtdd|DSdS)z)Does the node have a safe representation?NTcss|]}t|VqdS)N) has_safe_repr).0vr-r-r. sz has_safe_repr..css"|]\}}t|ot|VqdS)N)rO)rPkrQr-r-r.rRsF)NotImplementedEllipsistypeboolintfloatcomplexrangestrrtuplelistset frozensetalldictitems)rNr-r-r.rO}s rO)r namesr!cCs@t|}yx|D]}||qWWntk r8YnX|jS)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 rdr>r%r-r-r.find_undeclareds rhc@s*eZdZejejejfddddZdS)MacroRefN)r%r!cCs||_d|_d|_d|_dS)NF)r%accesses_calleraccesses_kwargsaccesses_varargs)r$r%r-r-r.__init__szMacroRef.__init__) __name__ __module__ __qualname__r1Unionr Macro CallBlockrmr-r-r-r.risric@sdeZdZdZdeejdejeddddZddddZ de dd d d Z ddd dZ e Z dS)r#z&Holds compile time information for us.N)r)parentlevelr!cCs~||_||_|dkr4t|d|_d|_d|_d|_n(t|j|d|_|j|_|j|_|j|_d|_d|_d|_ d|_ d|_ dS)N)ruF) r)rtr symbolsrequire_output_checkbufferblocktoplevel rootlevel loop_frame block_frame soft_frame)r$r)rtrur-r-r.rms  zFrame.__init__)r!cCs2ttt|j}|j|j|j |_|S)z!Create a copy of the current one.) r1r3r#object__new__ __class____dict__updatervcopy)r$rvr-r-r.rs z Frame.copyF)isolatedr!cCs&|rt|j|jjddSt|j|S)zReturn an inner frame.r )ru)r#r)rvru)r$rr-r-r.innersz Frame.innercCs|}d|_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 and conditional expressions. FT)rr{r~)r$rr-r-r.softsz Frame.soft)NN)F)rnrorp__doc__rr1OptionalrXrmrrWrr__copy__r-r-r-r.r#s. c@seZdZdZdS)rfz?Exception used by the `UndeclaredNameVisitor` to signal a stop.N)rnrorprr-r-r-r.rfsrfc@sTeZdZdZddddZejddddZejddd d Z ej ddd d Z dS) DependencyFinderVisitorz.A visitor that collects filter and test calls.N)r!cCst|_t|_dS)N)r_filterstests)r$r-r-r.rmsz DependencyFinderVisitor.__init__)r%r!cCs|||j|jdS)N) generic_visitraddrC)r$r%r-r-r. visit_Filters z$DependencyFinderVisitor.visit_FiltercCs|||j|jdS)N)rrrrC)r$r%r-r-r. visit_Tests z"DependencyFinderVisitor.visit_TestcCsdS)zStop visiting at blocks.Nr-)r$r%r-r-r. visit_Block sz#DependencyFinderVisitor.visit_Block) rnrorprrmr FilterrTestrBlockrr-r-r-r.rs rc@sJeZdZdZejeddddZej ddddZ ej ddd d Z dS) rezA 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. N)rdr!cCst||_t|_dS)N)r_rdrg)r$rdr-r-r.rms zUndeclaredNameVisitor.__init__)r%r!cCsJ|jdkr8|j|jkr8|j|j|j|jkrFtn|j|jdS)Nload)ctxrCrdrgrrfdiscard)r$r%r-r-r. visit_Names  z UndeclaredNameVisitor.visit_NamecCsdS)zStop visiting a blocks.Nr-)r$r%r-r-r.r!sz!UndeclaredNameVisitor.visit_Block) rnrorprr1Iterabler\rmr Namerrrr-r-r-r.resrec@seZdZdZdS) 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. N)rnrorprr-r-r-r.r%src @sJeZdZUddejeejeejejeeddddZe edd d Z ee d d d dZ edddZ eddddZdeeddddZddddZde ddddZdeejejddddZeddd d!Zdeeejejdd"d#d$Zejejedd%d&d'Zedd(d)d*Zdeejeje dd,d-d.Zdejeje dd/d0d1Zdejejejej feejej!eej"fdd2d3d4Z#ejejdd5d6d7Z$eddd8d9Z%deedd:d;d<Z&deeed?d@dAZ'eedBdCdDZ(ejej)ej*feej+ee,fdEdFdGZ-e,eddHdIdJZ.ejedKdLdMZ/eeddNdOZ0dddPdQZ1edddRdSZ2dddTdUZ3eddVdWdXZ4eddVdYdZZ5ddd[d\Z6edd]d^Z7edd_d`Z8eeddadbZ9eedVdcddZ:dddedfZ;edddgdhZej?eddEdkdlZ@ejAeddEdmdnZBejCeddEdodpZDejejEejFfeddEdqdrZGejEeddEdsdtZHejFeddEdudvZIejJeddEdwdxZKejLeddEdydzZMej)eddEd{d|ZNej*eddEd}d~ZOejPeddEddZQejReddEddZSejTeddEddZUGdddejVZWeXej"ej"dddZYdZZejeWe[d<eWdddZ\ejej"edddZ]ej^eeWedddZ_ej^eeWddddZ`ej^eeWddddZaejbeddEddZcejdeddEddZeejfeddEddZgejheddEddZiejjeddEddZkejleddEddZmejneddEddZoej+eddEddZpejqeddEddZrejseddEddZteudZveudZweudZxeudZyeudZzeudZ{eudZ|eudZ}eudZ~edZedZedZeejeddEddZeejeddEddZejeddEddZeejeddEddZeejeddEddZejeddEddZeejejej feeejddddÄZeejeddEddńZeej eddEddDŽZeejeddEddɄZedejeeddʜdd̄ZejeddEdd΄ZejeddEddЄZejeddEdd҄ZejeddEddԄZejeddEddքZejeddEdd؄ZejeddEddڄZejeddEdd܄ZejeddEddބZejeddEddZejeddEddZejeddEddZejeddEddZejeddEddZejeddEddZdS)r"NFTr)r9rCrDrErFrGr!cCs|dkrt}||_||_||_||_d|_||_d|_|rFt||_i|_ i|_ d|_ d|_ d|_ i|_i|_g|_d|_d|_d|_d|_d|_d|_g|_g|_dg|_dS)NFrr Tcontext)rr9rCrDrEZcreated_block_contextrFr(rimport_aliasesblocksextends_so_farhas_known_extends code_linenorr debug_info_write_debug_info _new_lines _last_line _first_write_last_identifier _indentation _assign_stack_param_def_block_context_reference_stack)r$r9rCrDrErFrGr-r-r.rm-s8  zCodeGenerator.__init__)r!cCs |jdk S)N)r()r$r-r-r.rGvszCodeGenerator.optimizedz te.NoReturn)msglinenor!cCst|||j|jdS)z*Fail with a :exc:`TemplateAssertionError`.N)r rCrD)r$rrr-r-r.fail|szCodeGenerator.failcCs|jd7_d|jS)zGet a new unique identifier.r Zt_)r)r$r-r-r.temporary_identifiersz"CodeGenerator.temporary_identifier)r&r!cCs ||_||jddS)z7Enable buffering for the frame from that point onwards.z = []N)rrx writeline)r$r&r-r-r.rxs zCodeGenerator.buffer)r&force_unescapedr!cCs|s|jjrl|d||d|jd||d||d|jd|dS|jjr|d|jddS|d|jddS)z(Return the buffer contents of the frame.zif context.eval_ctx.autoescape:zreturn Markup(concat(z))zelse:zreturn concat(r8N)r)r*rindentrxoutdent autoescape)r$r&rr-r-r.return_buffer_contentss  z$CodeGenerator.return_buffer_contentscCs|jd7_dS)zIndent by one.r N)r)r$r-r-r.rszCodeGenerator.indentr )stepr!cCs|j|8_dS)zOutdent by step.N)r)r$rr-r-r.rszCodeGenerator.outdent)r&r%r!cCs0|jdkr|d|n||jd|dS)z%Yield or write into the frame buffer.Nzyield z.append()rxr)r$r&r%r-r-r. start_writes zCodeGenerator.start_writecCs|jdk r|ddS)z1End the writing process started by `start_write`.Nr8)rxr;)r$r&r-r-r. end_writes zCodeGenerator.end_write)sr&r%r!cCs$|||||||dS)z4Simple shortcut for start_write + write + end_write.N)rr;r)r$rr&r%r-r-r. simple_writes  zCodeGenerator.simple_write)r r&r!cCsBy(|dx|D]}|||qWWntk r<YnXdS)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)rr+r)r$r r&r%r-r-r. blockvisits   zCodeGenerator.blockvisit)xr!cCs|jrp|jsR|jd|j|j|j7_|jdk rR|j|j|jfd|_d|_|jd|jd|_|j|dS)z&Write a string into the output stream. NFz r) rrrEr;rrrappendr)r$rr-r-r.r;s zCodeGenerator.writer)rr%extrar!cCs|||||dS)z!Combination of newline and write.N)newliner;)r$rr%rr-r-r.rs zCodeGenerator.writeline)r%rr!cCs:t|jd||_|dk r6|j|jkr6|j|_|j|_dS)z/Add one or more newlines before the next write.r N)maxrrrr)r$r%rr-r-r.rszCodeGenerator.newline)r%r& extra_kwargsr!c Cstddtdd|jD|pdD}x$|jD]}|d|||q0W|sx$|jD]}|d|||qZW|dk rx*|D]\}}|d|d|qW|jr|d||j||r|jdk r|d n |d x8|jD].}||j d ||j ||dqW|dk rbx,|D] \}}||d |dq>W|jdk r|d ||j||d n |dn$|jdk r|d||j|dS)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. css|]}ttt|VqdS)N)is_python_keywordr1r3r\)rPrSr-r-r.rRsz*CodeGenerator.signature..css|] }|jVqdS)N)key)rPrr-r-r.rRsr-z, N=z, *z , **dict({z, **{z: z}, **r8}z, **) anyrr'argsr;r+rcZdyn_argsZ dyn_kwargsrrN) r$r%r&rZkwarg_workaroundargkwargrrNr-r-r. signaturesF                 zCodeGenerator.signature)r r!c Cst}x|D]}||q Wx|j|jdf|j|jdffD]\}}}xt|D]}||krh|||<|d||||d|d|d||d||d|d ||d ||d |d d d|d||qPWqr%Zid_maprdZ dependencyrCr-r-r.pull_dependenciess.       zCodeGenerator.pull_dependenciesc Csg}x|jjD]z\}\}}|tkr(q|tkrR||d|d|dq|tkrp||d|q|tkr| |qt dqW|r|d |ddS)Nz = r6r8zunknown load instructionz = missing) rvloadsrcrrrget_resolve_funcr rrNotImplementedErrorjoin)r$r&undefstargetactionparamr-r-r. enter_frameEs"  zCodeGenerator.enter_frame)r&with_python_scoper!cCsB|s>g}x|jjD]}||qW|r>|d|ddS)Nz = z = missing)rvrrrr)r$r&rrrr-r-r. leave_frameUs zCodeGenerator.leave_frameasync ) async_value sync_valuer!cCs|jjr |S|S)N)r9is_async)r$rrr-r-r. choose_async]szCodeGenerator.choose_async)rCr!cCs|d|S)Nzdef )r)r$rCr-r-r.func`szCodeGenerator.func)r%r&r!c Cs|}|j|t|}d}t}g}xNt|jD]@\}}|jdkrL|}|jdkrb||j| |j |jq6Wt |j d} d| kr|dk ry|j |t|jWqtk r|d|jYqXn| |jdd|_d| krd|kr| |jdd|_d| krDd|krD| |jdd|_d |_|j|||d d d |d ||||||||xt|jD]\}}|j |j} |d| d|y|j |t|j} Wn6tk r*|| d|jd|jdYnX|| d|| ||| | qW|!|"|j ||j#|dd|j$|dd| ||fS)z/Dump the function def of a macro or call block.Ncaller)r'varargs)rr'rzhWhen defining macros or call blocks the special "caller" argument must be omitted or be given a default.Tr'rFmacror6z, z):zif z is missing:z = undefined("parameter z was not provided", name=r8z = )r)r)%rrv analyze_noderir_ enumeraterrCrrrefrhbodydefaultslen IndexErrorrrdeclare_parameterrjrkrlrwrrrrrxrpush_parameter_definitionsr+mark_parameter_storedrpop_parameter_definitionsrrr) r$r%r& macro_refZexplicit_callerZskip_special_paramsridxrrgrdefaultr-r-r. macro_bodycsn      $   "  zCodeGenerator.macro_body)rr&r!c Csrddd|jjD}t|jdd}t|jjdkr>|d7}|d|d |d |jd|jd|jd dS) z.rCNr ,zMacro(environment, macro, z, (z), z, context.eval_ctx.autoescape)) rr%rgetattrrr;rkrlrj)r$rr&Z arg_tuplerCr-r-r. macro_defs zCodeGenerator.macro_def)r%r!cCs*d|j}|jdk r&|d|j}|S)z.Return a human readable position for the node.zline Nz in )rrC)r$r%rr-r-r.positions  zCodeGenerator.positioncCs*ddd|jD}d|dS)Nz, css |]\}}|d|VqdS)z: Nr-)rPrCrr-r-r.rRsz3CodeGenerator.dump_local_context..{r)rrvZ dump_storesrc)r$r&Zitems_kvr-r-r.dump_local_contextsz CodeGenerator.dump_local_contextcCs,|d|d|d|ddS)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.undefinedzcond_expr_undefined = Undefinedzif 0: yield NoneN)r)r$r-r-r. write_commonss   zCodeGenerator.write_commonscCs|j|jdS)aQPushes 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)rrrvZdump_param_targets)r$r&r-r-r.rsz(CodeGenerator.push_parameter_definitionscCs|jdS)z+Pops the current parameter definitions set.N)rpop)r$r-r-r.rsz'CodeGenerator.pop_parameter_definitions)rr!cCs|jr|jd|dS)zMarks a parameter in the current parameter definitions as stored. This will skip the enforced undefined checks. rN)rr)r$rr-r-r.rsz#CodeGenerator.mark_parameter_storedcCs|j|dS)N)rr)r$rr-r-r.push_context_referencesz$CodeGenerator.push_context_referencecCs|jdS)N)rr)r$r-r-r.pop_context_referencesz#CodeGenerator.pop_context_referencecCs |jdS)Nr)r)r$r-r-r.get_context_refszCodeGenerator.get_context_refcCs |jd}|dkrdS|dS)Nrrresolvez.resolve)r)r$rr-r-r.rs zCodeGenerator.get_resolve_funccCs|d||dS)Nz .derived(r8)rr)r$r&r-r-r.derive_contextszCodeGenerator.derive_contextcCs|js dS||jdkS)z4Checks if a given target is an undeclared parameter.Fr)r)r$rr-r-r.parameter_is_undeclaredsz%CodeGenerator.parameter_is_undeclaredcCs|jtdS)z+Pushes a new layer for assignment tracking.N)rrr_)r$r-r-r.push_assign_trackingsz"CodeGenerator.push_assign_trackingcCs|j}|js|js|jr |s$dSdd|D}t|dkrtt|}|j |}|jrv| d|d|dS|jr| d|d|dS| d|d|n||jr| d n|jr| d n | d xBt |D]6\}}|r| d |j |}| |d |qW| d|js|js|rt|dkrf| d|ddn"d tt|}| d|ddS)zoPops the topmost level for assignment tracking and updates the context variables if necessary. NcSs g|]}|dddkr|qS)Nr _r-)rPrr-r-r. sz5CodeGenerator.pop_assign_tracking..r z _loop_vars[z] = z _block_vars[z context.vars[z_loop_vars.update({z_block_vars.update({zcontext.vars.update({z, z: z})zcontext.exported_vars.add(rr8zcontext.exported_vars.update((z)))rrr}r|rzrnextiterrvrrrr;rmapr)r$r&varsZ public_namesrCrr names_strr-r-r.pop_assign_tracking sB          z!CodeGenerator.pop_assign_trackingc Cs$|dkstdt|j|j}ddlm}m}|jjrDt||}nt|}| d| dd ||j rtdnd}| t jdk }xD|t jD]4} | j|jkr|d | jd | j| |j| j<qWx|t jD]v} | j|jkr| j} ||j| <} d | kr<| d d\} }| d | d |d| q| d| d| qW| d|j|j |dd|ddd||t|}dt|jdkr|j d}| |d|j!|d|_"|_#|o|j$ |_%|r| d|&||'|j|(|j||j)|dd|*|r|j$s`|| d||jjs~| dn$| d|| d|*|*d|j$ x|j+D]\}} | |d|d|d| d||t|}d|_,t| jd }d|kr@|j d}| |dd!|krr|j d!}| |d"|d#|d$|j!| ||_-| d%|&||'| j|(| j||j)|dd|*qWd d&d'|jD}|j d(|d)ddd* d+d'|j.D}| d,|dS)-Nzno root frame allowedr )exportedasync_exportedz%from __future__ import generator_stopzfrom jinja2.runtime import z, rz, environment=environmentzblock z defined twice.zfrom z import z as zimport zname = rootz(context, missing=missingz):)rr$)r$z = TemplateReference(context)Tzparent_template = None)rzif parent_template is not None:z4yield from parent_template.root_render_func(context)z=async for event in parent_template.root_render_func(context):z yield eventZblock_)r$superrz = context.super(z, block_r8z_block_vars = {}css|]}|d|VqdS)z: block_Nr-)rPrr-r-r.rRsz/CodeGenerator.visit_Template..z blocks = {r&css |]\}}|d|VqdS)rNr-)rPrSrQr-r-r.rRsz debug_info = )/AssertionErrorrr9rCZruntimerrrrrrrFfindr Extendsfind_allrrrr ImportedName importnamerrrsplitrrrr#rhrrvrrrzr{rrwrrrrrrcr}ryr)r$r%r&r)rrZexported_namesZenvenvZ have_extendsryimport_impaliasmoduleobjrrCr}rgZ blocks_kv_strZ debug_kv_strr-r-r.visit_Template9s                       zCodeGenerator.visit_TemplatecCsd}|jr8|jrdS|jdkr8|d||d7}|jrJ||}n|}|jr|d|j d|||d|j d|| |j j s|j dkr|d |j d |d |n@||d |j d |d |||d|| | |dS)z.Call a block and register it for the template.rNzif parent_template is None:r zif len(context.blocks[z]) <= 1:z+raise TemplateRuntimeError("Required block z not found")zyield from context.blocks[z][0](r8zfor event in context.blocks[z):event)rzrrrrscopedrrrequiredrCrr9rrxrr)r$r%r&rurr-r-r.rs8     zCodeGenerator.visit_BlockcCs|js|d|j|jdkrV|js6|d||d|jrNtn||d|| |j || d|j d|d||d ||j rd |_|jd 7_d S) zCalls the extender.z,cannot use extend from a non top-level scoperzif parent_template is not None:z5raise TemplateRuntimeError("extended multiple times")z+parent_template = environment.get_template(z, r8z9for name, parent_block in parent_template.blocks.items():z8context.blocks.setdefault(name, []).append(parent_block)Tr N)rzrrrrrrrrr+templater;rCr{)r$r%r&r-r-r. visit_Extendss(      zCodeGenerator.visit_ExtendscCsp|jr|d|d}t|jtjrVt|jjtr>d}qnt|jjt t frnd}nt|jtj tj frnd}|d|d|| |j||d|jd|jr||d ||d ||d |d }|jr||d ||dn$|jjr,|dn|dd}|s\||d|||jrl|dS)zHandles includes.ztry:Zget_or_select_templateZ get_templateZselect_templateztemplate = environment.r6z, r8zexcept TemplateNotFound:rzelse:FzUfor event in template.root_render_func(template.new_context(context.get_all(), True, z)):zGfor event in (await template._get_default_module_async())._body_stream:z6yield from template._get_default_module()._body_streamTr#N)Zignore_missingrrrHr&r ConstrNr\r]r^TupleListr+r;rCr with_contextrrr9rr)r$r%r& func_nameZskip_event_yieldr-r-r. visit_IncludesJ       zCodeGenerator.visit_IncludecCs||dd||j||d|jd|jrld|d}||d||dn|d |dd dS) Nzawait zenvironment.get_template(z, z).Z make_moduleZ_asyncz(context.get_all(), True, r8Z_get_default_modulez (context))r;rr+r&rCr+r)r$r%r&f_namer-r-r._import_common9szCodeGenerator._import_commoncCsl||j|jd||jr6|d|jd||||jrh|jdsh|d|jddS)zVisit regular imports.z = z context.vars[z] = rzcontext.exported_vars.discard(r8N)rrvrrrzr;r/ startswith)r$r%r&r-r-r. visit_ImportHs  zCodeGenerator.visit_Importc s|||d||g}g}x|jD]}t|trH|\}}n|}|j|d|d|dj|d| d| |d|}|j|d|d |d | j r0| ||d s0| |q0W|r\t|d kr2|d }|d|dj|n*dfdd|D}|d|d|rt|d kr|d|d d n"dtt|} |d| ddS)zVisit named imports.zincluded_template = z = getattr(included_template, z , missing)zif z is missing:z9the template {included_template.__name__!r} (imported on z%) does not export the requested name z = undefined(fz, name=r8rr rz context.vars[z] = z, c3s$|]}|dj|VqdS)z: N)rvr)rPrC)r&r-r.rRysz1CodeGenerator.visit_FromImport..zcontext.vars.update({z})zcontext.exported_vars.discard(z)context.exported_vars.difference_update((z))N)rr;r/rdrHr]rrvrrrrrzrr0rrr r) r$r%r&Z var_namesZdiscarded_namesrCrmessageZnames_kvrr-)r&r.visit_FromImportSsD          zCodeGenerator.visit_FromImportc Cs|}d|_|}|}|jpRdt|jdddkpRtdd|tjD}d}|rh|j d}|j j |dd |j r|j j |d d |j r|}|j j |d d |||d |j |||||d d||j||d||dd|d||d|j ||j ||d||d||j||d|j|dd|jr||dd|||||j|_|r||dx<|tjD],} | jdkr| jdkr|d| jqW|j r4|} || d||d d|||j||r||d|d|ddn |d|j r||d|jr|d nB|jj r|s|d!||j!||jj r|s|d"|j r|d"|jr|d#n||r(d$nd||||d%|"|j#||j rp|| d&||j||jo|j d|j r|d| d||||"|j |||||jrd|$|||%||||d'd(|jj r.|d!||j!||jj rP|d"|d)|&||j'r|j'd*(|j j)dS)+NTloop)r)only)r4css|] }|jVqdS)N)r$)rPryr-r-r.rRsz*CodeGenerator.visit_For..r)Z for_branchelsetestz(fiter):z async for zfor z in zauto_aiter(fiter)Zfiter:zif zyield )rz%(reciter, loop_render_func, depth=0):z = missingstorez8Can't assign to special loop variable in for-loop targetz = 1z, ZAsyncz LoopContext(r6Zreciterz auto_aiter(r8z&, undefined, loop_render_func, depth):z , undefined):z_loop_vars = {}z = 0zawait zloop(z, loop)r)*rr| recursiverhiter_child_nodesrrr rrvrrelse_r7rrrrrrr+rr;rrrxrrrCrrr9rr rrrrrrdifference_updateZstores) r$r%r&r|Z test_frameZ else_frameZ extended_loopZloop_refZloop_filter_funcrCZiteration_indicatorr-r-r. visit_Fors                           zCodeGenerator.visit_ForcCs|}|d|||j||d|||j||xP|j D]F}|d|||j||d|||j||qRW|j r|d|||j ||dS)Nzif r8zelif zelse:) rrr+r7r;rrrrelif_r=)r$r%r&Zif_framer@r-r-r.visit_Ifs&       zCodeGenerator.visit_IfcCs||||\}}||jrR|jds>|d|jd|d|jd||j|jd| ||dS)Nrzcontext.exported_vars.add(r8z context.vars[z] = z = ) rrrzrCr0r;rrvrr)r$r%r&Z macro_framerr-r-r. visit_Macro%s zCodeGenerator.visit_MacrocCsR|||\}}|d|||||||j|j|dd||dS)Nz caller = T)forward_caller)rrrr visit_Callcallr)r$r%r&Z call_framerr-r-r.visit_CallBlock/s    zCodeGenerator.visit_CallBlockcCsh|}|j|||||||j||||||j || || |dS)N) rrvrrrxrrrrfilterrr)r$r%r&Z filter_framer-r-r.visit_FilterBlock7s     zCodeGenerator.visit_FilterBlockcCs|}|j|||xDt|j|jD]2\}}||||| d|||q.W| |j || |dS)Nz = ) rrvrrziptargetsvaluesrr+r;rrr)r$r%r&Z with_framerexprr-r-r. visit_WithBs    zCodeGenerator.visit_WithcCs||||j|dS)N)rr+r%)r$r%r&r-r-r.visit_ExprStmtNs zCodeGenerator.visit_ExprStmtc@s4eZdZUejejdefed<ejeed<dS)zCodeGenerator._FinalizeInfo.constsrcN)rnrorpr1rCallabler\__annotations__r-r-r-r. _FinalizeInfoRs rS)rNr!cCst|S)zThe default finalize function if the environment isn't configured with one. Or, if the environment has one, this is called on that function's output for constants. )r\)rNr-r-r._default_finalizeVszCodeGenerator._default_finalize _finalizecsjdk rjSj}d}jjrd}jjtjdtjdtjdit}d}|dkr|t j t j dfdd }n2||d }|dkrt j t j dfd d } ||_jS) aBuild 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. Nzenvironment.finalize(rzcontext.eval_ctxr9)rNr!cs |S)Nr-)rN)r env_finalizer-r.finalizesz.CodeGenerator._make_finalize..finalizez, csj|S)N)r9)rN)rrVr$r-r.rWs) rUrTr9rWrr eval_contextgetfrom_objr1r2rS)r$rWrPpass_argr-)rrVr$r._make_finalize`s&    zCodeGenerator._make_finalize)groupr!cCs tt|S)zGiven a group of constant values converted from ``Output`` child nodes, produce a string to write to the template module source. )rr)r$r]r-r-r._output_const_reprsz CodeGenerator._output_const_repr)r%r&rWr!cCs:||j}|jjrt|}t|tjr0t|S||S)aCTry 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)rrrHr TemplateDatar\rO)r$r%r&rWrOr-r-r._output_child_to_consts  z$CodeGenerator._output_child_to_constcCsL|jjr|dn|jjr(|dn |d|jdk rH||jdS)zXOutput extra source code before visiting a child of an ``Output`` node. z1(escape if context.eval_ctx.autoescape else str)(zescape(zstr(N)r)r*r;rrP)r$r%r&rWr-r-r._output_child_pres    zCodeGenerator._output_child_precCs"|d|jdk r|ddS)zWOutput extra source code after visiting a child of an ``Output`` node. r8N)r;rP)r$r%r&rWr-r-r._output_child_posts  z CodeGenerator._output_child_postc Cs|jr"|jrdS|d||}g}x|jD]}y,|jsVt|tjsVt | |||}Wn&tj t fk r| |w6YnX|rt|dt r|d |q6| |gq6W|jdk rt|dkr||jdn||jd|x|D]}t|t rR||}|jdkrB|d|n||dnb|jdkrl|d|n ||||||||||||||jdk r |dq W|jdk r||t|dkrdnd |jr|dS) Nzif parent_template is None:rr z.append(z .extend((zyield rr8z)))rwrrrr\r rOrHr` Impossiblera Exceptionrr^rxrr^rrbr+rcr;r) r$r%r&rWrchildrOitemvalr-r-r. visit_OutputsV               zCodeGenerator.visit_OutputcCsF|||||j||d||j|||dS)Nz = )rrr+rr;r%r)r$r%r&r-r-r. visit_Assigns   zCodeGenerator.visit_AssigncCs||}d|_|j|||||||j|| || |j || d|j dk r||j |n| d|jd| d||||dS)NFz9 = (Markup if context.eval_ctx.autoescape else identity)(zconcat(r8)rrrwrvrrrxrrrr+rr;rGrrr)r$r%r&r}r-r-r.visit_AssignBlocks         zCodeGenerator.visit_AssignBlockc Cs|jdkr4|js|js|jr4|jr4|jd|j|j|j}|jdkr|j |}|dk rv|dt krv| |r| d|jd|d|ddS| |dS) Nr:rrrz(undefined(name=z) if z is missing else r8) rrzr|r}rrrCrvrZ find_loadrrr;)r$r%r&rrr-r-r.r6s     zCodeGenerator.visit_NamecCsV|j|j}|d|d||d|||d|jddS)Nzif not isinstance(z , Namespace):zMraise TemplateRuntimeError("cannot assign attribute on non-namespace object")rr)rvrrCrrrattr)r$r%r&rr-r-r. visit_NSRefOszCodeGenerator.visit_NSRefcCs8||j}t|tr&|t|n|t|dS)N)r_r)rHrYr;r\r)r$r%r&rhr-r-r. visit_Const]s  zCodeGenerator.visit_ConstcCsJy|t||jWn*tjk rD|d|jdYnXdS)Nz6(Markup if context.eval_ctx.autoescape else identity)(r8)r;rr_r)r rddata)r$r%r&r-r-r.visit_TemplateDatads z CodeGenerator.visit_TemplateDatacCsZ|dd}x0t|jD]"\}}|r0|d|||qW||dkrPdnddS)Nr6rz, rz,)r8)r;rrcr+)r$r%r&rrgr-r-r. visit_Tuplels  zCodeGenerator.visit_TuplecCsJ|dx0t|jD]"\}}|r,|d|||qW|ddS)Nrz, r)r;rrcr+)r$r%r&rrgr-r-r. visit_Listus   zCodeGenerator.visit_ListcCsd|dxJt|jD]<\}}|r,|d||j||d||j|qW|ddS)Nrz, z: r)r;rrcr+rrN)r$r%r&rrgr-r-r. visit_Dict}s   zCodeGenerator.visit_Dict+-*/z//z**%andorznot cCsd|jjrd}n|jjrd}nd}||dx$|jD]}||||dq8W|ddS)Nz8(markup_join if context.eval_ctx.volatile else str_join)Z markup_joinZstr_joinz((z, z)))r)r*rr;r r+)r$r%r&r,rr-r-r. visit_Concats  zCodeGenerator.visit_ConcatcCsB|d||j|x|jD]}|||q W|ddS)Nr6r8)r;r+rLZops)r$r%r&r5r-r-r. visit_Compares   zCodeGenerator.visit_ComparecCs*|dt|jd||j|dS)Nr7)r; operatorsr5r+rL)r$r%r&r-r-r. visit_OperandszCodeGenerator.visit_OperandcCsT|jjr|d|d||j||d|jd|jjrP|ddS)Nz(await auto_await(zenvironment.getattr(z, r8z)))r9rr;r+r%rl)r$r%r&r-r-r. visit_Getattrs  zCodeGenerator.visit_GetattrcCst|jtjr@||j||d||j||dn^|jjrR|d|d||j||d||j||d|jjr|ddS)Nrrz(await auto_await(zenvironment.getitem(z, r8z))) rHrr Slicer+r%r;r9r)r$r%r&r-r-r. visit_Getitems      zCodeGenerator.visit_GetitemcCs`|jdk r||j||d|jdk r:||j||jdk r\|d||j|dS)Nr8)startr+r;stopr)r$r%r&r-r-r. visit_Slices     zCodeGenerator.visit_Slice)r%r& is_filterr!ccs|jjr|d|r@||j|jd|jj|j}n(||j|jd|jj|j}|dkr|js|r~dnd}|d|d|jd|j t j dt j d t jd it |}|dk r||d dV||||d |jjr |d dS) Nzawait auto_await(r6rGr7zNo z named rrzcontext.eval_ctxr9z, r8)r9rr;rrCrYrr~rrrrrXrZr)r$r%r&rrZ type_namer[r-r-r._filter_test_commons*       z!CodeGenerator._filter_test_commonc Cs|||dx|jdk r*||j|nX|jjrP|d|jd|jdn2|jjrn|d|jdn|d|jdWdQRXdS)NTz(Markup(concat(z.)) if context.eval_ctx.autoescape else concat(z))zMarkup(concat(zconcat(r8)rr%r+r)r*r;rxr)r$r%r&r-r-r.rs zCodeGenerator.visit_Filterc Cs,|||d||j|WdQRXdS)NF)rr+r%)r$r%r&r-r-r.rszCodeGenerator.visit_Testcslddfdd }djdjd|ddS)N)r!cs8jdk rjdSdddS)Nz1cond_expr_undefined("the inline if-expression on z6 evaluated to false and no else section was defined."))Zexpr2r+r;rr-)r&r%r$r-r. write_expr2s  z1CodeGenerator.visit_CondExpr..write_expr2r6z if z else r8)rr;r+Zexpr1r7)r$r%r&rr-)r&r%r$r.visit_CondExprs   zCodeGenerator.visit_CondExpr)r%r&rCr!cCs|jjr|d|jjr&|dn |d||j||rJddind}|jr\ddini}|jrnddini}|r|j|f|n|s|rt |f|}| ||||d|jjr|ddS)Nzawait auto_await(zenvironment.call(context, z context.call(rZ _loop_varsZ _block_varsr8) r9rr;r:r+r%r|r}rrbr)r$r%r&rCrZ loop_kwargsZ block_kwargsr-r-r.rD0s"     zCodeGenerator.visit_CallcCs"||jd||j|dS)Nr)r;rr+rN)r$r%r&r-r-r. visit_KeywordGszCodeGenerator.visit_KeywordcCs&|d||j||ddS)NzMarkup(r8)r;r+rL)r$r%r&r-r-r.visit_MarkSafeMs zCodeGenerator.visit_MarkSafecCs&|d||j||ddS)Nz6(Markup if context.eval_ctx.autoescape else identity)(r8)r;r+rL)r$r%r&r-r-r.visit_MarkSafeIfAutoescapeRs z(CodeGenerator.visit_MarkSafeIfAutoescapecCs|d|jdS)Nz environment.)r;rC)r$r%r&r-r-r.visit_EnvironmentAttributeYsz(CodeGenerator.visit_EnvironmentAttributecCs|d|jd|jdS)Nzenvironment.extensions[z].)r; identifierrC)r$r%r&r-r-r.visit_ExtensionAttribute^sz&CodeGenerator.visit_ExtensionAttributecCs||j|jdS)N)r;rr)r$r%r&r-r-r.visit_ImportedNamecsz CodeGenerator.visit_ImportedNamecCs||jdS)N)r;rC)r$r%r&r-r-r.visit_InternalNamefsz CodeGenerator.visit_InternalNamecCs|ddS)Nr)r;)r$r%r&r-r-r.visit_ContextReferenceisz$CodeGenerator.visit_ContextReferencecCs|||dS)N)r;r)r$r%r&r-r-r.visit_DerivedContextReferencensz+CodeGenerator.visit_DerivedContextReferencecCs|d|dS)Ncontinue)r)r$r%r&r-r-r.visit_ContinuesszCodeGenerator.visit_ContinuecCs|d|dS)Nbreak)r)r$r%r&r-r-r. visit_BreakvszCodeGenerator.visit_BreakcCs:|}|j|||||j|||dS)N)rrvrrrrr)r$r%r& scope_framer-r-r. visit_Scopeys   zCodeGenerator.visit_ScopecCs|}||d||||d||j||||jdd}|j|| || |j || || dS)Nz = z.vars = T)r)rrrr+rrrrvrrrrrr)r$r%r&rrr-r-r.visit_OverlayScopes     z CodeGenerator.visit_OverlayScopec Csxxr|jD]h}|d|jd||j|y|j|j}Wntjk r^d|j_ YqXt |j|j|qWdS)Nzcontext.eval_ctx.z = T) optionsrrr+rNr_r)r rdr*setattr)r$r%r&keywordrhr-r-r.visit_EvalContextModifiers z'CodeGenerator.visit_EvalContextModifiercCsl|}|j}||d|||x|jD]}|||q6W|j||d|ddS)Nz = context.eval_ctx.save()zcontext.eval_ctx.revert(r8)rr)Zsaverrrr+Zrevert)r$r%r&Z old_ctx_nameZ saved_ctxrfr-r-r.visit_ScopedEvalContextModifiers    z-CodeGenerator.visit_ScopedEvalContextModifier)NFT)F)r )N)N)Nr)Nr)N)F)rr)N)F)rnrorpr1rr\TextIOrWrmpropertyrGrXrrr#rxrrrr Noderrrrrr;rrrqCallrrMappingr2rrrrrrrrrsr)rirrrrrrrrrrrrrrrrrIr"rrrr'Includer-ImportZ FromImportr/r1r3Forr?IfrArBrFZ FilterBlockrHWithrMZExprStmtrN NamedTuplerS staticmethodrTrUrRr\r^r0rarbrcZOutputriAssignrjZ AssignBlockrkrrZNSRefrmr(rnr`rprqr*rrDictrsr@Z visit_AddZ visit_SubZ visit_MulZ visit_DivZvisit_FloorDivZ visit_PowZ visit_ModZ visit_AndZvisit_OrrBZ visit_PosZ visit_NegZ visit_Notr4ZConcatr{Comparer|ZOperandr~ZGetattrrZGetitemrrrrIteratorrrrZCondExprrrDKeywordrZMarkSaferZMarkSafeIfAutoescaperZEnvironmentAttributerZExtensionAttributerrrZ InternalNamerZContextReferencerZDerivedContextReferencerContinuerBreakrZScoperZ OverlayScoperZEvalContextModifierrZScopedEvalContextModifierrr-r-r-r.r",s "A  ,4+Q   .u++4  2    0 O     '  )NFT)Frtypingr1 contextlibr functoolsrior itertoolsrrrrZ markupsaferrrr exceptionsr Z idtrackingr r rrrrr(rutilsrrr>r TYPE_CHECKINGZtyping_extensionster9rTypeVarrQr2rr}r4r\r?r@rArBrIrrrWrMrOrrSetrhrir# RuntimeErrorrfrrererr"r-r-r-r.sd                    " & S