U aW @sUdZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z ej rlddl Z dd lmZed ejejZed ejejZed d ddddddddddg ZeddddddgZejejejejejejdZ ej!e"ej#ej$fe%d<Gd d!d!Z&dS)"z8Parse tokens from the lexer into nodes for the compiler.N)nodes)TemplateAssertionError)TemplateSyntaxError)describe_token)describe_token_expr) Environment_ImportInclude _MacroCallforifblockZextendsprintmacroincludefromimportsetwith autoescapeeqneltZlteqgtZgteq)addsubmuldivfloordivmod _math_nodesc @s eZdZdZddeejeejeejeddddZdefeeje ej eddd d Z ejeej ej ed feje dd d dZdeeje ddddZdejej ed feje ddddZdejej ed fedddZdeje ejdddZejejej ejfdddZdej ed feej ejdd d!Zejejejfdd"d#Zejdd$d%Zejdd&d'Z ej!dd(d)Z"ej#dd*d+Z$ej%dd,d-Z&ej'dd.d/Z(e)ee)d0d1d2Z*ej+dd3d4Z,ej-dd5d6Z.ej/dd7d8Z0e1dd9d:d;Z2ej3ddd?Z6ej7dd@dAZ8ej9ddBdCZ:e;je;jdeeejej ed feejej?ej=ej fdIdKdGZ>deej@dLdMdNZAej@ddOdPZBej@ddQdRZCej@ddSdTZDej@ddUdVZEej@ddWdXZFej@ddYdZZGej@dd[d\ZHej@dd]d^ZIej@dd_d`ZJdeej@dadbdcZKej@ddddeZLdeeejej ed feejej ej@fdfdgdhZMej ddidjZNejOddkdlZPej@ej@d9dmdnZQej@ej@d9dodpZRej@ejejSejTfd9dqdrZUej@ddsdtZVej ddudvZWej@ejXd9dwdxZYdejej@eejej@dydzd{ZZej@ej@d9d|d}Z[dejej ed fej ejd~ddZ\ej]dddZ^dS)ParserzThis is the central parsing class Jinja uses. It's passed to extensions and can be used to parse expressions or statements. Nr) environmentsourcenamefilenamestatereturncCsl||_||||||_||_||_d|_i|_|D]}|jD]}|j |j|<qBq8d|_ g|_ g|_ dS)NFr) r" _tokenizestreamr$r%closed extensionsZiter_extensionstagsparse_last_identifier _tag_stack_end_token_stack)selfr"r#r$r%r& extensiontagr4NC:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-8gbwd15f\jinja2\parser.py__init__3s  zParser.__init__z te.NoReturn)msglinenoexcr'cCs(|dkr|jjj}||||j|jdS)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)currentr8r$r%)r1r7r8r9r4r4r5failJs  z Parser.fail.)r$end_token_stackr8r'cCst}|D]}|tt|q |r@dtttt|d}nd}|dkrTdg}nd|dg}|r|dk r||kr|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  ) rupdatemaprjoinreprappendr/r;)r1r$r<r8expectedexprsZcurrently_lookingmessager4r4r5 _fail_ut_eofXs0  zParser._fail_ut_eof)r$r8r'cCs|||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)rHr0)r1r$r8r4r4r5fail_unknown_tagszParser.fail_unknown_tag) end_tokensr8r'cCs.t|j}|dk r|||d||dS)z9Like fail_unknown_tag but for end of template situations.N)listr0rDrH)r1rJr8stackr4r4r5fail_eofs  zParser.fail_eof)extra_end_rulesr'cCs,|jjjdkrdS|dk r(|jj|SdS)zAre we at the end of a tuple?) variable_end block_endrparenTNF)r)r:typetest_any)r1rNr4r4r5 is_tuple_ends zParser.is_tuple_end)r8r'cCs8|jd7_ttj}tjj|d|j|d|S)zDReturn a new free identifier as :class:`~jinja2.nodes.InternalName`.rfir8)r.object__new__r InternalNameNoder6)r1r8rvr4r4r5free_identifiers zParser.free_identifierr'cCs|jj}|jdkr |d|j|j|jd}z|jt kr^t |d|jjj}|WrS|jdkrt| W\S|jdkr| WFS|j |j}|dk r||W$S|jd}||j|jW5|r|jXdS) zParse a single statement.r$ztag name expectedTZparse_callfilterNF)r)r:rRr;r8r/rDvaluepop_statement_keywordsgetattrparse_call_blockparse_filter_blockr+getrI)r1tokenZpop_tagfextr4r4r5parse_statements*         zParser.parse_statementF)rJ drop_needler'cCsL|jd|jd||}|jjjdkr:|||rHt|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. colonrPeof)r)skip_ifexpectsubparser:rRrMnext)r1rJrkresultr4r4r5parse_statementss     zParser.parse_statementscCsft|jj}|jdd}|jdr<|}tj|||dS|d}|j ddd}tj ||||dS)zParse an assign statement.T)with_namespaceassignrVN)z name:endsetrk) rqr)r8parse_assign_targetrn parse_tuplerAssign parse_filterrs AssignBlock)r1r8targetexprZ filter_nodebodyr4r4r5 parse_sets    zParser.parse_setc Cs|jdj}|jdd}|jd|jddd}d}|jd rL|}|jd }|d }t|jj d krxg}n|jd dd}t j |||||||dS)zParse a for loop.zname:for)name:in)rNrF)name:recursive) with_condexprrNNname:ifr) name:endfor name:elseZendfor)rTrvrV) r)ror8rwrxrnparse_expressionrsrqr`rFor)r1r8r|itertest recursiver~else_r4r4r5 parse_fors      zParser.parse_forcCstj|jdjd}}|jdd|_|d|_g|_ g|_ t |j}|drvtj|jj jd}|j |qq|dr|jdd d |_ qq|S) zParse an if construct.rrVFr) name:elifr name:endifrr)rTrv)rIfr)ror8rxrrsr~Zelif_rrqr:rD)r1noderrrgr4r4r5parse_ifs     zParser.parse_ifcCstjt|jjd}g}g}|jjjdkrr|r:|jd|}| d| ||jd| | q||_ ||_ |jddd|_|S) NrVrPcommaparamru)z name:endwithTrv)rWithrqr)r8r:rRrorwset_ctxrDrtargetsvaluesrsr~)r1rrrr|r4r4r5 parse_withs    zParser.parse_withcCsDtjt|jjd}td|g|_|jddd|_ t |gS)NrVr)zname:endautoescapeTrv) rZScopedEvalContextModifierrqr)r8Keywordroptionsrsr~Scoper1rr4r4r5parse_autoescape szParser.parse_autoescapecCstjt|jjd}|jdj|_|jd|_ |jd|_ |jj j dkrX| d|jddd |_|j rtd d |jDs| d |jd |j|S)NrVr$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:endblockTrvcss0|](}|jD]}t|tjo$|jVq qdSN)r isinstance TemplateDatadataisspace).0r~childr4r4r5 :sz%Parser.parse_block..z7Required blocks can only contain comments or whitespacezname:)rBlockrqr)r8ror`r$rnscopedrequiredr:rRr;rsr~allrr4r4r5 parse_block&s zParser.parse_blockcCs"tjt|jjd}||_|SNrV)rExtendsrqr)r8rtemplaterr4r4r5 parse_extendsDs zParser.parse_extends)rdefaultr'cCsH|jjddr>|jdr>t|jjdk|_|jn||_|S)Nz name:withz name:without name:contextr) r)r:rSlookrrqr` with_contextskip)r1rrr4r4r5parse_import_contextIs zParser.parse_import_contextcCsbtjt|jjd}||_|jjdrP|j drPd|_ |j dnd|_ | |dS)NrVz name:ignorez name:missingTF) rIncluderqr)r8rrr:rrZignore_missingrrrr4r4r5 parse_includeUs zParser.parse_includecCsFtjt|jjd}||_|jd|jddj |_ | |dS)NrVname:asT name_onlyF) rImportrqr)r8rrrorwr$r|rrr4r4r5 parse_importas   zParser.parse_importcstjtjjd_jdg_t dfdd }jrVjdjj j dkr|rlqj dd }|j d rjd |jtd jd rĈj dd }j|j |j fnj|j |sjj j dkrqqDjdqDtds d_S)NrVz name:importr]csBjjjdkr>jdr>tjjdk_jdSdS)N>withoutrrrTF)r)r:r`rrrqrrr4rr1r4r5 parse_contextns z(Parser.parse_from..parse_contextrr$Tr_z4names starting with an underline can not be imported)r9rrF)r FromImportrqr)r8rrronamesboolr:rRrwr$ startswithr;rrnrDhasattrr)r1rr|aliasr4rr5 parse_fromhs6        zParser.parse_from)rr'cCsg}|_g}|_|jd|jjjdkr|r>|jd|jdd}|d|jdrp| | n|r~| d| |q |jddS) NlparenrQrTrrruz-non-default argument follows default argument) argsdefaultsr)ror:rRrwrrnrDrr;)r1rrrargr4r4r5parse_signatures         zParser.parse_signaturecCsvtjt|jjd}|jjjdkr.||n g|_g|_ | }t |tj s\| d|j||_|jddd|_|S)NrVrz expected call)z name:endcallTrv)r CallBlockrqr)r8r:rRrrrrrCallr;r^rsr~)r1rZ call_noder4r4r5rds  zParser.parse_call_blockcCs8tjt|jjd}|jddd|_|jddd|_|S)NrVT) start_inline)zname:endfilterrv) r FilterBlockrqr)r8rzr_rsr~rr4r4r5reszParser.parse_filter_blockcCsBtjt|jjd}|jddj|_|||jddd|_ |S)NrVTr)z name:endmacrorv) rMacrorqr)r8rwr$rrsr~rr4r4r5 parse_macros  zParser.parse_macrocCsPtjt|jjd}g|_|jjjdkrL|jr:|jd|j| q|S)NrVrPr) rOutputrqr)r8r:rRrorDrrr4r4r5 parse_prints zParser.parse_printzte.Literal[True]) with_tuplerr'cCsdSrr4)r1rrr4r4r5rwszParser.parse_assign_targetT)rrrNrtr'cCsdSrr4)r1rrrNrtr4r4r5rwscCs|rN|jjdkrN|jd}t|j|jd}tj|j|j|jd}nL|rt|jd}tj |jd|jd}n&|r|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$rVstoreT) simplifiedrNzcan't assign to )r)rrRrorqrNSRefr`r8Namerx parse_primaryrZ can_assignr;__name__lower)r1rrrNrtrgattrr|r4r4r5rws*     )rr'cCs|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)r1rr4r4r5rszParser.parse_expressioncCsb|jjj}|}|jdr^|}|jdr<|}nd}tj||||d}|jjj}q|S)NrrrV)r)r:r8rrnrrZCondExpr)r1r8expr1Zexpr2Zexpr3r4r4r5rs     zParser.parse_condexprcCsF|jjj}|}|jdrB|}tj|||d}|jjj}q|S)Nname:orrV)r)r:r8 parse_andrnrOrr1r8leftrightr4r4r5rs   zParser.parse_orcCsF|jjj}|}|jdrB|}tj|||d}|jjj}q|S)Nname:andrV)r)r:r8 parse_notrnrAndrr4r4r5r&s   zParser.parse_andcCs4|jjdr,t|jj}tj||dS|S)Nname:notrV) r)r:rrqr8rNotr parse_compare)r1r8r4r4r5r/s zParser.parse_notcCs|jjj}|}g}|jjj}|tkrJt|j|t ||nh|j drn|t d|nD|jj dr|j dr|j d|t d|nq|jjj}q|s|Stj|||dS)NrinrrnotinrV)r)r:r8 parse_math1rR_compare_operatorsrqrDrZOperandrnrrrZCompare)r1r8r}ops token_typer4r4r5r5s&      zParser.parse_comparecCs^|jjj}|}|jjjdkrZt|jjj}t|j|}||||d}|jjj}q|S)N)rrrV)r)r:r8 parse_concatrRr rqr1r8rclsrr4r4r5rLs   zParser.parse_math1cCs^|jjj}|g}|jjjdkr|s|r|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)rr4r1r4r5r-sz!Parser.parse_tuple..parseFrTrzExpected an expression, got rrV)r)r:r8rrrExprrorTrDrRr;rTuple) r1rrrNr r8r-rZis_tupler4rr5rxs2     zParser.parse_tuplecCsj|jd}g}|jjjdkrN|r.|jd|jjjdkr>qN||q|jdtj||jdS)Nr rbracketrrV) r)ror:rRrDrrListr8)r1rgitemsr4r4r5rs   zParser.parse_listcCs|jd}g}|jjjdkrt|r.|jd|jjjdkr>qt|}|jd|}|tj|||jdq|jdtj ||jdS)NrrbracerrlrV) r)ror:rRrrDrZPairr8Dict)r1rgrkeyr`r4r4r5rs    zParser.parse_dictcCsB|jjj}|dks|dkr&||}q|dkr>||}qq>q|S)Nrr r)r)r:rRparse_subscript parse_callr1rrr4r4r5rs   zParser.parse_postfixcCs\|jjj}|dkr||}q|dkr@|jjjdkr@||}q|dkrX||}qqXq|S)Npiper$isr)r)r:rRrzr` parse_testrrr4r4r5rs    zParser.parse_filter_exprcCst|j}|jdkr|jj}t|j|jdkrFtj||jd|jdS|jdkr^|d|jtj |j|jd}tj ||d|jdS|jdkr g}|jjjdkr|r|j d | | q|j dt|d kr|d }ntj|d|jd}tj ||d|jdS|d |jdS) Nrr$rrVr zexpected name or numberr rrrrzexpected subscript expression)rqr)rRr:rGetattrr`r8r;rGetitemrorDparse_subscribedrr)r1rrgZ attr_tokenrrr4r4r5r#s6          zParser.parse_subscriptcCs|jjj}|jjjdkr*t|jdg}n*|}|jjjdkrD|St|j|g}|jjjdkrn|dn(|jjjdkr||n |d|jjjdkrt|j|jjjdkr||q|dn |dtj|d|iS)Nrl)rrr8) r)r:r8rRrqrrDrZSlice)r1r8rrr4r4r5r$Bs*        zParser.parse_subscribedc s|jdg}g}d}d}d}tddfdd }jjjdkrd|rhjdjjjdkrhqdjjjdkr||dko|dktj}njjjd kr||dktj}njjjd kr2jjd kr2||dkjjj}j d }| t j |||j d n,||dkoL|dkoL| | d}q6jd||||fS)NrF)r}r'cs|sdjdS)Nz+invalid syntax for function call expression)r;r8)r}r1rgr4r5ensurejsz&Parser.parse_call_args..ensurerQrrrr$rurrVT)r)rorr:rRrqrrr`rrDrrr8) r1rkwargsdyn_args dyn_kwargsZ require_commar&rr`r4r%r5parse_call_argsbsD            zParser.parse_call_argscCs0|jj}|\}}}}tj||||||jdSr)r)r:r*rrr8)r1rrgrr'r(r)r4r4r5rszParser.parse_call)rrr'c Cs|jjjdks|r|s t|j|jd}|j}|jjjdkrbt|j|d|jdj7}q2|jjjdkr|\}}}}ng}g}d}}tj|||||||j d}d}q|S)Nrr$rr>rrVF) r)r:rRrqror`r*rFilterr8) r1rrrgr$rr'r(r)r4r4r5rzs0   zParser.parse_filterc Cs t|j}|jjdr(t|jd}nd}|jdj}|jjjdkrjt|j|d|jdj7}q:d}}g}|jjjdkr|\}}}}nV|jjjdkr|jjd d d s|jjd r| d | } | | } | g}ng}t j |||||||jd}|rt j||jd}|S)NrTFr$rr>r>rr$r rr rr rrrzname:isz'You cannot chain multiple tests with isrV)rqr)r:rror`rRr*rSr;rrrZTestr8r) r1rrgZnegatedr$r(r)r'rZarg_noder4r4r5r!sJ       zParser.parse_test)rJr'csLggj}|dk r"|j|ddfdd }z|jr(|jj}|jdkrz|jrn|tj|j|j dt |jq8|jdkrt |j||j dd|j d q8|jd kr|t |j|dk r|jjj |rWNS|}t|tr|n ||j d q8td q8|W5|dk rF|jXS) Nr]cs8r4dj}tjdd|ddd=dS)NrrV)r8rDrrrVr~Z data_bufferr4r5 flush_datas z#Parser.subparse..flush_datarrVZvariable_beginTrrOZ block_beginrPzinternal parsing error)rDr0rar)r:rRr`rrr8rqrxrorSrjrrKextendAssertionError)r1rJZadd_datar-rgr[r4r,r5rpsD              zParser.subparsecCs"tj|dd}||j|S)z0Parse the whole template into a `Template` node.rrV)rTemplaterpZset_environmentr")r1rrr4r4r5r- s z Parser.parse)NNN)N)NN)N)N)F)..)TFNF)TFNF)T)T)FTNF)F)N)_r __module__ __qualname____doc__strtOptionalr6rintTyper;rrrHrIrMrrTrrYr\UnionrZrjrsryr{rrrrrrrrrrrrrr rrrrrrrr rrrdrrerrrrtypingoverloadrrwrrrrrrrrrrrrrrrxrrrrrr"r#rr$r*rrrzr!rpr0r-r4r4r4r5r!.s&   )   "     .   *       $ B    1  + 1r!)'r3r:r5r r exceptionsrrlexerrr TYPE_CHECKINGZtyping_extensionster"rTypeVarrrr rrr frozensetrbrZAddZSubZMulZDivZFloorDivZModr rr4r8r__annotations__r!r4r4r4r5sH