a +b@sUdZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z ej rlddl 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) forifblockZextendsprintZmacroZincludefromimportsetwith autoescape)eqneltZlteqgtZgteq)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$ extensiontagr2A/usr/lib/python3.9/site-packages/ansible/_vendor/jinja2/parser.py__init__3s  zParser.__init__z te.NoReturn)msglinenoexcr%cCs(|dur|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'currentr6r"r#)r/r5r6r7r2r2r3failJs  z Parser.fail.)r"end_token_stackr6r%cCst}|D]}|tt|q |r@dtttt|d}nd}|durTdg}nd|dg}|r|dur||vr|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-r9)r/r"r:r6ZexpectedZexprsZcurrently_lookingmessager2r2r3 _fail_ut_eofXs8 zParser._fail_ut_eof)r"r6r%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)rDr.)r/r"r6r2r2r3fail_unknown_tagszParser.fail_unknown_tag) end_tokensr6r%cCs.t|j}|dur|||d||dS)z9Like fail_unknown_tag but for end of template situations.N)listr.rBrD)r/rFr6stackr2r2r3fail_eofs  zParser.fail_eof)extra_end_rulesr%cCs,|jjjdvrdS|dur(|jj|SdS)zAre we at the end of a tuple?) variable_end block_endrparenTNF)r'r8typetest_any)r/rJr2r2r3 is_tuple_ends zParser.is_tuple_end)r6r%cCs8|jd7_ttj}tjj|d|j|d|S)zDReturn a new free identifier as :class:`~jinja2.nodes.InternalName`.rfir6)r,object__new__r InternalNameNoder4)r/r6rvr2r2r3free_identifiers zParser.free_identifierr%cCs$|jj}|jdkr |d|j|j|jd}z|jtvrjt |d|jjj}|W|rh|j S|jdkr| W|r|j S|jdkr| W|r|j S|j |j}|dur||W|r|j S|j d}||j|jW|r |j n|r|j 0dS) zParse a single statement.r"ztag name expectedTZparse_callfilterNF)r'r8rNr9r6r-rBvalue_statement_keywordsgetattrpopparse_call_blockparse_filter_blockr)getrE)r/tokenZpop_tagfextr2r2r3parse_statementsF            zParser.parse_statementF)rF 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. colonrLeof)r'skip_ifexpectsubparser8rNrInext)r/rFrgresultr2r2r3parse_statementss     zParser.parse_statementscCsft|jj}|jdd}|jdr<|}tj|||dS|d}|j ddd}tj ||||dS)zParse an assign statement.T)with_namespaceassignrRN)z name:endsetrg) rmr'r6parse_assign_targetrj parse_tuplerAssign parse_filterro AssignBlock)r/r6targetexprZ filter_nodebodyr2r2r3 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)rJr|F)name:recursive) with_condexprrJNname:ifr}) name:endfor name:elseZendfor)rTrrrR) r'rkr6rsrtrjparse_expressionrormr\rFor)r/r6rxitertest recursiverzelse_r2r2r3 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.rrRFr~) name:elifr name:endifrr)rTrr)rIfr'rkr6rtrrorzZelif_rrmr8rB)r/nodernrcr2r2r3parse_ifs     zParser.parse_ifcCstjt|jjd}g}g}|jjjdkrr|r:|jd|}| d| ||jd| | q||_ ||_ |jddd|_|S) NrRrLcommaparamrq)z name:endwithTrr)rWithrmr'r6r8rNrkrsset_ctxrBrtargetsvaluesrorz)r/rrrrxr2r2r3 parse_withs    zParser.parse_withcCsDtjt|jjd}td|g|_|jddd|_ t |gS)NrRr)zname:endautoescapeTrr) rZScopedEvalContextModifierrmr'r6KeywordroptionsrorzScoper/rr2r2r3parse_autoescape szParser.parse_autoescapecCstjt|jjd}|jdj|_|jd|_ |jd|_ |jj j dkrX| d|jddd |_|j rtd d |jDs| d |jd |j|S)NrRr"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:endblockTrrcss0|](}|jD]}t|tjo$|jVq qdSN)r isinstance TemplateDatadataisspace).0rzchildr2r2r3 :s z%Parser.parse_block..z7Required blocks can only contain comments or whitespacezname:)rBlockrmr'r6rkr\r"rjZscopedrequiredr8rNr9rorzallrr2r2r3 parse_block&s zParser.parse_blockcCs"tjt|jjd}||_|SNrR)rExtendsrmr'r6rtemplaterr2r2r3 parse_extendsDs zParser.parse_extends)rdefaultr%cCsH|jjddr>|jdr>t|jjdk|_|jn||_|S)Nz name:withz name:without name:contextr) r'r8rOlookrrmr\ with_contextskip)r/rrr2r2r3parse_import_contextIs zParser.parse_import_contextcCsbtjt|jjd}||_|jjdrP|j drPd|_ |j dnd|_ | |dS)NrRz name:ignorez name:missingTF) rIncludermr'r6rrr8rrZignore_missingrrrr2r2r3 parse_includeUs zParser.parse_includecCsFtjt|jjd}||_|jd|jddj |_ | |dS)NrRname:asT name_onlyF) rImportrmr'r6rrrkrsr"rxrrr2r2r3 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)NrRz name:importrYcsBjjjdvr>jdr>tjjdk_jdSdS)N>ZwithoutrrrTF)r'r8r\rrrmrrr2rr/r2r3 parse_contextns z(Parser.parse_from..parse_contextrr"Tr_z4names starting with an underline can not be imported)r7rrF)r FromImportrmr'r6rrrknamesboolr8rNrsr" startswithr9rrjrBhasattrr)r/rrxaliasr2rr3 parse_fromhs6         zParser.parse_from)rr%cCsg}|_g}|_|jd|jjjdkr|r>|jd|jdd}|d|jdrp| | n|r~| d| |q |jddS) NlparenrMrTrrrqz-non-default argument follows default argument) argsdefaultsr'rkr8rNrsrrjrBrr9)r/rrrargr2r2r3parse_signatures         zParser.parse_signaturecCsvtjt|jjd}|jjjdkr.||n g|_g|_ | }t |tj s\| d|j||_|jddd|_|S)NrRrz expected call)z name:endcallTrr)r CallBlockrmr'r6r8rNrrrrrCallr9rZrorz)r/rZ call_noder2r2r3r`s  zParser.parse_call_blockcCs8tjt|jjd}|jddd|_|jddd|_|S)NrRT) start_inline)zname:endfilterrr) r FilterBlockrmr'r6rvr[rorzrr2r2r3raszParser.parse_filter_blockcCsBtjt|jjd}|jddj|_|||jddd|_ |S)NrRTr)z name:endmacrorr) rMacrormr'r6rsr"rrorzrr2r2r3 parse_macros  zParser.parse_macrocCsPtjt|jjd}g|_|jjjdkrL|jr:|jd|j| q|S)NrRrLr) rOutputrmr'r6r8rNrkrBrrr2r2r3 parse_prints zParser.parse_printzte.Literal[True]) with_tuplerr%cCsdSrr2)r/rrr2r2r3rsszParser.parse_assign_targetT)rrrJrpr%cCsdSrr2)r/rrrJrpr2r2r3rsscCs|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"rRstoreT) simplifiedrJzcan't assign to )r'rrNrkrmrNSRefr\r6Namert parse_primaryrZ can_assignr9__name__lower)r/rrrJrprcattrrxr2r2r3rss&     )r~r%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)r/r~r2r2r3rszParser.parse_expressioncCsb|jjj}|}|jdr^|}|jdr<|}nd}tj||||d}|jjj}q|S)NrrrR)r'r8r6rrjrrZCondExpr)r/r6Zexpr1Zexpr2Zexpr3r2r2r3r s     zParser.parse_condexprcCsF|jjj}|}|jdrB|}tj|||d}|jjj}q|S)Nname:orrR)r'r8r6 parse_andrjrZOrr/r6leftrightr2r2r3rs   zParser.parse_orcCsF|jjj}|}|jdrB|}tj|||d}|jjj}q|S)Nname:andrR)r'r8r6 parse_notrjrZAndrr2r2r3r"s   zParser.parse_andcCs4|jjdr,t|jj}tj||dS|S)Nname:notrR) r'r8rrmr6rNotr parse_compare)r/r6r2r2r3r+s zParser.parse_notcCs|jjj}|}g}|jjj}|tvrJt|j|t ||nh|j drn|t d|nD|jj dr|j dr|j d|t d|nq|jjj}q|s|Stj|||dS)Nr|inrrZnotinrR)r'r8r6 parse_math1rN_compare_operatorsrmrBrZOperandrjrrrZCompare)r/r6ryops token_typer2r2r3r1s&      zParser.parse_comparecCs^|jjj}|}|jjjdvrZt|jjj}t|j|}||||d}|jjj}q|S)N)rrrR)r'r8r6 parse_concatrNrrmr/r6rclsrr2r2r3rHs   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. rYcs jddS)NFr)rr2r/r2r3r+sz!Parser.parse_tuple..parseFrTrzExpected an expression, got rrR)r'r8r6rrrExprrkrPrBrNr9rTuple) r/rr~rJrr6r+rZis_tupler2rr3rts6      zParser.parse_tuplecCsj|jd}g}|jjjdkrN|r.|jd|jjjdkr>qN||q|jdtj||jdS)NrrbracketrrR) r'rkr8rNrBrrListr6)r/rcitemsr2r2r3rs   zParser.parse_listcCs|jd}g}|jjjdkrt|r.|jd|jjjdkr>qt|}|jd|}|tj|||jdq|jdtj ||jdS)NrrbracerrhrR) r'rkr8rNrrBrZPairr6Dict)r/rcr keyr\r2r2r3rs    zParser.parse_dictcCsB|jjj}|dks|dkr&||}q|dkr>||}qq>q|S)Nrrr)r'r8rNparse_subscript parse_callr/rrr2r2r3rs   zParser.parse_postfixcCs\|jjj}|dkr||}q|dkr@|jjjdkr@||}q|dkrX||}qqXq|S)Npiper"isr)r'r8rNrvr\ parse_testrrr2r2r3rs    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"rrRrzexpected name or numberrr rrrzexpected subscript expression)rmr'rNr8rGetattrr\r6r9rGetitemrkrBparse_subscribedrr )r/rrcZ attr_tokenrrr2r2r3rs0           zParser.parse_subscriptcCs|jjj}|jjjdkr*t|jdg}n*|}|jjjdkrD|St|j|g}|jjjdkrn|dn(|jjjdvr||n |d|jjjdkrt|j|jjjdvr||q|dn |dtj|d|iS)Nrh)r rr6) r'r8r6rNrmrrBrZSlice)r/r6rrr2r2r3r>s*        zParser.parse_subscribedc s|jdg}g}d}d}d}tddfdd }jjjdkrd|rhjdjjjdkrhqdjjjdkr||duo|dutj}njjjd kr||dutj}njjjd kr2jjd kr2||dujjj}j d }| t j |||j d n,||duoL|duoL| | d}q6jd||||fS)NrF)ryr%cs|sdjdS)Nz+invalid syntax for function call expression)r9r6)ryr/rcr2r3ensurefsz&Parser.parse_call_args..ensurerMrrrr"rqrrRT)r'rkrr8rNrmrrr\rrBrrr6) r/rkwargsdyn_args dyn_kwargsZ require_commarrr\r2rr3parse_call_args^sD            zParser.parse_call_argscCs0|jj}|\}}}}tj||||||jdSr)r'r8rrrr6)r/rrcrrrrr2r2r3rszParser.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<rrRF) r'r8rNrmrkr\rrZFilterr6) r/rrrcr"rrrrr2r2r3rvs$   zParser.parse_filterc Cs t|j}|jjdr(t|jd}nd}|jdj}|jjjdkrjt|j|d|jdj7}q:d}}g}|jjjdkr|\}}}}nV|jjjdvr|jjd d d s|jjd r| d | } | | } | g}ng}t j |||||||jd}|rt j||jd}|S)NrTFr"rr<r>rrr"rrrrrrrzname:isz'You cannot chain multiple tests with isrR)rmr'r8rrkr\rNrrOr9rrrZTestr6r) r/rrcZnegatedr"rrrrZarg_noder2r2r3rs8      zParser.parse_test)rFr%csrggj}|dur"|j|ddfdd }z|jr:|jj}|jdkr||jrp|tj|j|jdt |jq:|jdkrt |j||j dd|j d q:|jd kr0|t |j|dur|jjj |rW|dur|j S|}t|tr|n ||j d q:td q:|W|durn|j n|durl|j 0S) NrYcs8r4dj}tjdd|ddd=dS)NrrR)r6rBrrrRrzZ data_bufferr2r3 flush_datas z#Parser.subparse..flush_datarrRZvariable_beginTrrKZ block_beginrLzinternal parsing error)rBr.r'r8rNr\rrr6rmrtrkrOr_rfrrGextendAssertionError)r/rFZadd_datar rcrWr2rr3rlsN                zParser.subparsecCs"tj|dd}||j|S)z0Parse the whole template into a `Template` node.rrR)rTemplaterlZset_environmentr )r/rnr2r2r3r+s z Parser.parse)NNN)N)NN)N)N)F)..)TFNF)TFNF)T)T)FTNF)F)N)_r __module__ __qualname____doc__strtOptionalr4rintTyper9r r rDrErIrrPrrUrXUnionrVrfrorurwr{rrrrrrrrrrrrr rrrrrrrr rrr`rrarrrrtypingoverloadrrsrrrrrrrrrrrrrrrtrrrrrrrrrrrrrvrrlr#r+r2r2r2r3r.s   )    "    *   *       $ B    1  ' 1r)'r&r-r(rr exceptionsrrZlexerrr TYPE_CHECKINGZtyping_extensionster rTypeVarrrr rrr frozensetr]rZAddZSubZMulZDivZFloorDivZModrrr'r+r__annotations__rr2r2r2r3s0