compiler.py 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  1. # -*- coding: utf-8 -*-
  2. """
  3. jinja2.compiler
  4. ~~~~~~~~~~~~~~~
  5. Compiles nodes into python code.
  6. :copyright: (c) 2010 by the Jinja Team.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. from itertools import chain
  10. from copy import deepcopy
  11. from keyword import iskeyword as is_python_keyword
  12. from jinja2 import nodes
  13. from jinja2.nodes import EvalContext
  14. from jinja2.visitor import NodeVisitor
  15. from jinja2.exceptions import TemplateAssertionError
  16. from jinja2.utils import Markup, concat, escape
  17. from jinja2._compat import range_type, text_type, string_types, \
  18. iteritems, NativeStringIO, imap
  19. operators = {
  20. 'eq': '==',
  21. 'ne': '!=',
  22. 'gt': '>',
  23. 'gteq': '>=',
  24. 'lt': '<',
  25. 'lteq': '<=',
  26. 'in': 'in',
  27. 'notin': 'not in'
  28. }
  29. # what method to iterate over items do we want to use for dict iteration
  30. # in generated code? on 2.x let's go with iteritems, on 3.x with items
  31. if hasattr(dict, 'iteritems'):
  32. dict_item_iter = 'iteritems'
  33. else:
  34. dict_item_iter = 'items'
  35. # does if 0: dummy(x) get us x into the scope?
  36. def unoptimize_before_dead_code():
  37. x = 42
  38. def f():
  39. if 0: dummy(x)
  40. return f
  41. # The getattr is necessary for pypy which does not set this attribute if
  42. # no closure is on the function
  43. unoptimize_before_dead_code = bool(
  44. getattr(unoptimize_before_dead_code(), '__closure__', None))
  45. def generate(node, environment, name, filename, stream=None,
  46. defer_init=False):
  47. """Generate the python source for a node tree."""
  48. if not isinstance(node, nodes.Template):
  49. raise TypeError('Can\'t compile non template nodes')
  50. generator = environment.code_generator_class(environment, name, filename,
  51. stream, defer_init)
  52. generator.visit(node)
  53. if stream is None:
  54. return generator.stream.getvalue()
  55. def has_safe_repr(value):
  56. """Does the node have a safe representation?"""
  57. if value is None or value is NotImplemented or value is Ellipsis:
  58. return True
  59. if isinstance(value, (bool, int, float, complex, range_type,
  60. Markup) + string_types):
  61. return True
  62. if isinstance(value, (tuple, list, set, frozenset)):
  63. for item in value:
  64. if not has_safe_repr(item):
  65. return False
  66. return True
  67. elif isinstance(value, dict):
  68. for key, value in iteritems(value):
  69. if not has_safe_repr(key):
  70. return False
  71. if not has_safe_repr(value):
  72. return False
  73. return True
  74. return False
  75. def find_undeclared(nodes, names):
  76. """Check if the names passed are accessed undeclared. The return value
  77. is a set of all the undeclared names from the sequence of names found.
  78. """
  79. visitor = UndeclaredNameVisitor(names)
  80. try:
  81. for node in nodes:
  82. visitor.visit(node)
  83. except VisitorExit:
  84. pass
  85. return visitor.undeclared
  86. class Identifiers(object):
  87. """Tracks the status of identifiers in frames."""
  88. def __init__(self):
  89. # variables that are known to be declared (probably from outer
  90. # frames or because they are special for the frame)
  91. self.declared = set()
  92. # undeclared variables from outer scopes
  93. self.outer_undeclared = set()
  94. # names that are accessed without being explicitly declared by
  95. # this one or any of the outer scopes. Names can appear both in
  96. # declared and undeclared.
  97. self.undeclared = set()
  98. # names that are declared locally
  99. self.declared_locally = set()
  100. # names that are declared by parameters
  101. self.declared_parameter = set()
  102. def add_special(self, name):
  103. """Register a special name like `loop`."""
  104. self.undeclared.discard(name)
  105. self.declared.add(name)
  106. def is_declared(self, name):
  107. """Check if a name is declared in this or an outer scope."""
  108. if name in self.declared_locally or name in self.declared_parameter:
  109. return True
  110. return name in self.declared
  111. def copy(self):
  112. return deepcopy(self)
  113. class Frame(object):
  114. """Holds compile time information for us."""
  115. def __init__(self, eval_ctx, parent=None):
  116. self.eval_ctx = eval_ctx
  117. self.identifiers = Identifiers()
  118. # a toplevel frame is the root + soft frames such as if conditions.
  119. self.toplevel = False
  120. # the root frame is basically just the outermost frame, so no if
  121. # conditions. This information is used to optimize inheritance
  122. # situations.
  123. self.rootlevel = False
  124. # in some dynamic inheritance situations the compiler needs to add
  125. # write tests around output statements.
  126. self.require_output_check = parent and parent.require_output_check
  127. # inside some tags we are using a buffer rather than yield statements.
  128. # this for example affects {% filter %} or {% macro %}. If a frame
  129. # is buffered this variable points to the name of the list used as
  130. # buffer.
  131. self.buffer = None
  132. # the name of the block we're in, otherwise None.
  133. self.block = parent and parent.block or None
  134. # a set of actually assigned names
  135. self.assigned_names = set()
  136. # the parent of this frame
  137. self.parent = parent
  138. if parent is not None:
  139. self.identifiers.declared.update(
  140. parent.identifiers.declared |
  141. parent.identifiers.declared_parameter |
  142. parent.assigned_names
  143. )
  144. self.identifiers.outer_undeclared.update(
  145. parent.identifiers.undeclared -
  146. self.identifiers.declared
  147. )
  148. self.buffer = parent.buffer
  149. def copy(self):
  150. """Create a copy of the current one."""
  151. rv = object.__new__(self.__class__)
  152. rv.__dict__.update(self.__dict__)
  153. rv.identifiers = object.__new__(self.identifiers.__class__)
  154. rv.identifiers.__dict__.update(self.identifiers.__dict__)
  155. return rv
  156. def inspect(self, nodes):
  157. """Walk the node and check for identifiers. If the scope is hard (eg:
  158. enforce on a python level) overrides from outer scopes are tracked
  159. differently.
  160. """
  161. visitor = FrameIdentifierVisitor(self.identifiers)
  162. for node in nodes:
  163. visitor.visit(node)
  164. def find_shadowed(self, extra=()):
  165. """Find all the shadowed names. extra is an iterable of variables
  166. that may be defined with `add_special` which may occour scoped.
  167. """
  168. i = self.identifiers
  169. return (i.declared | i.outer_undeclared) & \
  170. (i.declared_locally | i.declared_parameter) | \
  171. set(x for x in extra if i.is_declared(x))
  172. def inner(self):
  173. """Return an inner frame."""
  174. return Frame(self.eval_ctx, self)
  175. def soft(self):
  176. """Return a soft frame. A soft frame may not be modified as
  177. standalone thing as it shares the resources with the frame it
  178. was created of, but it's not a rootlevel frame any longer.
  179. """
  180. rv = self.copy()
  181. rv.rootlevel = False
  182. return rv
  183. __copy__ = copy
  184. class VisitorExit(RuntimeError):
  185. """Exception used by the `UndeclaredNameVisitor` to signal a stop."""
  186. class DependencyFinderVisitor(NodeVisitor):
  187. """A visitor that collects filter and test calls."""
  188. def __init__(self):
  189. self.filters = set()
  190. self.tests = set()
  191. def visit_Filter(self, node):
  192. self.generic_visit(node)
  193. self.filters.add(node.name)
  194. def visit_Test(self, node):
  195. self.generic_visit(node)
  196. self.tests.add(node.name)
  197. def visit_Block(self, node):
  198. """Stop visiting at blocks."""
  199. class UndeclaredNameVisitor(NodeVisitor):
  200. """A visitor that checks if a name is accessed without being
  201. declared. This is different from the frame visitor as it will
  202. not stop at closure frames.
  203. """
  204. def __init__(self, names):
  205. self.names = set(names)
  206. self.undeclared = set()
  207. def visit_Name(self, node):
  208. if node.ctx == 'load' and node.name in self.names:
  209. self.undeclared.add(node.name)
  210. if self.undeclared == self.names:
  211. raise VisitorExit()
  212. else:
  213. self.names.discard(node.name)
  214. def visit_Block(self, node):
  215. """Stop visiting a blocks."""
  216. class FrameIdentifierVisitor(NodeVisitor):
  217. """A visitor for `Frame.inspect`."""
  218. def __init__(self, identifiers):
  219. self.identifiers = identifiers
  220. def visit_Name(self, node):
  221. """All assignments to names go through this function."""
  222. if node.ctx == 'store':
  223. self.identifiers.declared_locally.add(node.name)
  224. elif node.ctx == 'param':
  225. self.identifiers.declared_parameter.add(node.name)
  226. elif node.ctx == 'load' and not \
  227. self.identifiers.is_declared(node.name):
  228. self.identifiers.undeclared.add(node.name)
  229. def visit_If(self, node):
  230. self.visit(node.test)
  231. real_identifiers = self.identifiers
  232. old_names = real_identifiers.declared_locally | \
  233. real_identifiers.declared_parameter
  234. def inner_visit(nodes):
  235. if not nodes:
  236. return set()
  237. self.identifiers = real_identifiers.copy()
  238. for subnode in nodes:
  239. self.visit(subnode)
  240. rv = self.identifiers.declared_locally - old_names
  241. # we have to remember the undeclared variables of this branch
  242. # because we will have to pull them.
  243. real_identifiers.undeclared.update(self.identifiers.undeclared)
  244. self.identifiers = real_identifiers
  245. return rv
  246. body = inner_visit(node.body)
  247. else_ = inner_visit(node.else_ or ())
  248. # the differences between the two branches are also pulled as
  249. # undeclared variables
  250. real_identifiers.undeclared.update(body.symmetric_difference(else_) -
  251. real_identifiers.declared)
  252. # remember those that are declared.
  253. real_identifiers.declared_locally.update(body | else_)
  254. def visit_Macro(self, node):
  255. self.identifiers.declared_locally.add(node.name)
  256. def visit_Import(self, node):
  257. self.generic_visit(node)
  258. self.identifiers.declared_locally.add(node.target)
  259. def visit_FromImport(self, node):
  260. self.generic_visit(node)
  261. for name in node.names:
  262. if isinstance(name, tuple):
  263. self.identifiers.declared_locally.add(name[1])
  264. else:
  265. self.identifiers.declared_locally.add(name)
  266. def visit_Assign(self, node):
  267. """Visit assignments in the correct order."""
  268. self.visit(node.node)
  269. self.visit(node.target)
  270. def visit_For(self, node):
  271. """Visiting stops at for blocks. However the block sequence
  272. is visited as part of the outer scope.
  273. """
  274. self.visit(node.iter)
  275. def visit_CallBlock(self, node):
  276. self.visit(node.call)
  277. def visit_FilterBlock(self, node):
  278. self.visit(node.filter)
  279. def visit_AssignBlock(self, node):
  280. """Stop visiting at block assigns."""
  281. def visit_Scope(self, node):
  282. """Stop visiting at scopes."""
  283. def visit_Block(self, node):
  284. """Stop visiting at blocks."""
  285. class CompilerExit(Exception):
  286. """Raised if the compiler encountered a situation where it just
  287. doesn't make sense to further process the code. Any block that
  288. raises such an exception is not further processed.
  289. """
  290. class CodeGenerator(NodeVisitor):
  291. def __init__(self, environment, name, filename, stream=None,
  292. defer_init=False):
  293. if stream is None:
  294. stream = NativeStringIO()
  295. self.environment = environment
  296. self.name = name
  297. self.filename = filename
  298. self.stream = stream
  299. self.created_block_context = False
  300. self.defer_init = defer_init
  301. # aliases for imports
  302. self.import_aliases = {}
  303. # a registry for all blocks. Because blocks are moved out
  304. # into the global python scope they are registered here
  305. self.blocks = {}
  306. # the number of extends statements so far
  307. self.extends_so_far = 0
  308. # some templates have a rootlevel extends. In this case we
  309. # can safely assume that we're a child template and do some
  310. # more optimizations.
  311. self.has_known_extends = False
  312. # the current line number
  313. self.code_lineno = 1
  314. # registry of all filters and tests (global, not block local)
  315. self.tests = {}
  316. self.filters = {}
  317. # the debug information
  318. self.debug_info = []
  319. self._write_debug_info = None
  320. # the number of new lines before the next write()
  321. self._new_lines = 0
  322. # the line number of the last written statement
  323. self._last_line = 0
  324. # true if nothing was written so far.
  325. self._first_write = True
  326. # used by the `temporary_identifier` method to get new
  327. # unique, temporary identifier
  328. self._last_identifier = 0
  329. # the current indentation
  330. self._indentation = 0
  331. # -- Various compilation helpers
  332. def fail(self, msg, lineno):
  333. """Fail with a :exc:`TemplateAssertionError`."""
  334. raise TemplateAssertionError(msg, lineno, self.name, self.filename)
  335. def temporary_identifier(self):
  336. """Get a new unique identifier."""
  337. self._last_identifier += 1
  338. return 't_%d' % self._last_identifier
  339. def buffer(self, frame):
  340. """Enable buffering for the frame from that point onwards."""
  341. frame.buffer = self.temporary_identifier()
  342. self.writeline('%s = []' % frame.buffer)
  343. def return_buffer_contents(self, frame):
  344. """Return the buffer contents of the frame."""
  345. if frame.eval_ctx.volatile:
  346. self.writeline('if context.eval_ctx.autoescape:')
  347. self.indent()
  348. self.writeline('return Markup(concat(%s))' % frame.buffer)
  349. self.outdent()
  350. self.writeline('else:')
  351. self.indent()
  352. self.writeline('return concat(%s)' % frame.buffer)
  353. self.outdent()
  354. elif frame.eval_ctx.autoescape:
  355. self.writeline('return Markup(concat(%s))' % frame.buffer)
  356. else:
  357. self.writeline('return concat(%s)' % frame.buffer)
  358. def indent(self):
  359. """Indent by one."""
  360. self._indentation += 1
  361. def outdent(self, step=1):
  362. """Outdent by step."""
  363. self._indentation -= step
  364. def start_write(self, frame, node=None):
  365. """Yield or write into the frame buffer."""
  366. if frame.buffer is None:
  367. self.writeline('yield ', node)
  368. else:
  369. self.writeline('%s.append(' % frame.buffer, node)
  370. def end_write(self, frame):
  371. """End the writing process started by `start_write`."""
  372. if frame.buffer is not None:
  373. self.write(')')
  374. def simple_write(self, s, frame, node=None):
  375. """Simple shortcut for start_write + write + end_write."""
  376. self.start_write(frame, node)
  377. self.write(s)
  378. self.end_write(frame)
  379. def blockvisit(self, nodes, frame):
  380. """Visit a list of nodes as block in a frame. If the current frame
  381. is no buffer a dummy ``if 0: yield None`` is written automatically
  382. unless the force_generator parameter is set to False.
  383. """
  384. if frame.buffer is None:
  385. self.writeline('if 0: yield None')
  386. else:
  387. self.writeline('pass')
  388. try:
  389. for node in nodes:
  390. self.visit(node, frame)
  391. except CompilerExit:
  392. pass
  393. def write(self, x):
  394. """Write a string into the output stream."""
  395. if self._new_lines:
  396. if not self._first_write:
  397. self.stream.write('\n' * self._new_lines)
  398. self.code_lineno += self._new_lines
  399. if self._write_debug_info is not None:
  400. self.debug_info.append((self._write_debug_info,
  401. self.code_lineno))
  402. self._write_debug_info = None
  403. self._first_write = False
  404. self.stream.write(' ' * self._indentation)
  405. self._new_lines = 0
  406. self.stream.write(x)
  407. def writeline(self, x, node=None, extra=0):
  408. """Combination of newline and write."""
  409. self.newline(node, extra)
  410. self.write(x)
  411. def newline(self, node=None, extra=0):
  412. """Add one or more newlines before the next write."""
  413. self._new_lines = max(self._new_lines, 1 + extra)
  414. if node is not None and node.lineno != self._last_line:
  415. self._write_debug_info = node.lineno
  416. self._last_line = node.lineno
  417. def signature(self, node, frame, extra_kwargs=None):
  418. """Writes a function call to the stream for the current node.
  419. A leading comma is added automatically. The extra keyword
  420. arguments may not include python keywords otherwise a syntax
  421. error could occour. The extra keyword arguments should be given
  422. as python dict.
  423. """
  424. # if any of the given keyword arguments is a python keyword
  425. # we have to make sure that no invalid call is created.
  426. kwarg_workaround = False
  427. for kwarg in chain((x.key for x in node.kwargs), extra_kwargs or ()):
  428. if is_python_keyword(kwarg):
  429. kwarg_workaround = True
  430. break
  431. for arg in node.args:
  432. self.write(', ')
  433. self.visit(arg, frame)
  434. if not kwarg_workaround:
  435. for kwarg in node.kwargs:
  436. self.write(', ')
  437. self.visit(kwarg, frame)
  438. if extra_kwargs is not None:
  439. for key, value in iteritems(extra_kwargs):
  440. self.write(', %s=%s' % (key, value))
  441. if node.dyn_args:
  442. self.write(', *')
  443. self.visit(node.dyn_args, frame)
  444. if kwarg_workaround:
  445. if node.dyn_kwargs is not None:
  446. self.write(', **dict({')
  447. else:
  448. self.write(', **{')
  449. for kwarg in node.kwargs:
  450. self.write('%r: ' % kwarg.key)
  451. self.visit(kwarg.value, frame)
  452. self.write(', ')
  453. if extra_kwargs is not None:
  454. for key, value in iteritems(extra_kwargs):
  455. self.write('%r: %s, ' % (key, value))
  456. if node.dyn_kwargs is not None:
  457. self.write('}, **')
  458. self.visit(node.dyn_kwargs, frame)
  459. self.write(')')
  460. else:
  461. self.write('}')
  462. elif node.dyn_kwargs is not None:
  463. self.write(', **')
  464. self.visit(node.dyn_kwargs, frame)
  465. def pull_locals(self, frame):
  466. """Pull all the references identifiers into the local scope."""
  467. for name in frame.identifiers.undeclared:
  468. self.writeline('l_%s = context.resolve(%r)' % (name, name))
  469. def pull_dependencies(self, nodes):
  470. """Pull all the dependencies."""
  471. visitor = DependencyFinderVisitor()
  472. for node in nodes:
  473. visitor.visit(node)
  474. for dependency in 'filters', 'tests':
  475. mapping = getattr(self, dependency)
  476. for name in getattr(visitor, dependency):
  477. if name not in mapping:
  478. mapping[name] = self.temporary_identifier()
  479. self.writeline('%s = environment.%s[%r]' %
  480. (mapping[name], dependency, name))
  481. def unoptimize_scope(self, frame):
  482. """Disable Python optimizations for the frame."""
  483. # XXX: this is not that nice but it has no real overhead. It
  484. # mainly works because python finds the locals before dead code
  485. # is removed. If that breaks we have to add a dummy function
  486. # that just accepts the arguments and does nothing.
  487. if frame.identifiers.declared:
  488. self.writeline('%sdummy(%s)' % (
  489. unoptimize_before_dead_code and 'if 0: ' or '',
  490. ', '.join('l_' + name for name in frame.identifiers.declared)
  491. ))
  492. def push_scope(self, frame, extra_vars=()):
  493. """This function returns all the shadowed variables in a dict
  494. in the form name: alias and will write the required assignments
  495. into the current scope. No indentation takes place.
  496. This also predefines locally declared variables from the loop
  497. body because under some circumstances it may be the case that
  498. `extra_vars` is passed to `Frame.find_shadowed`.
  499. """
  500. aliases = {}
  501. for name in frame.find_shadowed(extra_vars):
  502. aliases[name] = ident = self.temporary_identifier()
  503. self.writeline('%s = l_%s' % (ident, name))
  504. to_declare = set()
  505. for name in frame.identifiers.declared_locally:
  506. if name not in aliases:
  507. to_declare.add('l_' + name)
  508. if to_declare:
  509. self.writeline(' = '.join(to_declare) + ' = missing')
  510. return aliases
  511. def pop_scope(self, aliases, frame):
  512. """Restore all aliases and delete unused variables."""
  513. for name, alias in iteritems(aliases):
  514. self.writeline('l_%s = %s' % (name, alias))
  515. to_delete = set()
  516. for name in frame.identifiers.declared_locally:
  517. if name not in aliases:
  518. to_delete.add('l_' + name)
  519. if to_delete:
  520. # we cannot use the del statement here because enclosed
  521. # scopes can trigger a SyntaxError:
  522. # a = 42; b = lambda: a; del a
  523. self.writeline(' = '.join(to_delete) + ' = missing')
  524. def function_scoping(self, node, frame, children=None,
  525. find_special=True):
  526. """In Jinja a few statements require the help of anonymous
  527. functions. Those are currently macros and call blocks and in
  528. the future also recursive loops. As there is currently
  529. technical limitation that doesn't allow reading and writing a
  530. variable in a scope where the initial value is coming from an
  531. outer scope, this function tries to fall back with a common
  532. error message. Additionally the frame passed is modified so
  533. that the argumetns are collected and callers are looked up.
  534. This will return the modified frame.
  535. """
  536. # we have to iterate twice over it, make sure that works
  537. if children is None:
  538. children = node.iter_child_nodes()
  539. children = list(children)
  540. func_frame = frame.inner()
  541. func_frame.inspect(children)
  542. # variables that are undeclared (accessed before declaration) and
  543. # declared locally *and* part of an outside scope raise a template
  544. # assertion error. Reason: we can't generate reasonable code from
  545. # it without aliasing all the variables.
  546. # this could be fixed in Python 3 where we have the nonlocal
  547. # keyword or if we switch to bytecode generation
  548. overridden_closure_vars = (
  549. func_frame.identifiers.undeclared &
  550. func_frame.identifiers.declared &
  551. (func_frame.identifiers.declared_locally |
  552. func_frame.identifiers.declared_parameter)
  553. )
  554. if overridden_closure_vars:
  555. self.fail('It\'s not possible to set and access variables '
  556. 'derived from an outer scope! (affects: %s)' %
  557. ', '.join(sorted(overridden_closure_vars)), node.lineno)
  558. # remove variables from a closure from the frame's undeclared
  559. # identifiers.
  560. func_frame.identifiers.undeclared -= (
  561. func_frame.identifiers.undeclared &
  562. func_frame.identifiers.declared
  563. )
  564. # no special variables for this scope, abort early
  565. if not find_special:
  566. return func_frame
  567. func_frame.accesses_kwargs = False
  568. func_frame.accesses_varargs = False
  569. func_frame.accesses_caller = False
  570. func_frame.arguments = args = ['l_' + x.name for x in node.args]
  571. undeclared = find_undeclared(children, ('caller', 'kwargs', 'varargs'))
  572. if 'caller' in undeclared:
  573. func_frame.accesses_caller = True
  574. func_frame.identifiers.add_special('caller')
  575. args.append('l_caller')
  576. if 'kwargs' in undeclared:
  577. func_frame.accesses_kwargs = True
  578. func_frame.identifiers.add_special('kwargs')
  579. args.append('l_kwargs')
  580. if 'varargs' in undeclared:
  581. func_frame.accesses_varargs = True
  582. func_frame.identifiers.add_special('varargs')
  583. args.append('l_varargs')
  584. return func_frame
  585. def macro_body(self, node, frame, children=None):
  586. """Dump the function def of a macro or call block."""
  587. frame = self.function_scoping(node, frame, children)
  588. # macros are delayed, they never require output checks
  589. frame.require_output_check = False
  590. args = frame.arguments
  591. # XXX: this is an ugly fix for the loop nesting bug
  592. # (tests.test_old_bugs.test_loop_call_bug). This works around
  593. # a identifier nesting problem we have in general. It's just more
  594. # likely to happen in loops which is why we work around it. The
  595. # real solution would be "nonlocal" all the identifiers that are
  596. # leaking into a new python frame and might be used both unassigned
  597. # and assigned.
  598. if 'loop' in frame.identifiers.declared:
  599. args = args + ['l_loop=l_loop']
  600. self.writeline('def macro(%s):' % ', '.join(args), node)
  601. self.indent()
  602. self.buffer(frame)
  603. self.pull_locals(frame)
  604. self.blockvisit(node.body, frame)
  605. self.return_buffer_contents(frame)
  606. self.outdent()
  607. return frame
  608. def macro_def(self, node, frame):
  609. """Dump the macro definition for the def created by macro_body."""
  610. arg_tuple = ', '.join(repr(x.name) for x in node.args)
  611. name = getattr(node, 'name', None)
  612. if len(node.args) == 1:
  613. arg_tuple += ','
  614. self.write('Macro(environment, macro, %r, (%s), (' %
  615. (name, arg_tuple))
  616. for arg in node.defaults:
  617. self.visit(arg, frame)
  618. self.write(', ')
  619. self.write('), %r, %r, %r)' % (
  620. bool(frame.accesses_kwargs),
  621. bool(frame.accesses_varargs),
  622. bool(frame.accesses_caller)
  623. ))
  624. def position(self, node):
  625. """Return a human readable position for the node."""
  626. rv = 'line %d' % node.lineno
  627. if self.name is not None:
  628. rv += ' in ' + repr(self.name)
  629. return rv
  630. # -- Statement Visitors
  631. def visit_Template(self, node, frame=None):
  632. assert frame is None, 'no root frame allowed'
  633. eval_ctx = EvalContext(self.environment, self.name)
  634. from jinja2.runtime import __all__ as exported
  635. self.writeline('from __future__ import division')
  636. self.writeline('from jinja2.runtime import ' + ', '.join(exported))
  637. if not unoptimize_before_dead_code:
  638. self.writeline('dummy = lambda *x: None')
  639. # if we want a deferred initialization we cannot move the
  640. # environment into a local name
  641. envenv = not self.defer_init and ', environment=environment' or ''
  642. # do we have an extends tag at all? If not, we can save some
  643. # overhead by just not processing any inheritance code.
  644. have_extends = node.find(nodes.Extends) is not None
  645. # find all blocks
  646. for block in node.find_all(nodes.Block):
  647. if block.name in self.blocks:
  648. self.fail('block %r defined twice' % block.name, block.lineno)
  649. self.blocks[block.name] = block
  650. # find all imports and import them
  651. for import_ in node.find_all(nodes.ImportedName):
  652. if import_.importname not in self.import_aliases:
  653. imp = import_.importname
  654. self.import_aliases[imp] = alias = self.temporary_identifier()
  655. if '.' in imp:
  656. module, obj = imp.rsplit('.', 1)
  657. self.writeline('from %s import %s as %s' %
  658. (module, obj, alias))
  659. else:
  660. self.writeline('import %s as %s' % (imp, alias))
  661. # add the load name
  662. self.writeline('name = %r' % self.name)
  663. # generate the root render function.
  664. self.writeline('def root(context%s):' % envenv, extra=1)
  665. # process the root
  666. frame = Frame(eval_ctx)
  667. frame.inspect(node.body)
  668. frame.toplevel = frame.rootlevel = True
  669. frame.require_output_check = have_extends and not self.has_known_extends
  670. self.indent()
  671. if have_extends:
  672. self.writeline('parent_template = None')
  673. if 'self' in find_undeclared(node.body, ('self',)):
  674. frame.identifiers.add_special('self')
  675. self.writeline('l_self = TemplateReference(context)')
  676. self.pull_locals(frame)
  677. self.pull_dependencies(node.body)
  678. self.blockvisit(node.body, frame)
  679. self.outdent()
  680. # make sure that the parent root is called.
  681. if have_extends:
  682. if not self.has_known_extends:
  683. self.indent()
  684. self.writeline('if parent_template is not None:')
  685. self.indent()
  686. self.writeline('for event in parent_template.'
  687. 'root_render_func(context):')
  688. self.indent()
  689. self.writeline('yield event')
  690. self.outdent(2 + (not self.has_known_extends))
  691. # at this point we now have the blocks collected and can visit them too.
  692. for name, block in iteritems(self.blocks):
  693. block_frame = Frame(eval_ctx)
  694. block_frame.inspect(block.body)
  695. block_frame.block = name
  696. self.writeline('def block_%s(context%s):' % (name, envenv),
  697. block, 1)
  698. self.indent()
  699. undeclared = find_undeclared(block.body, ('self', 'super'))
  700. if 'self' in undeclared:
  701. block_frame.identifiers.add_special('self')
  702. self.writeline('l_self = TemplateReference(context)')
  703. if 'super' in undeclared:
  704. block_frame.identifiers.add_special('super')
  705. self.writeline('l_super = context.super(%r, '
  706. 'block_%s)' % (name, name))
  707. self.pull_locals(block_frame)
  708. self.pull_dependencies(block.body)
  709. self.blockvisit(block.body, block_frame)
  710. self.outdent()
  711. self.writeline('blocks = {%s}' % ', '.join('%r: block_%s' % (x, x)
  712. for x in self.blocks),
  713. extra=1)
  714. # add a function that returns the debug info
  715. self.writeline('debug_info = %r' % '&'.join('%s=%s' % x for x
  716. in self.debug_info))
  717. def visit_Block(self, node, frame):
  718. """Call a block and register it for the template."""
  719. level = 1
  720. if frame.toplevel:
  721. # if we know that we are a child template, there is no need to
  722. # check if we are one
  723. if self.has_known_extends:
  724. return
  725. if self.extends_so_far > 0:
  726. self.writeline('if parent_template is None:')
  727. self.indent()
  728. level += 1
  729. context = node.scoped and 'context.derived(locals())' or 'context'
  730. self.writeline('for event in context.blocks[%r][0](%s):' % (
  731. node.name, context), node)
  732. self.indent()
  733. self.simple_write('event', frame)
  734. self.outdent(level)
  735. def visit_Extends(self, node, frame):
  736. """Calls the extender."""
  737. if not frame.toplevel:
  738. self.fail('cannot use extend from a non top-level scope',
  739. node.lineno)
  740. # if the number of extends statements in general is zero so
  741. # far, we don't have to add a check if something extended
  742. # the template before this one.
  743. if self.extends_so_far > 0:
  744. # if we have a known extends we just add a template runtime
  745. # error into the generated code. We could catch that at compile
  746. # time too, but i welcome it not to confuse users by throwing the
  747. # same error at different times just "because we can".
  748. if not self.has_known_extends:
  749. self.writeline('if parent_template is not None:')
  750. self.indent()
  751. self.writeline('raise TemplateRuntimeError(%r)' %
  752. 'extended multiple times')
  753. # if we have a known extends already we don't need that code here
  754. # as we know that the template execution will end here.
  755. if self.has_known_extends:
  756. raise CompilerExit()
  757. else:
  758. self.outdent()
  759. self.writeline('parent_template = environment.get_template(', node)
  760. self.visit(node.template, frame)
  761. self.write(', %r)' % self.name)
  762. self.writeline('for name, parent_block in parent_template.'
  763. 'blocks.%s():' % dict_item_iter)
  764. self.indent()
  765. self.writeline('context.blocks.setdefault(name, []).'
  766. 'append(parent_block)')
  767. self.outdent()
  768. # if this extends statement was in the root level we can take
  769. # advantage of that information and simplify the generated code
  770. # in the top level from this point onwards
  771. if frame.rootlevel:
  772. self.has_known_extends = True
  773. # and now we have one more
  774. self.extends_so_far += 1
  775. def visit_Include(self, node, frame):
  776. """Handles includes."""
  777. if node.with_context:
  778. self.unoptimize_scope(frame)
  779. if node.ignore_missing:
  780. self.writeline('try:')
  781. self.indent()
  782. func_name = 'get_or_select_template'
  783. if isinstance(node.template, nodes.Const):
  784. if isinstance(node.template.value, string_types):
  785. func_name = 'get_template'
  786. elif isinstance(node.template.value, (tuple, list)):
  787. func_name = 'select_template'
  788. elif isinstance(node.template, (nodes.Tuple, nodes.List)):
  789. func_name = 'select_template'
  790. self.writeline('template = environment.%s(' % func_name, node)
  791. self.visit(node.template, frame)
  792. self.write(', %r)' % self.name)
  793. if node.ignore_missing:
  794. self.outdent()
  795. self.writeline('except TemplateNotFound:')
  796. self.indent()
  797. self.writeline('pass')
  798. self.outdent()
  799. self.writeline('else:')
  800. self.indent()
  801. if node.with_context:
  802. self.writeline('for event in template.root_render_func('
  803. 'template.new_context(context.parent, True, '
  804. 'locals())):')
  805. else:
  806. self.writeline('for event in template.module._body_stream:')
  807. self.indent()
  808. self.simple_write('event', frame)
  809. self.outdent()
  810. if node.ignore_missing:
  811. self.outdent()
  812. def visit_Import(self, node, frame):
  813. """Visit regular imports."""
  814. if node.with_context:
  815. self.unoptimize_scope(frame)
  816. self.writeline('l_%s = ' % node.target, node)
  817. if frame.toplevel:
  818. self.write('context.vars[%r] = ' % node.target)
  819. self.write('environment.get_template(')
  820. self.visit(node.template, frame)
  821. self.write(', %r).' % self.name)
  822. if node.with_context:
  823. self.write('make_module(context.parent, True, locals())')
  824. else:
  825. self.write('module')
  826. if frame.toplevel and not node.target.startswith('_'):
  827. self.writeline('context.exported_vars.discard(%r)' % node.target)
  828. frame.assigned_names.add(node.target)
  829. def visit_FromImport(self, node, frame):
  830. """Visit named imports."""
  831. self.newline(node)
  832. self.write('included_template = environment.get_template(')
  833. self.visit(node.template, frame)
  834. self.write(', %r).' % self.name)
  835. if node.with_context:
  836. self.write('make_module(context.parent, True)')
  837. else:
  838. self.write('module')
  839. var_names = []
  840. discarded_names = []
  841. for name in node.names:
  842. if isinstance(name, tuple):
  843. name, alias = name
  844. else:
  845. alias = name
  846. self.writeline('l_%s = getattr(included_template, '
  847. '%r, missing)' % (alias, name))
  848. self.writeline('if l_%s is missing:' % alias)
  849. self.indent()
  850. self.writeline('l_%s = environment.undefined(%r %% '
  851. 'included_template.__name__, '
  852. 'name=%r)' %
  853. (alias, 'the template %%r (imported on %s) does '
  854. 'not export the requested name %s' % (
  855. self.position(node),
  856. repr(name)
  857. ), name))
  858. self.outdent()
  859. if frame.toplevel:
  860. var_names.append(alias)
  861. if not alias.startswith('_'):
  862. discarded_names.append(alias)
  863. frame.assigned_names.add(alias)
  864. if var_names:
  865. if len(var_names) == 1:
  866. name = var_names[0]
  867. self.writeline('context.vars[%r] = l_%s' % (name, name))
  868. else:
  869. self.writeline('context.vars.update({%s})' % ', '.join(
  870. '%r: l_%s' % (name, name) for name in var_names
  871. ))
  872. if discarded_names:
  873. if len(discarded_names) == 1:
  874. self.writeline('context.exported_vars.discard(%r)' %
  875. discarded_names[0])
  876. else:
  877. self.writeline('context.exported_vars.difference_'
  878. 'update((%s))' % ', '.join(imap(repr, discarded_names)))
  879. def visit_For(self, node, frame):
  880. # when calculating the nodes for the inner frame we have to exclude
  881. # the iterator contents from it
  882. children = node.iter_child_nodes(exclude=('iter',))
  883. if node.recursive:
  884. loop_frame = self.function_scoping(node, frame, children,
  885. find_special=False)
  886. else:
  887. loop_frame = frame.inner()
  888. loop_frame.inspect(children)
  889. # try to figure out if we have an extended loop. An extended loop
  890. # is necessary if the loop is in recursive mode if the special loop
  891. # variable is accessed in the body.
  892. extended_loop = node.recursive or 'loop' in \
  893. find_undeclared(node.iter_child_nodes(
  894. only=('body',)), ('loop',))
  895. # if we don't have an recursive loop we have to find the shadowed
  896. # variables at that point. Because loops can be nested but the loop
  897. # variable is a special one we have to enforce aliasing for it.
  898. if not node.recursive:
  899. aliases = self.push_scope(loop_frame, ('loop',))
  900. # otherwise we set up a buffer and add a function def
  901. else:
  902. self.writeline('def loop(reciter, loop_render_func, depth=0):', node)
  903. self.indent()
  904. self.buffer(loop_frame)
  905. aliases = {}
  906. # make sure the loop variable is a special one and raise a template
  907. # assertion error if a loop tries to write to loop
  908. if extended_loop:
  909. self.writeline('l_loop = missing')
  910. loop_frame.identifiers.add_special('loop')
  911. for name in node.find_all(nodes.Name):
  912. if name.ctx == 'store' and name.name == 'loop':
  913. self.fail('Can\'t assign to special loop variable '
  914. 'in for-loop target', name.lineno)
  915. self.pull_locals(loop_frame)
  916. if node.else_:
  917. iteration_indicator = self.temporary_identifier()
  918. self.writeline('%s = 1' % iteration_indicator)
  919. # Create a fake parent loop if the else or test section of a
  920. # loop is accessing the special loop variable and no parent loop
  921. # exists.
  922. if 'loop' not in aliases and 'loop' in find_undeclared(
  923. node.iter_child_nodes(only=('else_', 'test')), ('loop',)):
  924. self.writeline("l_loop = environment.undefined(%r, name='loop')" %
  925. ("'loop' is undefined. the filter section of a loop as well "
  926. "as the else block don't have access to the special 'loop'"
  927. " variable of the current loop. Because there is no parent "
  928. "loop it's undefined. Happened in loop on %s" %
  929. self.position(node)))
  930. self.writeline('for ', node)
  931. self.visit(node.target, loop_frame)
  932. self.write(extended_loop and ', l_loop in LoopContext(' or ' in ')
  933. # if we have an extened loop and a node test, we filter in the
  934. # "outer frame".
  935. if extended_loop and node.test is not None:
  936. self.write('(')
  937. self.visit(node.target, loop_frame)
  938. self.write(' for ')
  939. self.visit(node.target, loop_frame)
  940. self.write(' in ')
  941. if node.recursive:
  942. self.write('reciter')
  943. else:
  944. self.visit(node.iter, loop_frame)
  945. self.write(' if (')
  946. test_frame = loop_frame.copy()
  947. self.visit(node.test, test_frame)
  948. self.write('))')
  949. elif node.recursive:
  950. self.write('reciter')
  951. else:
  952. self.visit(node.iter, loop_frame)
  953. if node.recursive:
  954. self.write(', loop_render_func, depth):')
  955. else:
  956. self.write(extended_loop and '):' or ':')
  957. # tests in not extended loops become a continue
  958. if not extended_loop and node.test is not None:
  959. self.indent()
  960. self.writeline('if not ')
  961. self.visit(node.test, loop_frame)
  962. self.write(':')
  963. self.indent()
  964. self.writeline('continue')
  965. self.outdent(2)
  966. self.indent()
  967. self.blockvisit(node.body, loop_frame)
  968. if node.else_:
  969. self.writeline('%s = 0' % iteration_indicator)
  970. self.outdent()
  971. if node.else_:
  972. self.writeline('if %s:' % iteration_indicator)
  973. self.indent()
  974. self.blockvisit(node.else_, loop_frame)
  975. self.outdent()
  976. # reset the aliases if there are any.
  977. if not node.recursive:
  978. self.pop_scope(aliases, loop_frame)
  979. # if the node was recursive we have to return the buffer contents
  980. # and start the iteration code
  981. if node.recursive:
  982. self.return_buffer_contents(loop_frame)
  983. self.outdent()
  984. self.start_write(frame, node)
  985. self.write('loop(')
  986. self.visit(node.iter, frame)
  987. self.write(', loop)')
  988. self.end_write(frame)
  989. def visit_If(self, node, frame):
  990. if_frame = frame.soft()
  991. self.writeline('if ', node)
  992. self.visit(node.test, if_frame)
  993. self.write(':')
  994. self.indent()
  995. self.blockvisit(node.body, if_frame)
  996. self.outdent()
  997. if node.else_:
  998. self.writeline('else:')
  999. self.indent()
  1000. self.blockvisit(node.else_, if_frame)
  1001. self.outdent()
  1002. def visit_Macro(self, node, frame):
  1003. macro_frame = self.macro_body(node, frame)
  1004. self.newline()
  1005. if frame.toplevel:
  1006. if not node.name.startswith('_'):
  1007. self.write('context.exported_vars.add(%r)' % node.name)
  1008. self.writeline('context.vars[%r] = ' % node.name)
  1009. self.write('l_%s = ' % node.name)
  1010. self.macro_def(node, macro_frame)
  1011. frame.assigned_names.add(node.name)
  1012. def visit_CallBlock(self, node, frame):
  1013. children = node.iter_child_nodes(exclude=('call',))
  1014. call_frame = self.macro_body(node, frame, children)
  1015. self.writeline('caller = ')
  1016. self.macro_def(node, call_frame)
  1017. self.start_write(frame, node)
  1018. self.visit_Call(node.call, call_frame, forward_caller=True)
  1019. self.end_write(frame)
  1020. def visit_FilterBlock(self, node, frame):
  1021. filter_frame = frame.inner()
  1022. filter_frame.inspect(node.iter_child_nodes())
  1023. aliases = self.push_scope(filter_frame)
  1024. self.pull_locals(filter_frame)
  1025. self.buffer(filter_frame)
  1026. self.blockvisit(node.body, filter_frame)
  1027. self.start_write(frame, node)
  1028. self.visit_Filter(node.filter, filter_frame)
  1029. self.end_write(frame)
  1030. self.pop_scope(aliases, filter_frame)
  1031. def visit_ExprStmt(self, node, frame):
  1032. self.newline(node)
  1033. self.visit(node.node, frame)
  1034. def visit_Output(self, node, frame):
  1035. # if we have a known extends statement, we don't output anything
  1036. # if we are in a require_output_check section
  1037. if self.has_known_extends and frame.require_output_check:
  1038. return
  1039. allow_constant_finalize = True
  1040. if self.environment.finalize:
  1041. func = self.environment.finalize
  1042. if getattr(func, 'contextfunction', False) or \
  1043. getattr(func, 'evalcontextfunction', False):
  1044. allow_constant_finalize = False
  1045. elif getattr(func, 'environmentfunction', False):
  1046. finalize = lambda x: text_type(
  1047. self.environment.finalize(self.environment, x))
  1048. else:
  1049. finalize = lambda x: text_type(self.environment.finalize(x))
  1050. else:
  1051. finalize = text_type
  1052. # if we are inside a frame that requires output checking, we do so
  1053. outdent_later = False
  1054. if frame.require_output_check:
  1055. self.writeline('if parent_template is None:')
  1056. self.indent()
  1057. outdent_later = True
  1058. # try to evaluate as many chunks as possible into a static
  1059. # string at compile time.
  1060. body = []
  1061. for child in node.nodes:
  1062. try:
  1063. if not allow_constant_finalize:
  1064. raise nodes.Impossible()
  1065. const = child.as_const(frame.eval_ctx)
  1066. except nodes.Impossible:
  1067. body.append(child)
  1068. continue
  1069. # the frame can't be volatile here, becaus otherwise the
  1070. # as_const() function would raise an Impossible exception
  1071. # at that point.
  1072. try:
  1073. if frame.eval_ctx.autoescape:
  1074. if hasattr(const, '__html__'):
  1075. const = const.__html__()
  1076. else:
  1077. const = escape(const)
  1078. const = finalize(const)
  1079. except Exception:
  1080. # if something goes wrong here we evaluate the node
  1081. # at runtime for easier debugging
  1082. body.append(child)
  1083. continue
  1084. if body and isinstance(body[-1], list):
  1085. body[-1].append(const)
  1086. else:
  1087. body.append([const])
  1088. # if we have less than 3 nodes or a buffer we yield or extend/append
  1089. if len(body) < 3 or frame.buffer is not None:
  1090. if frame.buffer is not None:
  1091. # for one item we append, for more we extend
  1092. if len(body) == 1:
  1093. self.writeline('%s.append(' % frame.buffer)
  1094. else:
  1095. self.writeline('%s.extend((' % frame.buffer)
  1096. self.indent()
  1097. for item in body:
  1098. if isinstance(item, list):
  1099. val = repr(concat(item))
  1100. if frame.buffer is None:
  1101. self.writeline('yield ' + val)
  1102. else:
  1103. self.writeline(val + ', ')
  1104. else:
  1105. if frame.buffer is None:
  1106. self.writeline('yield ', item)
  1107. else:
  1108. self.newline(item)
  1109. close = 1
  1110. if frame.eval_ctx.volatile:
  1111. self.write('(context.eval_ctx.autoescape and'
  1112. ' escape or to_string)(')
  1113. elif frame.eval_ctx.autoescape:
  1114. self.write('escape(')
  1115. else:
  1116. self.write('to_string(')
  1117. if self.environment.finalize is not None:
  1118. self.write('environment.finalize(')
  1119. if getattr(self.environment.finalize,
  1120. "contextfunction", False):
  1121. self.write('context, ')
  1122. close += 1
  1123. self.visit(item, frame)
  1124. self.write(')' * close)
  1125. if frame.buffer is not None:
  1126. self.write(', ')
  1127. if frame.buffer is not None:
  1128. # close the open parentheses
  1129. self.outdent()
  1130. self.writeline(len(body) == 1 and ')' or '))')
  1131. # otherwise we create a format string as this is faster in that case
  1132. else:
  1133. format = []
  1134. arguments = []
  1135. for item in body:
  1136. if isinstance(item, list):
  1137. format.append(concat(item).replace('%', '%%'))
  1138. else:
  1139. format.append('%s')
  1140. arguments.append(item)
  1141. self.writeline('yield ')
  1142. self.write(repr(concat(format)) + ' % (')
  1143. self.indent()
  1144. for argument in arguments:
  1145. self.newline(argument)
  1146. close = 0
  1147. if frame.eval_ctx.volatile:
  1148. self.write('(context.eval_ctx.autoescape and'
  1149. ' escape or to_string)(')
  1150. close += 1
  1151. elif frame.eval_ctx.autoescape:
  1152. self.write('escape(')
  1153. close += 1
  1154. if self.environment.finalize is not None:
  1155. self.write('environment.finalize(')
  1156. if getattr(self.environment.finalize,
  1157. 'contextfunction', False):
  1158. self.write('context, ')
  1159. elif getattr(self.environment.finalize,
  1160. 'evalcontextfunction', False):
  1161. self.write('context.eval_ctx, ')
  1162. elif getattr(self.environment.finalize,
  1163. 'environmentfunction', False):
  1164. self.write('environment, ')
  1165. close += 1
  1166. self.visit(argument, frame)
  1167. self.write(')' * close + ', ')
  1168. self.outdent()
  1169. self.writeline(')')
  1170. if outdent_later:
  1171. self.outdent()
  1172. def make_assignment_frame(self, frame):
  1173. # toplevel assignments however go into the local namespace and
  1174. # the current template's context. We create a copy of the frame
  1175. # here and add a set so that the Name visitor can add the assigned
  1176. # names here.
  1177. if not frame.toplevel:
  1178. return frame
  1179. assignment_frame = frame.copy()
  1180. assignment_frame.toplevel_assignments = set()
  1181. return assignment_frame
  1182. def export_assigned_vars(self, frame, assignment_frame):
  1183. if not frame.toplevel:
  1184. return
  1185. public_names = [x for x in assignment_frame.toplevel_assignments
  1186. if not x.startswith('_')]
  1187. if len(assignment_frame.toplevel_assignments) == 1:
  1188. name = next(iter(assignment_frame.toplevel_assignments))
  1189. self.writeline('context.vars[%r] = l_%s' % (name, name))
  1190. else:
  1191. self.writeline('context.vars.update({')
  1192. for idx, name in enumerate(assignment_frame.toplevel_assignments):
  1193. if idx:
  1194. self.write(', ')
  1195. self.write('%r: l_%s' % (name, name))
  1196. self.write('})')
  1197. if public_names:
  1198. if len(public_names) == 1:
  1199. self.writeline('context.exported_vars.add(%r)' %
  1200. public_names[0])
  1201. else:
  1202. self.writeline('context.exported_vars.update((%s))' %
  1203. ', '.join(imap(repr, public_names)))
  1204. def visit_Assign(self, node, frame):
  1205. self.newline(node)
  1206. assignment_frame = self.make_assignment_frame(frame)
  1207. self.visit(node.target, assignment_frame)
  1208. self.write(' = ')
  1209. self.visit(node.node, frame)
  1210. self.export_assigned_vars(frame, assignment_frame)
  1211. def visit_AssignBlock(self, node, frame):
  1212. block_frame = frame.inner()
  1213. block_frame.inspect(node.body)
  1214. aliases = self.push_scope(block_frame)
  1215. self.pull_locals(block_frame)
  1216. self.buffer(block_frame)
  1217. self.blockvisit(node.body, block_frame)
  1218. self.pop_scope(aliases, block_frame)
  1219. assignment_frame = self.make_assignment_frame(frame)
  1220. self.newline(node)
  1221. self.visit(node.target, assignment_frame)
  1222. self.write(' = concat(%s)' % block_frame.buffer)
  1223. self.export_assigned_vars(frame, assignment_frame)
  1224. # -- Expression Visitors
  1225. def visit_Name(self, node, frame):
  1226. if node.ctx == 'store' and frame.toplevel:
  1227. frame.toplevel_assignments.add(node.name)
  1228. self.write('l_' + node.name)
  1229. frame.assigned_names.add(node.name)
  1230. def visit_Const(self, node, frame):
  1231. val = node.value
  1232. if isinstance(val, float):
  1233. self.write(str(val))
  1234. else:
  1235. self.write(repr(val))
  1236. def visit_TemplateData(self, node, frame):
  1237. try:
  1238. self.write(repr(node.as_const(frame.eval_ctx)))
  1239. except nodes.Impossible:
  1240. self.write('(context.eval_ctx.autoescape and Markup or identity)(%r)'
  1241. % node.data)
  1242. def visit_Tuple(self, node, frame):
  1243. self.write('(')
  1244. idx = -1
  1245. for idx, item in enumerate(node.items):
  1246. if idx:
  1247. self.write(', ')
  1248. self.visit(item, frame)
  1249. self.write(idx == 0 and ',)' or ')')
  1250. def visit_List(self, node, frame):
  1251. self.write('[')
  1252. for idx, item in enumerate(node.items):
  1253. if idx:
  1254. self.write(', ')
  1255. self.visit(item, frame)
  1256. self.write(']')
  1257. def visit_Dict(self, node, frame):
  1258. self.write('{')
  1259. for idx, item in enumerate(node.items):
  1260. if idx:
  1261. self.write(', ')
  1262. self.visit(item.key, frame)
  1263. self.write(': ')
  1264. self.visit(item.value, frame)
  1265. self.write('}')
  1266. def binop(operator, interceptable=True):
  1267. def visitor(self, node, frame):
  1268. if self.environment.sandboxed and \
  1269. operator in self.environment.intercepted_binops:
  1270. self.write('environment.call_binop(context, %r, ' % operator)
  1271. self.visit(node.left, frame)
  1272. self.write(', ')
  1273. self.visit(node.right, frame)
  1274. else:
  1275. self.write('(')
  1276. self.visit(node.left, frame)
  1277. self.write(' %s ' % operator)
  1278. self.visit(node.right, frame)
  1279. self.write(')')
  1280. return visitor
  1281. def uaop(operator, interceptable=True):
  1282. def visitor(self, node, frame):
  1283. if self.environment.sandboxed and \
  1284. operator in self.environment.intercepted_unops:
  1285. self.write('environment.call_unop(context, %r, ' % operator)
  1286. self.visit(node.node, frame)
  1287. else:
  1288. self.write('(' + operator)
  1289. self.visit(node.node, frame)
  1290. self.write(')')
  1291. return visitor
  1292. visit_Add = binop('+')
  1293. visit_Sub = binop('-')
  1294. visit_Mul = binop('*')
  1295. visit_Div = binop('/')
  1296. visit_FloorDiv = binop('//')
  1297. visit_Pow = binop('**')
  1298. visit_Mod = binop('%')
  1299. visit_And = binop('and', interceptable=False)
  1300. visit_Or = binop('or', interceptable=False)
  1301. visit_Pos = uaop('+')
  1302. visit_Neg = uaop('-')
  1303. visit_Not = uaop('not ', interceptable=False)
  1304. del binop, uaop
  1305. def visit_Concat(self, node, frame):
  1306. if frame.eval_ctx.volatile:
  1307. func_name = '(context.eval_ctx.volatile and' \
  1308. ' markup_join or unicode_join)'
  1309. elif frame.eval_ctx.autoescape:
  1310. func_name = 'markup_join'
  1311. else:
  1312. func_name = 'unicode_join'
  1313. self.write('%s((' % func_name)
  1314. for arg in node.nodes:
  1315. self.visit(arg, frame)
  1316. self.write(', ')
  1317. self.write('))')
  1318. def visit_Compare(self, node, frame):
  1319. self.visit(node.expr, frame)
  1320. for op in node.ops:
  1321. self.visit(op, frame)
  1322. def visit_Operand(self, node, frame):
  1323. self.write(' %s ' % operators[node.op])
  1324. self.visit(node.expr, frame)
  1325. def visit_Getattr(self, node, frame):
  1326. self.write('environment.getattr(')
  1327. self.visit(node.node, frame)
  1328. self.write(', %r)' % node.attr)
  1329. def visit_Getitem(self, node, frame):
  1330. # slices bypass the environment getitem method.
  1331. if isinstance(node.arg, nodes.Slice):
  1332. self.visit(node.node, frame)
  1333. self.write('[')
  1334. self.visit(node.arg, frame)
  1335. self.write(']')
  1336. else:
  1337. self.write('environment.getitem(')
  1338. self.visit(node.node, frame)
  1339. self.write(', ')
  1340. self.visit(node.arg, frame)
  1341. self.write(')')
  1342. def visit_Slice(self, node, frame):
  1343. if node.start is not None:
  1344. self.visit(node.start, frame)
  1345. self.write(':')
  1346. if node.stop is not None:
  1347. self.visit(node.stop, frame)
  1348. if node.step is not None:
  1349. self.write(':')
  1350. self.visit(node.step, frame)
  1351. def visit_Filter(self, node, frame):
  1352. self.write(self.filters[node.name] + '(')
  1353. func = self.environment.filters.get(node.name)
  1354. if func is None:
  1355. self.fail('no filter named %r' % node.name, node.lineno)
  1356. if getattr(func, 'contextfilter', False):
  1357. self.write('context, ')
  1358. elif getattr(func, 'evalcontextfilter', False):
  1359. self.write('context.eval_ctx, ')
  1360. elif getattr(func, 'environmentfilter', False):
  1361. self.write('environment, ')
  1362. # if the filter node is None we are inside a filter block
  1363. # and want to write to the current buffer
  1364. if node.node is not None:
  1365. self.visit(node.node, frame)
  1366. elif frame.eval_ctx.volatile:
  1367. self.write('(context.eval_ctx.autoescape and'
  1368. ' Markup(concat(%s)) or concat(%s))' %
  1369. (frame.buffer, frame.buffer))
  1370. elif frame.eval_ctx.autoescape:
  1371. self.write('Markup(concat(%s))' % frame.buffer)
  1372. else:
  1373. self.write('concat(%s)' % frame.buffer)
  1374. self.signature(node, frame)
  1375. self.write(')')
  1376. def visit_Test(self, node, frame):
  1377. self.write(self.tests[node.name] + '(')
  1378. if node.name not in self.environment.tests:
  1379. self.fail('no test named %r' % node.name, node.lineno)
  1380. self.visit(node.node, frame)
  1381. self.signature(node, frame)
  1382. self.write(')')
  1383. def visit_CondExpr(self, node, frame):
  1384. def write_expr2():
  1385. if node.expr2 is not None:
  1386. return self.visit(node.expr2, frame)
  1387. self.write('environment.undefined(%r)' % ('the inline if-'
  1388. 'expression on %s evaluated to false and '
  1389. 'no else section was defined.' % self.position(node)))
  1390. self.write('(')
  1391. self.visit(node.expr1, frame)
  1392. self.write(' if ')
  1393. self.visit(node.test, frame)
  1394. self.write(' else ')
  1395. write_expr2()
  1396. self.write(')')
  1397. def visit_Call(self, node, frame, forward_caller=False):
  1398. if self.environment.sandboxed:
  1399. self.write('environment.call(context, ')
  1400. else:
  1401. self.write('context.call(')
  1402. self.visit(node.node, frame)
  1403. extra_kwargs = forward_caller and {'caller': 'caller'} or None
  1404. self.signature(node, frame, extra_kwargs)
  1405. self.write(')')
  1406. def visit_Keyword(self, node, frame):
  1407. self.write(node.key + '=')
  1408. self.visit(node.value, frame)
  1409. # -- Unused nodes for extensions
  1410. def visit_MarkSafe(self, node, frame):
  1411. self.write('Markup(')
  1412. self.visit(node.expr, frame)
  1413. self.write(')')
  1414. def visit_MarkSafeIfAutoescape(self, node, frame):
  1415. self.write('(context.eval_ctx.autoescape and Markup or identity)(')
  1416. self.visit(node.expr, frame)
  1417. self.write(')')
  1418. def visit_EnvironmentAttribute(self, node, frame):
  1419. self.write('environment.' + node.name)
  1420. def visit_ExtensionAttribute(self, node, frame):
  1421. self.write('environment.extensions[%r].%s' % (node.identifier, node.name))
  1422. def visit_ImportedName(self, node, frame):
  1423. self.write(self.import_aliases[node.importname])
  1424. def visit_InternalName(self, node, frame):
  1425. self.write(node.name)
  1426. def visit_ContextReference(self, node, frame):
  1427. self.write('context')
  1428. def visit_Continue(self, node, frame):
  1429. self.writeline('continue', node)
  1430. def visit_Break(self, node, frame):
  1431. self.writeline('break', node)
  1432. def visit_Scope(self, node, frame):
  1433. scope_frame = frame.inner()
  1434. scope_frame.inspect(node.iter_child_nodes())
  1435. aliases = self.push_scope(scope_frame)
  1436. self.pull_locals(scope_frame)
  1437. self.blockvisit(node.body, scope_frame)
  1438. self.pop_scope(aliases, scope_frame)
  1439. def visit_EvalContextModifier(self, node, frame):
  1440. for keyword in node.options:
  1441. self.writeline('context.eval_ctx.%s = ' % keyword.key)
  1442. self.visit(keyword.value, frame)
  1443. try:
  1444. val = keyword.value.as_const(frame.eval_ctx)
  1445. except nodes.Impossible:
  1446. frame.eval_ctx.volatile = True
  1447. else:
  1448. setattr(frame.eval_ctx, keyword.key, val)
  1449. def visit_ScopedEvalContextModifier(self, node, frame):
  1450. old_ctx_name = self.temporary_identifier()
  1451. safed_ctx = frame.eval_ctx.save()
  1452. self.writeline('%s = context.eval_ctx.save()' % old_ctx_name)
  1453. self.visit_EvalContextModifier(node, frame)
  1454. for child in node.body:
  1455. self.visit(child, frame)
  1456. frame.eval_ctx.revert(safed_ctx)
  1457. self.writeline('context.eval_ctx.revert(%s)' % old_ctx_name)