Rc @sdZddlmZddlmZmZddlmZmZddl m Z m Z e dddd d d d d ddg Z e ddddddgZdefdYZdS(s jinja2.parser ~~~~~~~~~~~~~ Implements the template parser. :copyright: (c) 2010 by the Jinja Team. :license: BSD, see LICENSE for more details. i(tnodes(tTemplateSyntaxErrortTemplateAssertionError(tdescribe_tokentdescribe_token_expr(tnexttimaptfortiftblocktextendstprinttmacrotincludetfromtimporttsetteqtnetlttlteqtgttgteqtParsercBs$eZdZd5d5d5dZd5edZdZd5dZd5d5dZ d5dZ d5dZ dZ e d Zd Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZee d5dZedZdZ dZ!dZ"dZ#dZ$dZ%d Z&d!Z'd"Z(d#Z)d$Z*d%Z+d&Z,ed'Z-d(Z.e ed5e d)Z/d*Z0d+Z1d,Z2d-Z3d.Z4d/Z5d0Z6e d1Z7d2Z8d5d3Z9d4Z:RS(6sThis is the central parsing class Jinja2 uses. It's passed to extensions and can be used to parse expressions or statements. cCs||_|j|||||_||_||_t|_i|_x8|jD]*}x!|j D]}|j |j|;sisUnexpected end of template.sEncountered unknown tag '%s'.s_You probably made a nesting mistake. Jinja is expecting this tag, but currently looking for %s.s-Jinja was looking for the following tags: %s.s4The innermost block that needs to be closed is '%s'.t (textendRRtjoinR,tappendR$R1(R&Rtend_token_stackR.texpectedtexprstcurrently_lookingtmessage((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt _fail_ut_eof5s*          cCs|j||j|S(sCalled if the parser encounters an unknown tag. Tries to fail with a human readable error message that could help to identify the problem. (R=R%(R&RR.((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytfail_unknown_tagTscCs>t|j}|dk r+|j|n|jd||S(s9Like fail_unknown_tag but for end of template situations.N(tlistR%R,R7R=(R&t end_tokensR.tstack((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytfail_eof[s cCs<|jjjdkrtS|dk r8|jjj|StS(sAre we at the end of a tuple?t variable_endt block_endtrparen(RCRDREN(RR-ttypetTrueR,ttest_anyR(R&textra_end_rules((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt is_tuple_endbs  cCsE|jd7_tjtj}tjj|d|jd||S(sDReturn a new free identifier as :class:`~jinja2.nodes.InternalName`.isfi%dR.(R#tobjectt__new__Rt InternalNametNodeR+(R&R.trv((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytfree_identifierjs cCs|jj}|jdkr1|jd|jn|jj|jt}z|jt kryt |d|jjjS|jdkr|j S|jdkr|j S|j j|j}|dk r||S|jjt}|j|j|jWd|r|jjnXdS(sParse a single statement.Rstag name expectedtparse_tcalltfilterN(RR-RFR1R.R$R7tvalueRGt_statement_keywordstgetattrtparse_call_blocktparse_filter_blockRtgetR,tpopRR>(R&ttokentpop_tagtext((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytparse_statementqs(      cCsn|jjd|jjd|j|}|jjjdkrT|j|n|rjt|jn|S(sRParse multiple statements into a list until one of the end tokens is reached. This is used to parse the body of statements as it also parses template data if appropriate. The parser checks first if the current token is a colon and skips it if there is one. Then it checks for the block end and parses until if one of the `end_tokens` is reached. Per default the active token in the stream at the end of the call is the matched end token. If this is not wanted `drop_needle` can be set to `True` and the end token is removed. tcolonRDteof(Rtskip_iftexpecttsubparseR-RFRBR(R&R@t drop_needletresult((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytparse_statementss cCsPt|jj}|j}|jjd|j}tj||d|S(sParse an assign statement.tassignR.(RRR.tparse_assign_targetRbt parse_tupleRtAssign(R&R.ttargetR3((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_sets   c Cs|jjdj}|jdd }|jjd|jdtdd }d}|jjdrv|j}n|jjd}|j d}t |jj d krg}n|j dd t }t j||||||d |S(sParse a for loop.sname:forRIsname:int with_condexprsname:recursivesname:ifs name:endfors name:elsetendforRdR.(sname:in(sname:recursiveN(s name:endfors name:else(s name:endfor(RRbR.RhRiRR,Ratparse_expressionRfRRTRGRtFor(R&R.Rktiterttestt recursivetbodytelse_((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_fors  cCstjd|jjdj}}x|jdt|_|jd|_ t |j}|jdrtjd|jj j}|g|_ |}q(n3|jdr|jd dt |_ n g|_ Pq(|S( sParse an if construct.R.sname:ifRms name:elifs name:elses name:endifRd(s name:elifs name:elses name:endif(s name:endif(RtIfRRbR.RiRRrRfRtRR-RuRG(R&tnodeReR[tnew_node((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytparse_ifs"%    cCstjdt|jj}|jjdj|_|jjd|_ |jj j dkrp|j dn|j d dt|_|jjd|j|S( NR.Rs name:scopedtsubspBlock names in Jinja have to be valid Python identifiers and may not contain hyphens, use an underscore instead.s name:endblockRdsname:(s name:endblock(RtBlockRRR.RbRTRRatscopedR-RFR1RfRGRt(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_blockscCs1tjdt|jj}|j|_|S(NR.(RtExtendsRRR.Rottemplate(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_extendsscCsh|jjjddr[|jjjdr[t|jjdk|_|jjn ||_|S(Ns name:withs name:withouts name:contexttwith( RR-RHtlookRrRRTt with_contexttskip(R&Rxtdefault((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytparse_import_contexts  cCstjdt|jj}|j|_|jjjdrv|jj jdrvt |_ |jj dn t |_ |j|t S(NR.s name:ignores name:missingi(RtIncludeRRR.RoRR-RrRRGtignore_missingRRR(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_includes  cCsetjdt|jj}|j|_|jjd|jdt j |_ |j |t S(NR.sname:ast name_only(RtImportRRR.RoRRbRhRGRRkRR(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_imports cstjdtjjj_jjdg_fd}xjrwjjdnjj j dkrT|rPnj dt }|j jdrjd|jd tnjjd rj dt }jj|j |j fnjj|j |sMjj j dkrUPqUq[Pq[td st_jjdnS( NR.s name:importcs]jjjdkrYjjjdrYtjjdk_jjtSt S(NRtwithouts name:context(swithR( RR-RTRRrRRRRGR((RxR&(s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_contexts  tcommaRRt_s4names starting with an underline can not be importedR0sname:asR(Rt FromImportRRR.RoRRbtnamesR-RFRhRGRt startswithR1RRaR7thasattrRR(R&RRktalias((RxR&s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_from s6       cCsg|_}g|_}|jjdx|jjjdkr|r[|jjdn|jdt}|jd|jj dr|j |j n|j |q-W|jjddS(NtlparenRERRtparamRg( targstdefaultsRRbR-RFRhRGtset_ctxRaR7Ro(R&RxRRtarg((s1/usr/lib/python2.7/site-packages/jinja2/parser.pytparse_signature0s   cCstjdt|jj}|jjjdkrC|j|ng|_g|_ |j |_ t |j tj s|jd|jn|jddt|_|S(NR.Rs expected calls name:endcallRd(s name:endcall(Rt CallBlockRRR.R-RFRRRRoRRt isinstancetCallR1RfRGRt(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRW>s  cCsRtjdt|jj}|jddt|_|j ddt|_ |S(NR.t start_inlinesname:endfilterRd(sname:endfilter( Rt FilterBlockRRR.t parse_filterR,RGRSRfRt(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRXLs   cCs_tjdt|jj}|jdtj|_|j||j ddt|_ |S(NR.Rs name:endmacroRd(s name:endmacro( RtMacroRRR.RhRGRRRfRt(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_macroSs    cCsytjdt|jj}g|_xK|jjjdkrt|jr[|jjdn|jj|j q*W|S(NR.RDR( RtOutputRRR.R-RFRbR7Ro(R&Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt parse_print[s  cCs|r9|jjd}tj|jdd|j}n:|rZ|jdtd|}n |j}|j d|j s|j d|j j j|jn|S(sParse an assignment target. As Jinja2 allows assignments to tuples, this function can parse all allowed assignment targets. Per default assignments to tuples are parsed, that can be disable however by setting `with_tuple` to `False`. If only assignments to names are wanted `name_only` can be set to `True`. The `extra_end_rules` parameter is forwarded to the tuple parsing function. RtstoreR.t simplifiedRIscan't assign to %r(RRbRtNameRTR.RiRGt parse_primaryRt can_assignR1t __class__t__name__tlower(R&t with_tupleRRIR[Rk((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRhds !     cCs|r|jS|jS(sParse an expression. Per default all expressions are parsed, if the optional `with_condexpr` parameter is set to `False` conditional expressions are not parsed. (tparse_condexprtparse_or(R&Rm((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRo|s cCs|jjj}|j}xs|jjdr|j}|jjdr]|j}nd}tj|||d|}|jjj}qW|S(Nsname:ifs name:elseR.( RR-R.RRaRR,RtCondExpr(R&R.texpr1texpr2texpr3((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs  cCsk|jjj}|j}xI|jjdrf|j}tj||d|}|jjj}qW|S(Nsname:orR.(RR-R.t parse_andRaRtOr(R&R.tlefttright((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs  cCsk|jjj}|j}xI|jjdrf|j}tj||d|}|jjj}qW|S(Nsname:andR.(RR-R.t parse_notRaRtAnd(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs  cCsJ|jjjdr@t|jj}tj|jd|S|jS(Nsname:notR.( RR-RrRR.RtNotRt parse_compare(R&R.((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRscCs4|jjj}|j}g}x|jjj}|tkrnt|j|jtj ||jn|jj dr|jtj d|jn`|jjj dr|jj j dr|jj d|jtj d|jnP|jjj}q$|s|Stj||d|S(Nsname:intinsname:notitnotinR.(RR-R.t parse_addRFt_compare_operatorsRR7RtOperandRaRrRRtCompare(R&R.R3topst token_type((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs&   """cCs{|jjj}|j}xY|jjjdkrvt|j|j}tj||d|}|jjj}qW|S(NtaddR.(RR-R.t parse_subRFRRtAdd(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs   cCs{|jjj}|j}xY|jjjdkrvt|j|j}tj||d|}|jjj}qW|S(NR{R.(RR-R.t parse_concatRFRRtSub(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs   cCs|jjj}|jg}x9|jjjdkrYt|j|j|jq!Wt|dkrt|dStj |d|S(NttildeiiR.( RR-R.t parse_mulRFRR7tlenRtConcat(R&R.R((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs cCs{|jjj}|j}xY|jjjdkrvt|j|j}tj||d|}|jjj}qW|S(NtmulR.(RR-R.t parse_divRFRRtMul(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs   cCs{|jjj}|j}xY|jjjdkrvt|j|j}tj||d|}|jjj}qW|S(NtdivR.(RR-R.tparse_floordivRFRRtDiv(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs   cCs{|jjj}|j}xY|jjjdkrvt|j|j}tj||d|}|jjj}qW|S(NtfloordivR.(RR-R.t parse_modRFRRtFloorDiv(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs   cCs{|jjj}|j}xY|jjjdkrvt|j|j}tj||d|}|jjj}qW|S(NtmodR.(RR-R.t parse_powRFRRtMod(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs   cCs{|jjj}|j}xY|jjjdkrvt|j|j}tj||d|}|jjj}qW|S(NtpowR.(RR-R.t parse_unaryRFRRtPow(R&R.RR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs   cCs|jjj}|jjj}|dkrXt|jtj|jtd|}nF|dkrt|jtj |jtd|}n |j }|j |}|r|j |}n|S(NR{R.R( RR-RFR.RRtNegRRtPosRt parse_postfixtparse_filter_expr(R&t with_filterRR.Rx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs  !  ! cCs|jj}|jdkr|jdkrNtj|jdkd|j}nH|jdkrxtjdd|j}ntj|jd d|j}t |jne|jd kr7t |j|jg}|j}x<|jjjd kr|j |jjjt |jqWtjd j |d|}n|jdkrqt |jtj|jd|j}n|jdkrt |j|j dt }|jjdnY|jdkr|j}n;|jdkr|j}n|jdt||j|S(NRttruetfalseRGRR.tnoneR,tloadtstringttintegertfloatRtexplicit_parenthesesREtlbrackettlbracesunexpected '%s'(RRsTruesFalse(RsTrue(RsNone(Rsfloat(RR-RFRTRtConstR.R,RRR7R6RiRGRbt parse_listt parse_dictR1R(R&R[RxtbufR.((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyR s<    !  c sjjj}|r!j}n!|r3j}nfd}g}t}xm|rjjjdnj|r}Pn|j|jjj dkrt }nPjjj}qQ|s|r|dS|sj dt jjqnt j|dd|S(sWorks like `parse_expression` but if multiple expressions are delimited by a comma a :class:`~jinja2.nodes.Tuple` node is created. This method could also return a regular expression instead of a tuple if no commas where found. The default parsing mode is a full tuple. If `simplified` is `True` only names and literals are parsed. The `no_condexpr` parameter is forwarded to :meth:`parse_expression`. Because tuples do not require delimiters and may end in a bogus comma an extra hint is needed that marks the end of a tuple. For example for loops support tuples between `for` and `in`. In that case the `extra_end_rules` is set to ``['name:in']``. `explicit_parentheses` is true if the parsing was triggered by an expression in parentheses. This is used to figure out if an empty tuple is a valid expression or not. csjdtS(NRm(RoR((R&(s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt\sRis Expected an expression, got '%s'RR.(RR-R.RRoRRbRJR7RFRGR1RRtTuple( R&RRmRIRR.R"Rtis_tuple((R&s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRiBs2    cCs|jjd}g}x^|jjjdkrx|rI|jjdn|jjjdkrbPn|j|jqW|jjdtj|d|jS(NRtrbracketRR.( RRbR-RFR7RoRtListR.(R&R[titems((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRyscCs|jjd}g}x|jjjdkr|rI|jjdn|jjjdkrbPn|j}|jjd|j}|jtj||d|jqW|jjdtj |d|jS(NRtrbraceRR_R.( RRbR-RFRoR7RtPairR.tDict(R&R[RtkeyRT((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs  &cCsbx[|jjj}|dks*|dkr<|j|}q|dkrZ|j|}qPq|S(NtdotRR(RR-RFtparse_subscriptt parse_call(R&RxR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs cCsx|jjj}|dkr0|j|}q|dkrc|jjjdkrc|j|}q|dkr|j|}qPq|S(NtpipeRtisR(RR-RFRRTt parse_testR(R&RxR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs ! cCst|j}|jdkr|jj}t|j|jdkretj||jdd|jS|jdkr|jd|jntj |jd|j}tj ||dd|jS|jdkrg}xE|jjjdkr|r|jj d n|j |j qW|jj dt|d krM|d }ntj|dd|j}tj ||dd|jS|jd |jdS( NRRRR.Rsexpected name or numberRRRiisexpected subscript expression(RRRFR-RtGetattrRTR.R1RtGetitemRbR7tparse_subscribedRR(R&RxR[t attr_tokenRR((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs.    cCsR|jjj}|jjjdkr=t|jdg}n;|j}|jjjdkrb|St|j|g}|jjjdkr|jdn8|jjjdkr|j|jn |jd|jjjdkr2t|j|jjjdkr"|j|jq?|jdn |jdtj d||S(NR_RRR.(srbracketscomma(srbracketscomma( RR-R.RFRR,RoR7RtSlice(R&R.RRx((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs*        c s'jjdg}g}d}}t}fd}xjjjdkr|rjjdjjjdkrPqnjjjdkr||dko|dktjj}njjjdkr||dktjj}n||dko0|dkjjjdkrjjjdkrjjj }jj d j} |j t j || d | jn|| |j jt}qCWjjd|dkr||||fSt j|||||d jS( NRcs |sjdjndS(Ns+invalid syntax for function call expression(R1R.(R3(R&R[(s1/usr/lib/python2.7/site-packages/jinja2/parser.pytensures RERRRRRgiR.(RRbR,RR-RFRRoRRTRR7RtKeywordR.RGR( R&RxRtkwargstdyn_argst dyn_kwargst require_commaR RRT((R&R[s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRsF       c Csx |jjjdks|r|s4t|jn|jjd}|j}xC|jjjdkrt|j|d|jjdj7}qRW|jjjdkr|jd\}}}}ng}g}d}}tj ||||||d|j }t }qW|S(NRRRt.RR.( RR-RFRRbRTRR,RtFilterR.R( R&RxRR[RRR R R ((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRs"  !  c Cst|j}|jjjdr:t|jt}nt}|jjdj}xC|jjjdkrt|j|d|jjdj7}qXWd}}g}|jjjdkr|j d\}}}}nn|jjjdkrF|jjj d d d  rF|jjjdr4|j dn|j g}ng}tj||||||d|j}|rtj|d|j}n|S(Nsname:notRRRRRRRRRs name:elsesname:orsname:andsname:iss'You cannot chain multiple tests with isR.(snamesstringsintegersfloatslparenslbracketslbrace(RRR-RrRGRRbRTRFR,RRHR1RoRtTestR.R( R&RxR[tnegatedRR R R R((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyR,s6   !    csggj}|dk r4|jj|nfd}zUxG|jr|jj}|jdkr|jr|tj|jd|j nt |jqL|jdkrt |j||j dt |jj dqL|jdkr|t |j|dk r8|jjj|r8S|j}t|trcj|n j||jj dqLtd qLW|Wd|dk r|jjnXS( Ncs;r7dj}jtjd|2ndS(NiR.(R.R7RR(R.(Rtt data_buffer(s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt flush_dataSs tdataR.tvariable_beginRmRCt block_beginRDsinternal parsing error(R7R,R%RR-RFRTRt TemplateDataR.RRiRGRbRHR^RR?R5tAssertionErrorRZ(R&R@tadd_dataRR[RO((RtRs1/usr/lib/python2.7/site-packages/jinja2/parser.pyRcKsD            cCs/tj|jdd}|j|j|S(s0Parse the whole template into a `Template` node.R.i(RtTemplateRctset_environmentR(R&Re((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyR"{sN(;Rt __module__t__doc__R,R+RR1R=R>RBRJRPR^RRfRlRvRzR~RRRRRRRWRXRRRGRhRoRRRRRRRRRRRRRRRRiRRRRRRRRRRcR"(((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyRsp              '          "6     /   0N(Rtjinja2Rtjinja2.exceptionsRRt jinja2.lexerRRtjinja2._compatRRt frozensetRURRKR(((s1/usr/lib/python2.7/site-packages/jinja2/parser.pyt s