o !bYQ@sdZddlmZddlmZddlZddlmZddlm Z ddl m Z m Z m Z ddlmZdd lmZdd lmZmZmZmZmZmZmZgd Zd ZGd ddeZGdddeZGdddeZ eZ!GdddeZ"GdddeZ#GdddeZ$Gddde$Z%Gddde$Z&d+ddZ' d,d!d"Z(d#d$Z)ej*+Z,e,-e e#d%e.gd&Z/Gd'd(d(e Z0Gd)d*d*e0Z1dS)-z4Support for "safe" evaluation of Python expressions.)dedent)CodeTypeN)builtins)Markup)ASTTransformerASTCodeGeneratorparse)TemplateRuntimeError)flatten)ast _ast_Constantget_code_paramsbuild_code_chunkisstring IS_PYTHON2_ast_Str)Code ExpressionSuite LenientLookup StrictLookup UndefinedUndefinedErrorzrestructuredtext enc@sVeZdZdZgdZ  dddZdd Zd d Zd d ZddZ ddZ ddZ dS)rz=Abstract base class for the `Expression` and `Suite` classes.)sourcecoder _globalsNstrictcCst|tjr||_t||jd}n$t|tjsJd|d|_|jdkr-t}||_ nt }|g|_ ||_ t ||j|j|||d|_ |durLt}n t|tjrYttd|}|j|_dS)aCreate the code object, either from a string, or from an AST node. :param source: either a string containing the source code, or an AST node :param filename: the (preferably absolute) name of the file containing the code :param lineno: the number of the line on which the code was found :param lookup: the lookup class that defines how variables are looked up in the context; can be either "strict" (the default), "lenient", or a custom lookup class :param xform: the AST transformer that should be applied to the code; if `None`, the appropriate transformation is chosen depending on the mode )modez'Expected string or AST node, but got %r?eval)rfilenamelinenoxformN)lenientr) isinstancesix string_typesr_parser_astASTrbodyModuler _compilerrrglobalsr)selfrr!r"lookupr#noder26/usr/lib/python3/dist-packages/genshi/template/eval.py__init__(s*     z Code.__init__cCs@t|jdr |jj}n|jj}|j|j|d}t|j|d<|S)N__self__)rr r0r)hasattrrr5im_selfrr r r)r/ lookup_fnstater2r2r3 __getstate__Os  zCode.__getstate__cCs:|d|_|d|_tdg|dR|_|dj|_dS)Nrr rrr0)rr rrr.r)r/r9r2r2r3 __setstate__Ys  zCode.__setstate__cCst|t|ko |j|jkSN)typerr/otherr2r2r3__eq___sz Code.__eq__cCs t|jSr<)hashrr/r2r2r3__hash__b z Code.__hash__cCs ||k Sr<r2r>r2r2r3__ne__erDz Code.__ne__cCdt|j|jfS)Nz%s(%r))r=__name__rrBr2r2r3__repr__hz Code.__repr__)NrrN) rG __module__ __qualname____doc__ __slots__r4r:r;r@rCrErHr2r2r2r3r$s '  rc@ eZdZdZgZdZddZdS)raEvaluates Python expressions used in templates. >>> data = dict(test='Foo', items=[1, 2, 3], dict={'some': 'thing'}) >>> Expression('test').evaluate(data) 'Foo' >>> Expression('items[0]').evaluate(data) 1 >>> Expression('items[-1]').evaluate(data) 3 >>> Expression('dict["some"]').evaluate(data) 'thing' Similar to e.g. Javascript, expressions in templates can use the dot notation for attribute access to access items in mappings: >>> Expression('dict.some').evaluate(data) 'thing' This also works the other way around: item access can be used to access any object attribute: >>> class MyClass(object): ... myattr = 'Bar' >>> data = dict(mine=MyClass(), key='myattr') >>> Expression('mine.myattr').evaluate(data) 'Bar' >>> Expression('mine["myattr"]').evaluate(data) 'Bar' >>> Expression('mine[key]').evaluate(data) 'Bar' All of the standard Python operators are available to template expressions. Built-in functions such as ``len()`` are also available in template expressions: >>> data = dict(items=[1, 2, 3]) >>> Expression('len(items)').evaluate(data) 3 r cCs d}||}t|j|d|iS)zEvaluate the expression against the given data dictionary. :param data: a mapping containing the data to evaluate against :return: the result of the evaluation before_and_this__data__)rr rr/data__traceback_hide__rr2r2r3evaluates zExpression.evaluateN)rGrJrKrLrMrrTr2r2r2r3rls ( rc@rN)rzExecutes Python statements used in templates. >>> data = dict(test='Foo', items=[1, 2, 3], dict={'some': 'thing'}) >>> Suite("foo = dict['some']").execute(data) >>> data['foo'] 'thing' execcCs"d}||}t|j||dS)zExecute the suite in the given data dictionary. :param data: a mapping containing the data to execute in rON)rr&exec_rrQr2r2r3executes z Suite.executeN)rGrJrKrLrMrrWr2r2r2r3rs  rc@seZdZdZefddZdS)rzException thrown when a template expression attempts to access a variable not defined in the context. :see: `LenientLookup`, `StrictLookup` cCs2|tur dt||f}nd|}t||dS)Nz%s has no member named "%s"z"%s" not defined) UNDEFINEDreprr r4)r/nameownermessager2r2r3r4szUndefinedError.__init__N)rGrJrKrLrXr4r2r2r2r3rsrc@s`eZdZdZddgZefddZddZdd ZeZ d d Z d d Z ddZ e Z ZZdZdS)raRepresents a reference to an undefined variable. Unlike the Python runtime, template expressions can refer to an undefined variable without causing a `NameError` to be raised. The result will be an instance of the `Undefined` class, which is treated the same as ``False`` in conditions, but raise an exception on any other operation: >>> foo = Undefined('foo') >>> bool(foo) False >>> list(foo) [] >>> print(foo) undefined However, calling an undefined variable, or trying to access an attribute of that variable, will raise an exception that includes the name used to reference that undefined variable. >>> try: ... foo('bar') ... except UndefinedError as e: ... print(e.msg) "foo" not defined >>> try: ... foo.bar ... except UndefinedError as e: ... print(e.msg) "foo" not defined :see: `LenientLookup` _name_ownercCs||_||_dS)zInitialize the object. :param name: the name of the reference :param owner: the owning object, if the variable is accessed as a member N)r]r^)r/rZr[r2r2r3r4s zUndefined.__init__cCstgSr<)iterrBr2r2r3__iter__szUndefined.__iter__cCdS)NFr2rBr2r2r3__bool__zUndefined.__bool__cCrF)Nz<%s %r>)r=rGr]rBr2r2r3rHrIzUndefined.__repr__cCra)N undefinedr2rBr2r2r3__str__rczUndefined.__str__cOsd}t|j|j)zRaise an `UndefinedError`.T)rr]r^)r/argskwargsrSr2r2r3_dieszUndefined._dieN)rGrJrKrLrMrXr4r`rb __nonzero__rHrerh__call__ __getattr__ __getitem____length_hint__r2r2r2r3rs!   rc@sPeZdZdZeddZeddZeddZedd Zee fd d Z d S) LookupBasez8Abstract base class for variable lookup implementations.cCs||j|j|jtdS)znConstruct the globals dictionary to use as the execution context for the expression or suite. )rP _lookup_name _lookup_attr _lookup_itemr) lookup_name lookup_attr lookup_itemr)clsrRr2r2r3r.s zLookupBase.globalscCs:d}||t}|turt||}|tur||}|S)NT)getrXBUILTINSrd)rurRrZrSvalr2r2r3rrs   zLookupBase.lookup_namec Csld}zt||}W|Sty5t|j|rz||}WY|Sttfy4|j||d}YY|Sww)NTr[)getattrAttributeErrorr6 __class__KeyError TypeErrorrd)ruobjkeyrSrxr2r2r3rs)s   zLookupBase.lookup_attrc Csd}t|dkr |d}z||WSttttfyA}z t|tjr>> expr = Expression('nothing', lookup='lenient') >>> undef = expr.evaluate({}) >>> undef The same will happen when a non-existing attribute or item is accessed on an existing object: >>> expr = Expression('something.nil', lookup='lenient') >>> expr.evaluate({'something': dict()}) See the documentation of the `Undefined` class for details on the behavior of such objects. :see: `StrictLookup` cCsd}t||dS)zReturn an ``Undefined`` object.Try)rrurr[rSr2r2r3rdj zLenientLookup.undefinedNrGrJrKrLrrXrdr2r2r2r3rRrc@r)raStrict variable lookup mechanism for expressions. Referencing an undefined variable using this lookup style will immediately raise an ``UndefinedError``: >>> expr = Expression('nothing', lookup='strict') >>> try: ... expr.evaluate({}) ... except UndefinedError as e: ... print(e.msg) "nothing" not defined The same happens when a non-existing attribute or item is accessed on an existing object: >>> expr = Expression('something.nil', lookup='strict') >>> try: ... expr.evaluate({'something': dict()}) ... except UndefinedError as e: ... print(e.msg) {} has no member named "nil" cCsd}t||d)z(Raise an ``UndefinedError`` immediately.Try)rrr2r2r3rdrzStrictLookup.undefinedNrr2r2r2r3rqrrr cCs|}|dkrDdd|D}|rD|d}td|dd}|dr=|ds=ddd|D}d||g}t|tj rQd | d }t ||S) NrUcSsg|]}|qSr2) expandtabs.0liner2r2r3 z_parse..r r:cSsg|]}d|qS)z %sr2rr2r2r3rruutf-8) strip splitlinesrjoinrstripendswithisspacer%r& text_typeencoder)rrlinesfirstrestr2r2r3r(s  r(rc Cs|sd}trt|tjr|dd}n t|tjs|dd}|dkr%d}|dur1dti|t}| |}|dkrBd|p?d}n| }|sKd } n|d} t |dkrY| d 7} d | }t |j } t| ||} zt| |||WSty{| YSw) Nzrreplacerrr zrz ...z )rr%r&rrdecodeExpressionASTTransformerrvTemplateASTTransformervisitrrrrcompiler RuntimeError) r1rrr!r"r#treerZrextract new_sourcerr2r2r3r-s@         r-cOsV|}t|j|D]\}}||vrtdt|||q |D] \}}t|||q|S)Nz!Field set both in args and kwargs)zip_fields ValueErrorsetattr)class_rfrgretattrvaluer2r2r3_news r)rr)FalseTrueNoneNotImplementedEllipsisc@steZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ e Z ddZddZddZdS)rpConcrete AST transformer that implements the AST transformations needed for code embedded in templates. cCs tg|_dSr<) CONSTANTSlocalsrBr2r2r3r4s zTemplateASTTransformer.__init__cCstst|tjr||jdSt|r||dSt|tjr)||jdSt|tjr:||j p6|j dSt|tj rL|j D] }| ||qCdSdSr<)rr%r)argaddrNameidaliasasnamerZTupleelts_process)r/namesr1eltr2r2r3rs    zTemplateASTTransformer._processcCst}t|dr?|jD]}|||q t|dr%|jD]}|||qt|dr1|||jt|dr=|||j|St|drP|jD]}|||qG|S)Nrf kwonlyargsvarargkwargr)setr6rfrrrrr)r/r1rrrr2r2r3_extract_namess        z%TemplateASTTransformer._extract_namescCsJt|jtjs#z |jdW|Sty"tt|jdYSw|S)Nasciir)r%sr&rrrrrr/r1r2r2r3 visit_Strs z TemplateASTTransformer.visit_StrcCsTt|jdkr|jd|j|jtz t||W|jS|jwNrr) rrrrZappendrrvisit_ClassDefpoprr2r2r3rs  z%TemplateASTTransformer.visit_ClassDefcCs0t|jdkr|jd||t||Sr)rrupdaterr visit_Importrr2r2r3rs z#TemplateASTTransformer.visit_ImportcCsJdd|jDdgkr |St|jdkr|jd||t||S)NcSsg|]}|jqSr2)rZ)rar2r2r3rsz;TemplateASTTransformer.visit_ImportFrom..*rr)rrrrrrvisit_ImportFromrr2r2r3rs  z'TemplateASTTransformer.visit_ImportFromcCsZt|jdkr|jd|j|j||jz t||W|j S|j wr) rrrrZrrrfrvisit_FunctionDefrrr2r2r3rs  z(TemplateASTTransformer.visit_FunctionDefcsg}|jD]&}jtttj|j|j fdd|j D}||qt|j |j |}jt |j d=|S)Ncsg|]}|qSr2)r)rif_rBr2r3r/sz=TemplateASTTransformer.visit_GeneratorExp..) generatorsrrrrr) comprehensionrtargetr_ifsr|rr)r/r1gens generatorgenrr2rBr3visit_GeneratorExp(s   z)TemplateASTTransformer.visit_GeneratorExpcCs:|j||jz t||W|jS|jwr<)rrrrfr visit_Lambdarrr2r2r3r;s z#TemplateASTTransformer.visit_LambdacCs||j|_|Sr<)rrrr2r2r3 visit_StarredCsz$TemplateASTTransformer.visit_StarredcCst|jtjr3|jt|jvr3ttjdt}ttjdt}tt |j}ttj |||gg}|St|jtj rJt |jdkrJ|jd |j|S)NrorPrr)r%ctxr)Loadrr rrrrCallStorerr)r/r1rZnameargstrargr2r2r3 visit_NameGs z!TemplateASTTransformer.visit_NameN)rGrJrKrLr4rrrrrrrrvisit_ListComprrrr2r2r2r3rs    rc@s eZdZdZddZddZdS)rrcCsTt|jtjs t||Sttjdt}||j tt |j g}ttj ||gS)Nrp) r%rr)rrvisit_Attributerrrrrrr)r/r1funcrfr2r2r3r]s  z(ExpressionASTTransformer.visit_AttributecCst|jtjrt|jtjttjtjfst ||St|jtjtjfr(|j}n|jj }t tjdt}| |j t tj| |ftg}t tj||gS)Nrq)r%rr)rsliceIndexr rrrvisit_Subscriptrrrr)r/r1 slice_valuerrfr2r2r3res  z(ExpressionASTTransformer.visit_SubscriptN)rGrJrKrLrrr2r2r2r3rXs r)r )Nr NrN)2rLtextwraprtypesrr& six.movesr genshi.corergenshi.template.astutilrrrgenshi.template.baser genshi.utilr genshi.compatr r)r r rrrr__all__ __docformat__objectrrrrXrrrnrrr(r-r__dict__copyrwr frozensetrrrr2r2r2r3s>      $H7FC  +  ~