o ˝`W@sUdZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z ej r6ddl Z dd lmZed ejejZed ejejZegd Zegd ZejejejejejejdZ ej!e"ej#ej$fe%d<GdddZ&dS)z8Parse tokens from the lexer into nodes for the compiler.N)nodes)TemplateAssertionError)TemplateSyntaxError)describe_token)describe_token_expr) Environment_ImportInclude _MacroCall) forifblockextendsprintmacroincludefromimportsetwith autoescape)eqneltlteqgtgteq)addsubmuldivfloordivmod _math_nodesc@seZdZdZ   ddddedejedejedejed df d d Zdefd ed eje dej ed dfddZ dejedej ej edfd eje d dfddZ dded eje d dfddZ  ddejej edfd eje d dfddZ ddejej edfd efddZdd eje d ejfddZd ejejej ejffd d!Z "ddej edfd#ed ej ejfd$d%Zd ejejejffd&d'Zd ejfd(d)Zd ejfd*d+Z d ej!fd,d-Z"d ej#fd.d/Z$d ej%fd0d1Z&d ej'fd2d3Z(d4e)d5ed e)fd6d7Z*d ej+fd8d9Z,d ej-fd:d;Z.d ej/fdd?Z2d ej3fd@dAZ4d ej5fdBdCZ6d ej7fdDdEZ8d ej9fdFdGZ:e;j< ddHedIdJd ej=fdKdLZ>e;j< M "  "ddHedIedejej edfdNed ejej?ej=ej ff dOdLZ> M "  "ddHedIedejej edfdNed ejej?ej=ej ff dPdLZ>ddQed ej@fdRdSZAd ej@fdTdUZBd ej@fdVdWZCd ej@fdXdYZDd ej@fdZd[ZEd ej@fd\d]ZFd ej@fd^d_ZGd ej@fd`daZHd ej@fdbdcZId ej@fdddeZJddfed ej@fdgdhZKd ej@fdidjZL " M  "ddkedQedejej edfdled ejej ej@ff dmdnZMd ej fdodpZNd ejOfdqdrZPd4ej@d ej@fdsdtZQd4ej@d ej@fdudvZRd4ej@d ejejSejTffdwdxZUd ej@fdydzZVd ej fd{d|ZWd4ej@d ejXfd}d~ZY "dd4ejej@ded ejej@fddZZd4ej@d ej@fddZ[ ddejej edfd ej ejfddZ\d ej]fddZ^dS)ParserzThis is the central parsing class Jinja uses. It's passed to extensions and can be used to parse expressions or statements. N environmentrsourcenamefilenamestatereturncCsl||_||||||_||_||_d|_i|_|D]}|jD]}|j |j|<q!qd|_ g|_ g|_ dS)NFr) r% _tokenizestreamr'r(closed extensionsiter_extensionstagsparse_last_identifier _tag_stack_end_token_stack)selfr%r&r'r(r) extensiontagr8//usr/lib/python3/dist-packages/jinja2/parser.py__init__3s   zParser.__init__msglinenoexcz te.NoReturncCs$|dur |jjj}||||j|j)zConvenience method that raises `exc` with the message, passed line number or last line number as well as the current name and filename. N)r,currentr<r'r()r5r;r<r=r8r8r9failJs z Parser.failend_token_stack.cCst}|D] }|tt|q|r dtttt|d}nd}|dur*dg}nd|dg}|rN|durE||vrE|d|dn |d|d|jr]|d|jdd|d ||dS) Nz or zUnexpected end of template.zEncountered unknown tag .z\You probably made a nesting mistake. Jinja is expecting this tag, but currently looking for z*Jinja was looking for the following tags: z/The innermost block that needs to be closed is  ) rupdatemaprjoinreprappendr3r?)r5r'r@r<expectedexprscurrently_lookingmessager8r8r9 _fail_ut_eofXs8 zParser._fail_ut_eofcCs|||j|dS)zCalled if the parser encounters an unknown tag. Tries to fail with a human readable error message that could help to identify the problem. N)rMr4)r5r'r<r8r8r9fail_unknown_tagszParser.fail_unknown_tag end_tokenscCs.t|j}|dur|||d||dS)z9Like fail_unknown_tag but for end of template situations.N)listr4rHrM)r5rOr<stackr8r8r9fail_eofs  zParser.fail_eofextra_end_rulescCs,|jjjdvr dS|dur|jj|SdS)zAre we at the end of a tuple?) variable_end block_endrparenTNF)r,r>typetest_any)r5rSr8r8r9 is_tuple_ends zParser.is_tuple_endcCs8|jd7_ttj}tjj|d|j|d|S)zDReturn a new free identifier as :class:`~jinja2.nodes.InternalName`.rfir<)r2object__new__r InternalNameNoder:)r5r<rvr8r8r9free_identifiers zParser.free_identifiercCs,|jj}|jdkr|d|j|j|jd}zs|jtvr6t |d|jjj}|W|r5|j SS|jdkrH| W|rG|j SS|jdkrZ| W|rY|j SS|j |j}|durr||W|rq|j SS|j d}||j|jW|r|j dSdS|r|j ww) zParse a single statement.r'ztag name expectedTparse_callfilterNF)r,r>rWr?r<r3rHvalue_statement_keywordsgetattrpopparse_call_blockparse_filter_blockr.getrN)r5tokenpop_tagfextr8r8r9parse_statementsH          zParser.parse_statementF drop_needlecCsL|jd|jd||}|jjjdkr|||r$t|j|S)aRParse 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. colonrUeof)r,skip_ifexpectsubparser>rWrRnext)r5rOrqresultr8r8r9parse_statementss    zParser.parse_statementscCsft|jj}|jdd}|jdr|}tj|||dS|d}|j ddd}tj ||||dS)zParse an assign statement.T)with_namespaceassignr[N)z name:endsetrq) rwr,r<parse_assign_targetrt parse_tuplerAssign parse_filterry AssignBlock)r5r<targetexpr filter_nodebodyr8r8r9 parse_sets    zParser.parse_setc Cs|jdj}|jdd}|jd|jddd}d}|jd r&|}|jd }|d }t|jj d krrH)r5noderxrlr8r8r9parse_ifs     zParser.parse_ifcCstjt|jjd}g}g}|jjjdkr?|r|jd|}| d| ||jd| | |jjjdks||_ ||_ |jddd|_|S) Nr[rUcommaparamr{)z name:endwithTr|)rWithrwr,r<r>rWrur}set_ctxrHrtargetsvaluesryr)r5rrrrr8r8r9 parse_withs     zParser.parse_withcCsDtjt|jjd}td|g|_|jddd|_ t |gS)Nr[r)zname:endautoescapeTr|) rScopedEvalContextModifierrwr,r<KeywordroptionsryrScoper5rr8r8r9parse_autoescape s zParser.parse_autoescapecCstjt|jjd}|jdj|_|jd|_ |jd|_ |jj j dkr,| d|jddd |_|j rFtd d |jDsF| d |jd |j|S)Nr[r'z name:scopedz name:requiredrzpBlock names in Jinja have to be valid Python identifiers and may not contain hyphens, use an underscore instead.)z name:endblockTr|css2|]}|jD]}t|tjo|jVqqdSN)r isinstance TemplateDatadataisspace).0rchildr8r8r9 :s z%Parser.parse_block..z7Required blocks can only contain comments or whitespacezname:)rBlockrwr,r<rurer'rtscopedrequiredr>rWr?ryrallrr8r8r9 parse_block&s zParser.parse_blockcCs"tjt|jjd}||_|SNr[)rExtendsrwr,r<rtemplaterr8r8r9 parse_extendsDs zParser.parse_extendsrdefaultcCsJ|jjddr |jdr t|jjdk|_|j|S||_|S)Nz name:withz name:without name:contextr) r,r>rXlookrrwre with_contextskip)r5rrr8r8r9parse_import_contextIs zParser.parse_import_contextcCsbtjt|jjd}||_|jjdr(|j dr(d|_ |j dnd|_ | |dS)Nr[z name:ignorez name:missingTF) rIncluderwr,r<rrr>rrignore_missingrrrr8r8r9 parse_includeUs  zParser.parse_includecCsFtjt|jjd}||_|jd|jddj |_ | |dS)Nr[name:asT name_onlyF) rImportrwr,r<rrrur}r'rrrr8r8r9 parse_importas    zParser.parse_importcstjtjjd_jdg_dt ffdd } jr,jdjj j dkrv|r7nFj dd }|j d rLjd |jtd jd rcj dd }j|j |j fnj|j |stjj j dkrunnjdq#tdsd_S)Nr[z name:importr*csBjjjdvrjdrtjjdk_jdSdS)N>rwithoutrrTF)r,r>rerrrwrrr8rr5r8r9 parse_contextns z(Parser.parse_from..parse_contextTrr'r_z4names starting with an underline can not be imported)r=rrF)r FromImportrwr,r<rrrunamesboolr>rWr}r' startswithr?rrtrHhasattrr)r5rraliasr8rr9 parse_fromhs<         zParser.parse_fromcCsg}|_g}|_|jd|jjjdkrK|r|jd|jdd}|d|jdr8| | n|r?| d| ||jjjdks|jddS) NlparenrVrTrrr{z-non-default argument follows default argument) argsdefaultsr,rur>rWr}rrtrHrr?)r5rrrargr8r8r9parse_signatures          zParser.parse_signaturecCsvtjt|jjd}|jjjdkr||ng|_g|_ | }t |tj s.| d|j||_|jddd|_|S)Nr[rz expected call)z name:endcallTr|)r CallBlockrwr,r<r>rWrrrrrCallr?rcryr)r5r call_noder8r8r9ris  zParser.parse_call_blockcCs8tjt|jjd}|jddd|_|jddd|_|S)Nr[T) start_inline)zname:endfilterr|) r FilterBlockrwr,r<rrdryrrr8r8r9rjszParser.parse_filter_blockcCsBtjt|jjd}|jddj|_|||jddd|_ |S)Nr[Tr)z name:endmacror|) rMacrorwr,r<r}r'rryrrr8r8r9 parse_macros  zParser.parse_macrocCs\tjt|jjd}g|_|jjjdkr,|jr|jd|j| |jjjdks|S)Nr[rUr) rOutputrwr,r<r>rWrurHrrr8r8r9 parse_prints zParser.parse_print with_tuplerzte.Literal[True]cCdSrr8)r5rrr8r8r9r}szParser.parse_assign_targetTrzcCrrr8)r5rrrSrzr8r8r9r}scCs|r'|jjdkr'|jd}t|j|jd}tj|j|j|jd}n&|r:|jd}tj |jd|jd}n|rD|j d|d}n| }| d| s`|dt|j|j|S)aParse an assignment target. As Jinja 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. If `with_namespace` is enabled, a namespace assignment may be parsed. dotr'r[storeT) simplifiedrSzcan't assign to )r,rrWrurwrNSRefrer<Namer~ parse_primaryr can_assignr?__name__lower)r5rrrSrzrlattrrr8r8r9r}s&     rcCs|r|S|S)zParse an expression. Per default all expressions are parsed, if the optional `with_condexpr` parameter is set to `False` conditional expressions are not parsed. )parse_condexprparse_or)r5rr8r8r9rszParser.parse_expressioncCsl|jjj}|}|jdr4|}|jdr|}nd}tj||||d}|jjj}|jds|S)Nrrr[)r,r>r<rrtrrCondExpr)r5r<expr1expr2expr3r8r8r9rs      zParser.parse_condexprcCP|jjj}|}|jdr&|}tj|||d}|jjj}|jds|S)Nname:orr[)r,r>r< parse_andrtrOrr5r<leftrightr8r8r9r    zParser.parse_orcCr)Nname:andr[)r,r>r< parse_notrtrAndrr8r8r9r&rzParser.parse_andcCs4|jjdrt|jj}tj||dS|S)Nname:notr[) r,r>rrwr<rNotr parse_compare)r5r<r8r8r9r/s zParser.parse_notcCs|jjj}|}g} |jjj}|tvr&t|j|t ||n4|j dr8|t d|n"|jj drY|j drY|j d|t d|nn|jjj}q |sd|Stj|||dS)NTrinrrnotinr[)r,r>r< parse_math1rW_compare_operatorsrwrHrOperandrtrrrCompare)r5r<rops token_typer8r8r9r5s*      zParser.parse_comparecCj|jjj}|}|jjjdvr3t|jjj}t|j|}||||d}|jjj}|jjjdvs|S)N)rrr[)r,r>r< parse_concatrWr#rwr5r<rclsrr8r8r9rL   zParser.parse_math1cCsj|jjj}|g}|jjjdkr$t|j|||jjjdkst|dkr.|dStj ||dS)Ntilderrr[) r,r>r< parse_math2rWrwrHlenrConcat)r5r<rr8r8r9r Ws    zParser.parse_concatcCr )N)rr r!r"r[)r,r>r< parse_powrWr#rwr r8r8r9rarzParser.parse_math2cCs^|jjj}|}|jjjdkr-t|j|}tj|||d}|jjj}|jjjdks|S)Npowr[)r,r>r< parse_unaryrWrwrPowrr8r8r9rls   zParser.parse_pow with_filtercCs|jjj}|jjj}|dkrt|jtj|d|d}n|dkr2t|jtj|d|d}n| }| |}|rB| |}|S)NrFr[r) r,r>rWr<rwrNegrPosr parse_postfixparse_filter_expr)r5rr r<rr8r8r9rvs      zParser.parse_unarycCs|jj}|jdkr9|jdvrtj|jdv|jd}n|jdvr(tjd|jd}n tj|jd|jd}t|j|S|jdkrqt|j|jg}|j}|jjjdkre| |jjjt|j|jjjdksQtjd ||d}|S|jd vrt|jtj|j|jd}|S|jd krt|j|j d d }|j d |S|jdkr| }|S|jdkr|}|S|dt||j|S)Nr')truefalseTrueFalse)rrr[)noneNoneloadstring)integerfloatrT)explicit_parenthesesrVlbracketlbracez unexpected )r,r>rWrerConstr<rrwrHrFr~ru parse_list parse_dictr?r)r5rlrbufr<r8r8r9rsH            zParser.parse_primaryrr'c sjjj}|r j}n|rj}n dtjffdd }g}d} |r(jd|r.n| |jjj dkr>d}nnjjj}q |s[|rM|dS|s[ dt jjtj |d |d S) aWorks 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. r*cs jddS)NFr)rr8r5r8r9r1s z!Parser.parse_tuple..parseFTrrzExpected an expression, got r"r[)r,r>r<rrrExprrurYrHrWr?rTuple) r5rrrSr'r<r1ris_tupler8r.r9r~s:       zParser.parse_tuplecCsv|jd}g}|jjjdkr-|r|jd|jjjdkrn|||jjjdks|jdtj||jdS)Nr(rbracketrr[) r,rur>rWrHrrListr<)r5rlitemsr8r8r9r+s   zParser.parse_listcCs|jd}g}|jjjdkr@|r|jd|jjjdkrn!|}|jd|}|tj|||jd|jjjdks|jdtj ||jdS)Nr)rbracerrrr[) r,rur>rWrrHrPairr<Dict)r5rlr4keyrer8r8r9r,s    zParser.parse_dictcCsD |jjj}|dks|dkr||}n |dkr||}n |Sq)NTrr(r)r,r>rWparse_subscript parse_callr5rr r8r8r9rs   zParser.parse_postfixcCs^ |jjj}|dkr||}n|dkr!|jjjdkr!||}n |dkr+||}n |Sq)NTpiper'isr)r,r>rWrre parse_testr:r;r8r8r9rs    zParser.parse_filter_exprcCs&t|j}|jdkrB|jj}t|j|jdkr#tj||jd|jdS|jdkr/|d|jtj |j|jd}tj ||d|jdS|jdkrg}|jjjdkrf|rX|j d | | |jjjdksP|j dt|d krw|d }n tj|d|jd}tj ||d|jdS|d |jdS) Nrr'r"r[r%zexpected name or numberr(r2rrrzexpected subscript expression)rwr,rWr>rGetattrrer<r?r*GetitemrurHparse_subscribedrr0)r5rrl attr_tokenrrr8r8r9r9#s2           zParser.parse_subscriptcCs|jjj}|jjjdkrt|jdg}n|}|jjjdkr"|St|j|g}|jjjdkr7|dn|jjjdvrF||n|d|jjjdkrlt|j|jjjdvrf||n |dn|dtj|d|iS)Nrr)r2rr<) r,r>r<rWrwrrHrSlice)r5r<rrr8r8r9rABs*        zParser.parse_subscribedc s~jdg}g}d}d}d}dtddffdd }jjjdkr|r3jdjjjdkr3njjjd krN||duoB|dutj}n\jjjd kre||dutj}nEjjjd krjjd kr||dujjj}j d }| t j |||j dn||duo|duo| | d}jjjdks#jd||||fS)NrFrr*cs|s djdSdS)Nz+invalid syntax for function call expression)r?r<)rr5rlr8r9ensurejsz&Parser.parse_call_args..ensurerVrrrr'r{rr[T)r,rurr>rWrwrrrerrHrrr<) r5rkwargsdyn_args dyn_kwargs require_commarEr8rer8rDr9parse_call_argsbsB           " zParser.parse_call_argscCs0|jj}|\}}}}tj||||||jdSr)r,r>rJrrr<)r5rrlrrFrGrHr8r8r9r:szParser.parse_callrc Cs|jjjdks |rg|st|j|jd}|j}|jjjdkr7t|j|d|jdj7}|jjjdks |jjjdkrG|\}}}}ng}g}d}}tj|||||||j d}d}|jjjdks |s |S)Nr<r'rrBrr[F) r,r>rWrwrurerJrFilterr<) r5rrrlr'rrFrGrHr8r8r9rs(   zParser.parse_filterc Cs*t|j}|jjdrt|jd}nd}|jdj}|jjjdkr;t|j|d|jdj7}|jjjdks$d}}g}|jjjdkrQ|\}}}}n+|jjjdvrz|jjd d d sz|jjd rm| d | } | | } | g}ng}t j |||||||jd}|rt j||jd}|S)NrTFr'rrBr>r'r&r)rr#r%r(rrrzname:isz'You cannot chain multiple tests with isr[)rwr,r>rrurerWrJrXr?rrrTestr<r) r5rrlnegatedr'rGrHrFrarg_noder8r8r9r>s>      zParser.parse_testcshggj}|dur|j|d fdd }z|jr|jj}|jdkr:|jr4|tj|j|jdt |jn]|jdkrSt |j||j dd|j d nD|jd kr|t |j|durx|jjj |rxW|durw|j SS|}t|tr|n||j d ntd |js|W|dur|j S|dur|j ww)Nr*cs<rdj}tjdd|ddd=dSdS)Nrr[)r<rHrrr[r data_bufferr8r9 flush_datas  z#Parser.subparse..flush_datarr[variable_beginTrrT block_beginrUzinternal parsing error)r*N)rHr4r,r>rWrerrr<rwr~rurXrhrprrPextendAssertionError)r5rOadd_datarQrlr`r8rOr9rvsR             zParser.subparsecCs"tj|dd}||j|S)z0Parse the whole template into a `Template` node.rr[)rTemplatervset_environmentr%)r5rxr8r8r9r1 s z Parser.parse)NNNr)NN)F)..)TFNF)T)FTNF)_r __module__ __qualname____doc__strtOptionalr:rintTyper?r3r0rMrNrRrrYrr^raUnionr_rpryrrrrrrrrrrrrrrrr rrrrrrrr rrrirrjrrrrtypingoverloadrr}rr/rrrrrrrr rrrrr~r+r7r,rrr?r@r9rArJrr:rr>rvrWr1r8r8r8r9r$.sx   )      "       .     *       $ B    1   +  1r$)'r[rbr]r$r exceptionsrrlexerrr TYPE_CHECKINGtyping_extensionster%rTypeVarrrr rrr frozensetrfrAddSubMulDivFloorDivModr#r7r\r`r/__annotations__r$r8r8r8r9s2