NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

nodes.py (16353B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\nodes.py
      2 import operator
      3 from itertools import chain, izip
      4 from collections import deque
      5 from jinja2.utils import Markup, MethodType, FunctionType
      6 _context_function_types = (FunctionType, MethodType)
      7 _binop_to_func = {'*': operator.mul,
      8  '/': operator.truediv,
      9  '//': operator.floordiv,
     10  '**': operator.pow,
     11  '%': operator.mod,
     12  '+': operator.add,
     13  '-': operator.sub}
     14 _uaop_to_func = {'not': operator.not_,
     15  '+': operator.pos,
     16  '-': operator.neg}
     17 _cmpop_to_func = {'eq': operator.eq,
     18  'ne': operator.ne,
     19  'gt': operator.gt,
     20  'gteq': operator.ge,
     21  'lt': operator.lt,
     22  'lteq': operator.le,
     23  'in': lambda a, b: a in b,
     24  'notin': lambda a, b: a not in b}
     25 
     26 class Impossible(Exception):
     27     pass
     28 
     29 
     30 class NodeType(type):
     31 
     32     def __new__(cls, name, bases, d):
     33         for attr in ('fields', 'attributes'):
     34             storage = []
     35             storage.extend(getattr(bases[0], attr, ()))
     36             storage.extend(d.get(attr, ()))
     37             d[attr] = tuple(storage)
     38 
     39         d.setdefault('abstract', False)
     40         return type.__new__(cls, name, bases, d)
     41 
     42 
     43 class EvalContext(object):
     44 
     45     def __init__(self, environment, template_name = None):
     46         self.environment = environment
     47         if callable(environment.autoescape):
     48             self.autoescape = environment.autoescape(template_name)
     49         else:
     50             self.autoescape = environment.autoescape
     51         self.volatile = False
     52 
     53     def save(self):
     54         return self.__dict__.copy()
     55 
     56     def revert(self, old):
     57         self.__dict__.clear()
     58         self.__dict__.update(old)
     59 
     60 
     61 def get_eval_context(node, ctx):
     62     if ctx is None:
     63         if node.environment is None:
     64             raise RuntimeError('if no eval context is passed, the node must have an attached environment.')
     65         return EvalContext(node.environment)
     66     return ctx
     67 
     68 
     69 class Node(object):
     70     __metaclass__ = NodeType
     71     fields = ()
     72     attributes = ('lineno', 'environment')
     73     abstract = True
     74 
     75     def __init__(self, *fields, **attributes):
     76         if self.abstract:
     77             raise TypeError('abstract nodes are not instanciable')
     78         if fields:
     79             if len(fields) != len(self.fields):
     80                 if not self.fields:
     81                     raise TypeError('%r takes 0 arguments' % self.__class__.__name__)
     82                 raise TypeError('%r takes 0 or %d argument%s' % (self.__class__.__name__, len(self.fields), len(self.fields) != 1 and 's' or ''))
     83             for name, arg in izip(self.fields, fields):
     84                 setattr(self, name, arg)
     85 
     86         for attr in self.attributes:
     87             setattr(self, attr, attributes.pop(attr, None))
     88 
     89         if attributes:
     90             raise TypeError('unknown attribute %r' % iter(attributes).next())
     91 
     92     def iter_fields(self, exclude = None, only = None):
     93         for name in self.fields:
     94             if exclude is only is None or exclude is not None and name not in exclude or only is not None and name in only:
     95                 try:
     96                     yield (name, getattr(self, name))
     97                 except AttributeError:
     98                     pass
     99 
    100     def iter_child_nodes(self, exclude = None, only = None):
    101         for field, item in self.iter_fields(exclude, only):
    102             if isinstance(item, list):
    103                 for n in item:
    104                     if isinstance(n, Node):
    105                         yield n
    106 
    107             elif isinstance(item, Node):
    108                 yield item
    109 
    110     def find(self, node_type):
    111         for result in self.find_all(node_type):
    112             return result
    113 
    114     def find_all(self, node_type):
    115         for child in self.iter_child_nodes():
    116             if isinstance(child, node_type):
    117                 yield child
    118             for result in child.find_all(node_type):
    119                 yield result
    120 
    121     def set_ctx(self, ctx):
    122         todo = deque([self])
    123         while todo:
    124             node = todo.popleft()
    125             if 'ctx' in node.fields:
    126                 node.ctx = ctx
    127             todo.extend(node.iter_child_nodes())
    128 
    129         return self
    130 
    131     def set_lineno(self, lineno, override = False):
    132         todo = deque([self])
    133         while todo:
    134             node = todo.popleft()
    135             if 'lineno' in node.attributes:
    136                 if node.lineno is None or override:
    137                     node.lineno = lineno
    138             todo.extend(node.iter_child_nodes())
    139 
    140         return self
    141 
    142     def set_environment(self, environment):
    143         todo = deque([self])
    144         while todo:
    145             node = todo.popleft()
    146             node.environment = environment
    147             todo.extend(node.iter_child_nodes())
    148 
    149         return self
    150 
    151     def __eq__(self, other):
    152         return type(self) is type(other) and tuple(self.iter_fields()) == tuple(other.iter_fields())
    153 
    154     def __ne__(self, other):
    155         return not self.__eq__(other)
    156 
    157     def __repr__(self):
    158         return '%s(%s)' % (self.__class__.__name__, ', '.join(('%s=%r' % (arg, getattr(self, arg, None)) for arg in self.fields)))
    159 
    160 
    161 class Stmt(Node):
    162     abstract = True
    163 
    164 
    165 class Helper(Node):
    166     abstract = True
    167 
    168 
    169 class Template(Node):
    170     fields = ('body',)
    171 
    172 
    173 class Output(Stmt):
    174     fields = ('nodes',)
    175 
    176 
    177 class Extends(Stmt):
    178     fields = ('template',)
    179 
    180 
    181 class For(Stmt):
    182     fields = ('target', 'iter', 'body', 'else_', 'test', 'recursive')
    183 
    184 
    185 class If(Stmt):
    186     fields = ('test', 'body', 'else_')
    187 
    188 
    189 class Macro(Stmt):
    190     fields = ('name', 'args', 'defaults', 'body')
    191 
    192 
    193 class CallBlock(Stmt):
    194     fields = ('call', 'args', 'defaults', 'body')
    195 
    196 
    197 class FilterBlock(Stmt):
    198     fields = ('body', 'filter')
    199 
    200 
    201 class Block(Stmt):
    202     fields = ('name', 'body', 'scoped')
    203 
    204 
    205 class Include(Stmt):
    206     fields = ('template', 'with_context', 'ignore_missing')
    207 
    208 
    209 class Import(Stmt):
    210     fields = ('template', 'target', 'with_context')
    211 
    212 
    213 class FromImport(Stmt):
    214     fields = ('template', 'names', 'with_context')
    215 
    216 
    217 class ExprStmt(Stmt):
    218     fields = ('node',)
    219 
    220 
    221 class Assign(Stmt):
    222     fields = ('target', 'node')
    223 
    224 
    225 class Expr(Node):
    226     abstract = True
    227 
    228     def as_const(self, eval_ctx = None):
    229         raise Impossible()
    230 
    231     def can_assign(self):
    232         return False
    233 
    234 
    235 class BinExpr(Expr):
    236     fields = ('left', 'right')
    237     operator = None
    238     abstract = True
    239 
    240     def as_const(self, eval_ctx = None):
    241         eval_ctx = get_eval_context(self, eval_ctx)
    242         if self.environment.sandboxed and self.operator in self.environment.intercepted_binops:
    243             raise Impossible()
    244         f = _binop_to_func[self.operator]
    245         try:
    246             return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx))
    247         except Exception:
    248             raise Impossible()
    249 
    250 
    251 class UnaryExpr(Expr):
    252     fields = ('node',)
    253     operator = None
    254     abstract = True
    255 
    256     def as_const(self, eval_ctx = None):
    257         eval_ctx = get_eval_context(self, eval_ctx)
    258         if self.environment.sandboxed and self.operator in self.environment.intercepted_unops:
    259             raise Impossible()
    260         f = _uaop_to_func[self.operator]
    261         try:
    262             return f(self.node.as_const(eval_ctx))
    263         except Exception:
    264             raise Impossible()
    265 
    266 
    267 class Name(Expr):
    268     fields = ('name', 'ctx')
    269 
    270     def can_assign(self):
    271         return self.name not in ('true', 'false', 'none', 'True', 'False', 'None')
    272 
    273 
    274 class Literal(Expr):
    275     abstract = True
    276 
    277 
    278 class Const(Literal):
    279     fields = ('value',)
    280 
    281     def as_const(self, eval_ctx = None):
    282         return self.value
    283 
    284     @classmethod
    285     def from_untrusted(cls, value, lineno = None, environment = None):
    286         from compiler import has_safe_repr
    287         if not has_safe_repr(value):
    288             raise Impossible()
    289         return cls(value, lineno=lineno, environment=environment)
    290 
    291 
    292 class TemplateData(Literal):
    293     fields = ('data',)
    294 
    295     def as_const(self, eval_ctx = None):
    296         eval_ctx = get_eval_context(self, eval_ctx)
    297         if eval_ctx.volatile:
    298             raise Impossible()
    299         if eval_ctx.autoescape:
    300             return Markup(self.data)
    301         return self.data
    302 
    303 
    304 class Tuple(Literal):
    305     fields = ('items', 'ctx')
    306 
    307     def as_const(self, eval_ctx = None):
    308         eval_ctx = get_eval_context(self, eval_ctx)
    309         return tuple((x.as_const(eval_ctx) for x in self.items))
    310 
    311     def can_assign(self):
    312         for item in self.items:
    313             if not item.can_assign():
    314                 return False
    315 
    316         return True
    317 
    318 
    319 class List(Literal):
    320     fields = ('items',)
    321 
    322     def as_const(self, eval_ctx = None):
    323         eval_ctx = get_eval_context(self, eval_ctx)
    324         return [ x.as_const(eval_ctx) for x in self.items ]
    325 
    326 
    327 class Dict(Literal):
    328     fields = ('items',)
    329 
    330     def as_const(self, eval_ctx = None):
    331         eval_ctx = get_eval_context(self, eval_ctx)
    332         return dict((x.as_const(eval_ctx) for x in self.items))
    333 
    334 
    335 class Pair(Helper):
    336     fields = ('key', 'value')
    337 
    338     def as_const(self, eval_ctx = None):
    339         eval_ctx = get_eval_context(self, eval_ctx)
    340         return (self.key.as_const(eval_ctx), self.value.as_const(eval_ctx))
    341 
    342 
    343 class Keyword(Helper):
    344     fields = ('key', 'value')
    345 
    346     def as_const(self, eval_ctx = None):
    347         eval_ctx = get_eval_context(self, eval_ctx)
    348         return (self.key, self.value.as_const(eval_ctx))
    349 
    350 
    351 class CondExpr(Expr):
    352     fields = ('test', 'expr1', 'expr2')
    353 
    354     def as_const(self, eval_ctx = None):
    355         eval_ctx = get_eval_context(self, eval_ctx)
    356         if self.test.as_const(eval_ctx):
    357             return self.expr1.as_const(eval_ctx)
    358         if self.expr2 is None:
    359             raise Impossible()
    360         return self.expr2.as_const(eval_ctx)
    361 
    362 
    363 class Filter(Expr):
    364     fields = ('node', 'name', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
    365 
    366     def as_const(self, eval_ctx = None):
    367         eval_ctx = get_eval_context(self, eval_ctx)
    368         if eval_ctx.volatile or self.node is None:
    369             raise Impossible()
    370         filter_ = self.environment.filters.get(self.name)
    371         if filter_ is None or getattr(filter_, 'contextfilter', False):
    372             raise Impossible()
    373         obj = self.node.as_const(eval_ctx)
    374         args = [ x.as_const(eval_ctx) for x in self.args ]
    375         if getattr(filter_, 'evalcontextfilter', False):
    376             args.insert(0, eval_ctx)
    377         elif getattr(filter_, 'environmentfilter', False):
    378             args.insert(0, self.environment)
    379         kwargs = dict((x.as_const(eval_ctx) for x in self.kwargs))
    380         if self.dyn_args is not None:
    381             try:
    382                 args.extend(self.dyn_args.as_const(eval_ctx))
    383             except Exception:
    384                 raise Impossible()
    385 
    386         if self.dyn_kwargs is not None:
    387             try:
    388                 kwargs.update(self.dyn_kwargs.as_const(eval_ctx))
    389             except Exception:
    390                 raise Impossible()
    391 
    392         try:
    393             return filter_(obj, *args, **kwargs)
    394         except Exception:
    395             raise Impossible()
    396 
    397 
    398 class Test(Expr):
    399     fields = ('node', 'name', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
    400 
    401 
    402 class Call(Expr):
    403     fields = ('node', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
    404 
    405     def as_const(self, eval_ctx = None):
    406         eval_ctx = get_eval_context(self, eval_ctx)
    407         if eval_ctx.volatile:
    408             raise Impossible()
    409         obj = self.node.as_const(eval_ctx)
    410         args = [ x.as_const(eval_ctx) for x in self.args ]
    411         if isinstance(obj, _context_function_types):
    412             if getattr(obj, 'contextfunction', False):
    413                 raise Impossible()
    414             elif getattr(obj, 'evalcontextfunction', False):
    415                 args.insert(0, eval_ctx)
    416             elif getattr(obj, 'environmentfunction', False):
    417                 args.insert(0, self.environment)
    418         kwargs = dict((x.as_const(eval_ctx) for x in self.kwargs))
    419         if self.dyn_args is not None:
    420             try:
    421                 args.extend(self.dyn_args.as_const(eval_ctx))
    422             except Exception:
    423                 raise Impossible()
    424 
    425         if self.dyn_kwargs is not None:
    426             try:
    427                 kwargs.update(self.dyn_kwargs.as_const(eval_ctx))
    428             except Exception:
    429                 raise Impossible()
    430 
    431         try:
    432             return obj(*args, **kwargs)
    433         except Exception:
    434             raise Impossible()
    435 
    436 
    437 class Getitem(Expr):
    438     fields = ('node', 'arg', 'ctx')
    439 
    440     def as_const(self, eval_ctx = None):
    441         eval_ctx = get_eval_context(self, eval_ctx)
    442         if self.ctx != 'load':
    443             raise Impossible()
    444         try:
    445             return self.environment.getitem(self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx))
    446         except Exception:
    447             raise Impossible()
    448 
    449     def can_assign(self):
    450         return False
    451 
    452 
    453 class Getattr(Expr):
    454     fields = ('node', 'attr', 'ctx')
    455 
    456     def as_const(self, eval_ctx = None):
    457         if self.ctx != 'load':
    458             raise Impossible()
    459         try:
    460             eval_ctx = get_eval_context(self, eval_ctx)
    461             return self.environment.getattr(self.node.as_const(eval_ctx), self.attr)
    462         except Exception:
    463             raise Impossible()
    464 
    465     def can_assign(self):
    466         return False
    467 
    468 
    469 class Slice(Expr):
    470     fields = ('start', 'stop', 'step')
    471 
    472     def as_const(self, eval_ctx = None):
    473         eval_ctx = get_eval_context(self, eval_ctx)
    474 
    475         def const(obj):
    476             if obj is None:
    477                 return
    478             return obj.as_const(eval_ctx)
    479 
    480         return slice(const(self.start), const(self.stop), const(self.step))
    481 
    482 
    483 class Concat(Expr):
    484     fields = ('nodes',)
    485 
    486     def as_const(self, eval_ctx = None):
    487         eval_ctx = get_eval_context(self, eval_ctx)
    488         return ''.join((unicode(x.as_const(eval_ctx)) for x in self.nodes))
    489 
    490 
    491 class Compare(Expr):
    492     fields = ('expr', 'ops')
    493 
    494     def as_const(self, eval_ctx = None):
    495         eval_ctx = get_eval_context(self, eval_ctx)
    496         result = value = self.expr.as_const(eval_ctx)
    497         try:
    498             for op in self.ops:
    499                 new_value = op.expr.as_const(eval_ctx)
    500                 result = _cmpop_to_func[op.op](value, new_value)
    501                 value = new_value
    502 
    503         except Exception:
    504             raise Impossible()
    505 
    506         return result
    507 
    508 
    509 class Operand(Helper):
    510     fields = ('op', 'expr')
    511 
    512 
    513 class Mul(BinExpr):
    514     operator = '*'
    515 
    516 
    517 class Div(BinExpr):
    518     operator = '/'
    519 
    520 
    521 class FloorDiv(BinExpr):
    522     operator = '//'
    523 
    524 
    525 class Add(BinExpr):
    526     operator = '+'
    527 
    528 
    529 class Sub(BinExpr):
    530     operator = '-'
    531 
    532 
    533 class Mod(BinExpr):
    534     operator = '%'
    535 
    536 
    537 class Pow(BinExpr):
    538     operator = '**'
    539 
    540 
    541 class And(BinExpr):
    542     operator = 'and'
    543 
    544     def as_const(self, eval_ctx = None):
    545         eval_ctx = get_eval_context(self, eval_ctx)
    546         return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx)
    547 
    548 
    549 class Or(BinExpr):
    550     operator = 'or'
    551 
    552     def as_const(self, eval_ctx = None):
    553         eval_ctx = get_eval_context(self, eval_ctx)
    554         return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx)
    555 
    556 
    557 class Not(UnaryExpr):
    558     operator = 'not'
    559 
    560 
    561 class Neg(UnaryExpr):
    562     operator = '-'
    563 
    564 
    565 class Pos(UnaryExpr):
    566     operator = '+'
    567 
    568 
    569 class EnvironmentAttribute(Expr):
    570     fields = ('name',)
    571 
    572 
    573 class ExtensionAttribute(Expr):
    574     fields = ('identifier', 'name')
    575 
    576 
    577 class ImportedName(Expr):
    578     fields = ('importname',)
    579 
    580 
    581 class InternalName(Expr):
    582     fields = ('name',)
    583 
    584     def __init__(self):
    585         raise TypeError("Can't create internal names.  Use the `free_identifier` method on a parser.")
    586 
    587 
    588 class MarkSafe(Expr):
    589     fields = ('expr',)
    590 
    591     def as_const(self, eval_ctx = None):
    592         eval_ctx = get_eval_context(self, eval_ctx)
    593         return Markup(self.expr.as_const(eval_ctx))
    594 
    595 
    596 class MarkSafeIfAutoescape(Expr):
    597     fields = ('expr',)
    598 
    599     def as_const(self, eval_ctx = None):
    600         eval_ctx = get_eval_context(self, eval_ctx)
    601         if eval_ctx.volatile:
    602             raise Impossible()
    603         expr = self.expr.as_const(eval_ctx)
    604         if eval_ctx.autoescape:
    605             return Markup(expr)
    606         return expr
    607 
    608 
    609 class ContextReference(Expr):
    610     pass
    611 
    612 
    613 class Continue(Stmt):
    614     pass
    615 
    616 
    617 class Break(Stmt):
    618     pass
    619 
    620 
    621 class Scope(Stmt):
    622     fields = ('body',)
    623 
    624 
    625 class EvalContextModifier(Stmt):
    626     fields = ('options',)
    627 
    628 
    629 class ScopedEvalContextModifier(EvalContextModifier):
    630     fields = ('body',)
    631 
    632 
    633 def _failing_new(*args, **kwargs):
    634     raise TypeError("can't create custom node types")
    635 
    636 
    637 NodeType.__new__ = staticmethod(_failing_new)
    638 del _failing_new