runtime.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  1. """The runtime functions and state used by compiled templates."""
  2. import functools
  3. import sys
  4. import typing as t
  5. from collections import abc
  6. from itertools import chain
  7. from markupsafe import escape # noqa: F401
  8. from markupsafe import Markup
  9. from markupsafe import soft_str
  10. from .async_utils import auto_aiter
  11. from .async_utils import auto_await # noqa: F401
  12. from .exceptions import TemplateNotFound # noqa: F401
  13. from .exceptions import TemplateRuntimeError # noqa: F401
  14. from .exceptions import UndefinedError
  15. from .nodes import EvalContext
  16. from .utils import _PassArg
  17. from .utils import concat
  18. from .utils import internalcode
  19. from .utils import missing
  20. from .utils import Namespace # noqa: F401
  21. from .utils import object_type_repr
  22. from .utils import pass_eval_context
  23. V = t.TypeVar("V")
  24. F = t.TypeVar("F", bound=t.Callable[..., t.Any])
  25. if t.TYPE_CHECKING:
  26. import logging
  27. import typing_extensions as te
  28. from .environment import Environment
  29. class LoopRenderFunc(te.Protocol):
  30. def __call__(
  31. self,
  32. reciter: t.Iterable[V],
  33. loop_render_func: "LoopRenderFunc",
  34. depth: int = 0,
  35. ) -> str:
  36. ...
  37. # these variables are exported to the template runtime
  38. exported = [
  39. "LoopContext",
  40. "TemplateReference",
  41. "Macro",
  42. "Markup",
  43. "TemplateRuntimeError",
  44. "missing",
  45. "escape",
  46. "markup_join",
  47. "str_join",
  48. "identity",
  49. "TemplateNotFound",
  50. "Namespace",
  51. "Undefined",
  52. "internalcode",
  53. ]
  54. async_exported = [
  55. "AsyncLoopContext",
  56. "auto_aiter",
  57. "auto_await",
  58. ]
  59. def identity(x: V) -> V:
  60. """Returns its argument. Useful for certain things in the
  61. environment.
  62. """
  63. return x
  64. def markup_join(seq: t.Iterable[t.Any]) -> str:
  65. """Concatenation that escapes if necessary and converts to string."""
  66. buf = []
  67. iterator = map(soft_str, seq)
  68. for arg in iterator:
  69. buf.append(arg)
  70. if hasattr(arg, "__html__"):
  71. return Markup("").join(chain(buf, iterator))
  72. return concat(buf)
  73. def str_join(seq: t.Iterable[t.Any]) -> str:
  74. """Simple args to string conversion and concatenation."""
  75. return concat(map(str, seq))
  76. def new_context(
  77. environment: "Environment",
  78. template_name: t.Optional[str],
  79. blocks: t.Dict[str, t.Callable[["Context"], t.Iterator[str]]],
  80. vars: t.Optional[t.Dict[str, t.Any]] = None,
  81. shared: bool = False,
  82. globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
  83. locals: t.Optional[t.Mapping[str, t.Any]] = None,
  84. ) -> "Context":
  85. """Internal helper for context creation."""
  86. if vars is None:
  87. vars = {}
  88. if shared:
  89. parent = vars
  90. else:
  91. parent = dict(globals or (), **vars)
  92. if locals:
  93. # if the parent is shared a copy should be created because
  94. # we don't want to modify the dict passed
  95. if shared:
  96. parent = dict(parent)
  97. for key, value in locals.items():
  98. if value is not missing:
  99. parent[key] = value
  100. return environment.context_class(
  101. environment, parent, template_name, blocks, globals=globals
  102. )
  103. class TemplateReference:
  104. """The `self` in templates."""
  105. def __init__(self, context: "Context") -> None:
  106. self.__context = context
  107. def __getitem__(self, name: str) -> t.Any:
  108. blocks = self.__context.blocks[name]
  109. return BlockReference(name, self.__context, blocks, 0)
  110. def __repr__(self) -> str:
  111. return f"<{type(self).__name__} {self.__context.name!r}>"
  112. def _dict_method_all(dict_method: F) -> F:
  113. @functools.wraps(dict_method)
  114. def f_all(self: "Context") -> t.Any:
  115. return dict_method(self.get_all())
  116. return t.cast(F, f_all)
  117. @abc.Mapping.register
  118. class Context:
  119. """The template context holds the variables of a template. It stores the
  120. values passed to the template and also the names the template exports.
  121. Creating instances is neither supported nor useful as it's created
  122. automatically at various stages of the template evaluation and should not
  123. be created by hand.
  124. The context is immutable. Modifications on :attr:`parent` **must not**
  125. happen and modifications on :attr:`vars` are allowed from generated
  126. template code only. Template filters and global functions marked as
  127. :func:`pass_context` get the active context passed as first argument
  128. and are allowed to access the context read-only.
  129. The template context supports read only dict operations (`get`,
  130. `keys`, `values`, `items`, `iterkeys`, `itervalues`, `iteritems`,
  131. `__getitem__`, `__contains__`). Additionally there is a :meth:`resolve`
  132. method that doesn't fail with a `KeyError` but returns an
  133. :class:`Undefined` object for missing variables.
  134. """
  135. def __init__(
  136. self,
  137. environment: "Environment",
  138. parent: t.Dict[str, t.Any],
  139. name: t.Optional[str],
  140. blocks: t.Dict[str, t.Callable[["Context"], t.Iterator[str]]],
  141. globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
  142. ):
  143. self.parent = parent
  144. self.vars: t.Dict[str, t.Any] = {}
  145. self.environment: "Environment" = environment
  146. self.eval_ctx = EvalContext(self.environment, name)
  147. self.exported_vars: t.Set[str] = set()
  148. self.name = name
  149. self.globals_keys = set() if globals is None else set(globals)
  150. # create the initial mapping of blocks. Whenever template inheritance
  151. # takes place the runtime will update this mapping with the new blocks
  152. # from the template.
  153. self.blocks = {k: [v] for k, v in blocks.items()}
  154. def super(
  155. self, name: str, current: t.Callable[["Context"], t.Iterator[str]]
  156. ) -> t.Union["BlockReference", "Undefined"]:
  157. """Render a parent block."""
  158. try:
  159. blocks = self.blocks[name]
  160. index = blocks.index(current) + 1
  161. blocks[index]
  162. except LookupError:
  163. return self.environment.undefined(
  164. f"there is no parent block called {name!r}.", name="super"
  165. )
  166. return BlockReference(name, self, blocks, index)
  167. def get(self, key: str, default: t.Any = None) -> t.Any:
  168. """Look up a variable by name, or return a default if the key is
  169. not found.
  170. :param key: The variable name to look up.
  171. :param default: The value to return if the key is not found.
  172. """
  173. try:
  174. return self[key]
  175. except KeyError:
  176. return default
  177. def resolve(self, key: str) -> t.Union[t.Any, "Undefined"]:
  178. """Look up a variable by name, or return an :class:`Undefined`
  179. object if the key is not found.
  180. If you need to add custom behavior, override
  181. :meth:`resolve_or_missing`, not this method. The various lookup
  182. functions use that method, not this one.
  183. :param key: The variable name to look up.
  184. """
  185. rv = self.resolve_or_missing(key)
  186. if rv is missing:
  187. return self.environment.undefined(name=key)
  188. return rv
  189. def resolve_or_missing(self, key: str) -> t.Any:
  190. """Look up a variable by name, or return a ``missing`` sentinel
  191. if the key is not found.
  192. Override this method to add custom lookup behavior.
  193. :meth:`resolve`, :meth:`get`, and :meth:`__getitem__` use this
  194. method. Don't call this method directly.
  195. :param key: The variable name to look up.
  196. """
  197. if key in self.vars:
  198. return self.vars[key]
  199. if key in self.parent:
  200. return self.parent[key]
  201. return missing
  202. def get_exported(self) -> t.Dict[str, t.Any]:
  203. """Get a new dict with the exported variables."""
  204. return {k: self.vars[k] for k in self.exported_vars}
  205. def get_all(self) -> t.Dict[str, t.Any]:
  206. """Return the complete context as dict including the exported
  207. variables. For optimizations reasons this might not return an
  208. actual copy so be careful with using it.
  209. """
  210. if not self.vars:
  211. return self.parent
  212. if not self.parent:
  213. return self.vars
  214. return dict(self.parent, **self.vars)
  215. @internalcode
  216. def call(
  217. __self, __obj: t.Callable, *args: t.Any, **kwargs: t.Any # noqa: B902
  218. ) -> t.Union[t.Any, "Undefined"]:
  219. """Call the callable with the arguments and keyword arguments
  220. provided but inject the active context or environment as first
  221. argument if the callable has :func:`pass_context` or
  222. :func:`pass_environment`.
  223. """
  224. if __debug__:
  225. __traceback_hide__ = True # noqa
  226. # Allow callable classes to take a context
  227. if (
  228. hasattr(__obj, "__call__") # noqa: B004
  229. and _PassArg.from_obj(__obj.__call__) is not None # type: ignore
  230. ):
  231. __obj = __obj.__call__ # type: ignore
  232. pass_arg = _PassArg.from_obj(__obj)
  233. if pass_arg is _PassArg.context:
  234. # the active context should have access to variables set in
  235. # loops and blocks without mutating the context itself
  236. if kwargs.get("_loop_vars"):
  237. __self = __self.derived(kwargs["_loop_vars"])
  238. if kwargs.get("_block_vars"):
  239. __self = __self.derived(kwargs["_block_vars"])
  240. args = (__self,) + args
  241. elif pass_arg is _PassArg.eval_context:
  242. args = (__self.eval_ctx,) + args
  243. elif pass_arg is _PassArg.environment:
  244. args = (__self.environment,) + args
  245. kwargs.pop("_block_vars", None)
  246. kwargs.pop("_loop_vars", None)
  247. try:
  248. return __obj(*args, **kwargs)
  249. except StopIteration:
  250. return __self.environment.undefined(
  251. "value was undefined because a callable raised a"
  252. " StopIteration exception"
  253. )
  254. def derived(self, locals: t.Optional[t.Dict[str, t.Any]] = None) -> "Context":
  255. """Internal helper function to create a derived context. This is
  256. used in situations where the system needs a new context in the same
  257. template that is independent.
  258. """
  259. context = new_context(
  260. self.environment, self.name, {}, self.get_all(), True, None, locals
  261. )
  262. context.eval_ctx = self.eval_ctx
  263. context.blocks.update((k, list(v)) for k, v in self.blocks.items())
  264. return context
  265. keys = _dict_method_all(dict.keys)
  266. values = _dict_method_all(dict.values)
  267. items = _dict_method_all(dict.items)
  268. def __contains__(self, name: str) -> bool:
  269. return name in self.vars or name in self.parent
  270. def __getitem__(self, key: str) -> t.Any:
  271. """Look up a variable by name with ``[]`` syntax, or raise a
  272. ``KeyError`` if the key is not found.
  273. """
  274. item = self.resolve_or_missing(key)
  275. if item is missing:
  276. raise KeyError(key)
  277. return item
  278. def __repr__(self) -> str:
  279. return f"<{type(self).__name__} {self.get_all()!r} of {self.name!r}>"
  280. class BlockReference:
  281. """One block on a template reference."""
  282. def __init__(
  283. self,
  284. name: str,
  285. context: "Context",
  286. stack: t.List[t.Callable[["Context"], t.Iterator[str]]],
  287. depth: int,
  288. ) -> None:
  289. self.name = name
  290. self._context = context
  291. self._stack = stack
  292. self._depth = depth
  293. @property
  294. def super(self) -> t.Union["BlockReference", "Undefined"]:
  295. """Super the block."""
  296. if self._depth + 1 >= len(self._stack):
  297. return self._context.environment.undefined(
  298. f"there is no parent block called {self.name!r}.", name="super"
  299. )
  300. return BlockReference(self.name, self._context, self._stack, self._depth + 1)
  301. @internalcode
  302. async def _async_call(self) -> str:
  303. rv = concat(
  304. [x async for x in self._stack[self._depth](self._context)] # type: ignore
  305. )
  306. if self._context.eval_ctx.autoescape:
  307. return Markup(rv)
  308. return rv
  309. @internalcode
  310. def __call__(self) -> str:
  311. if self._context.environment.is_async:
  312. return self._async_call() # type: ignore
  313. rv = concat(self._stack[self._depth](self._context))
  314. if self._context.eval_ctx.autoescape:
  315. return Markup(rv)
  316. return rv
  317. class LoopContext:
  318. """A wrapper iterable for dynamic ``for`` loops, with information
  319. about the loop and iteration.
  320. """
  321. #: Current iteration of the loop, starting at 0.
  322. index0 = -1
  323. _length: t.Optional[int] = None
  324. _after: t.Any = missing
  325. _current: t.Any = missing
  326. _before: t.Any = missing
  327. _last_changed_value: t.Any = missing
  328. def __init__(
  329. self,
  330. iterable: t.Iterable[V],
  331. undefined: t.Type["Undefined"],
  332. recurse: t.Optional["LoopRenderFunc"] = None,
  333. depth0: int = 0,
  334. ) -> None:
  335. """
  336. :param iterable: Iterable to wrap.
  337. :param undefined: :class:`Undefined` class to use for next and
  338. previous items.
  339. :param recurse: The function to render the loop body when the
  340. loop is marked recursive.
  341. :param depth0: Incremented when looping recursively.
  342. """
  343. self._iterable = iterable
  344. self._iterator = self._to_iterator(iterable)
  345. self._undefined = undefined
  346. self._recurse = recurse
  347. #: How many levels deep a recursive loop currently is, starting at 0.
  348. self.depth0 = depth0
  349. @staticmethod
  350. def _to_iterator(iterable: t.Iterable[V]) -> t.Iterator[V]:
  351. return iter(iterable)
  352. @property
  353. def length(self) -> int:
  354. """Length of the iterable.
  355. If the iterable is a generator or otherwise does not have a
  356. size, it is eagerly evaluated to get a size.
  357. """
  358. if self._length is not None:
  359. return self._length
  360. try:
  361. self._length = len(self._iterable) # type: ignore
  362. except TypeError:
  363. iterable = list(self._iterator)
  364. self._iterator = self._to_iterator(iterable)
  365. self._length = len(iterable) + self.index + (self._after is not missing)
  366. return self._length
  367. def __len__(self) -> int:
  368. return self.length
  369. @property
  370. def depth(self) -> int:
  371. """How many levels deep a recursive loop currently is, starting at 1."""
  372. return self.depth0 + 1
  373. @property
  374. def index(self) -> int:
  375. """Current iteration of the loop, starting at 1."""
  376. return self.index0 + 1
  377. @property
  378. def revindex0(self) -> int:
  379. """Number of iterations from the end of the loop, ending at 0.
  380. Requires calculating :attr:`length`.
  381. """
  382. return self.length - self.index
  383. @property
  384. def revindex(self) -> int:
  385. """Number of iterations from the end of the loop, ending at 1.
  386. Requires calculating :attr:`length`.
  387. """
  388. return self.length - self.index0
  389. @property
  390. def first(self) -> bool:
  391. """Whether this is the first iteration of the loop."""
  392. return self.index0 == 0
  393. def _peek_next(self) -> t.Any:
  394. """Return the next element in the iterable, or :data:`missing`
  395. if the iterable is exhausted. Only peeks one item ahead, caching
  396. the result in :attr:`_last` for use in subsequent checks. The
  397. cache is reset when :meth:`__next__` is called.
  398. """
  399. if self._after is not missing:
  400. return self._after
  401. self._after = next(self._iterator, missing)
  402. return self._after
  403. @property
  404. def last(self) -> bool:
  405. """Whether this is the last iteration of the loop.
  406. Causes the iterable to advance early. See
  407. :func:`itertools.groupby` for issues this can cause.
  408. The :func:`groupby` filter avoids that issue.
  409. """
  410. return self._peek_next() is missing
  411. @property
  412. def previtem(self) -> t.Union[t.Any, "Undefined"]:
  413. """The item in the previous iteration. Undefined during the
  414. first iteration.
  415. """
  416. if self.first:
  417. return self._undefined("there is no previous item")
  418. return self._before
  419. @property
  420. def nextitem(self) -> t.Union[t.Any, "Undefined"]:
  421. """The item in the next iteration. Undefined during the last
  422. iteration.
  423. Causes the iterable to advance early. See
  424. :func:`itertools.groupby` for issues this can cause.
  425. The :func:`jinja-filters.groupby` filter avoids that issue.
  426. """
  427. rv = self._peek_next()
  428. if rv is missing:
  429. return self._undefined("there is no next item")
  430. return rv
  431. def cycle(self, *args: V) -> V:
  432. """Return a value from the given args, cycling through based on
  433. the current :attr:`index0`.
  434. :param args: One or more values to cycle through.
  435. """
  436. if not args:
  437. raise TypeError("no items for cycling given")
  438. return args[self.index0 % len(args)]
  439. def changed(self, *value: t.Any) -> bool:
  440. """Return ``True`` if previously called with a different value
  441. (including when called for the first time).
  442. :param value: One or more values to compare to the last call.
  443. """
  444. if self._last_changed_value != value:
  445. self._last_changed_value = value
  446. return True
  447. return False
  448. def __iter__(self) -> "LoopContext":
  449. return self
  450. def __next__(self) -> t.Tuple[t.Any, "LoopContext"]:
  451. if self._after is not missing:
  452. rv = self._after
  453. self._after = missing
  454. else:
  455. rv = next(self._iterator)
  456. self.index0 += 1
  457. self._before = self._current
  458. self._current = rv
  459. return rv, self
  460. @internalcode
  461. def __call__(self, iterable: t.Iterable[V]) -> str:
  462. """When iterating over nested data, render the body of the loop
  463. recursively with the given inner iterable data.
  464. The loop must have the ``recursive`` marker for this to work.
  465. """
  466. if self._recurse is None:
  467. raise TypeError(
  468. "The loop must have the 'recursive' marker to be called recursively."
  469. )
  470. return self._recurse(iterable, self._recurse, depth=self.depth)
  471. def __repr__(self) -> str:
  472. return f"<{type(self).__name__} {self.index}/{self.length}>"
  473. class AsyncLoopContext(LoopContext):
  474. _iterator: t.AsyncIterator[t.Any] # type: ignore
  475. @staticmethod
  476. def _to_iterator( # type: ignore
  477. iterable: t.Union[t.Iterable[V], t.AsyncIterable[V]]
  478. ) -> t.AsyncIterator[V]:
  479. return auto_aiter(iterable)
  480. @property
  481. async def length(self) -> int: # type: ignore
  482. if self._length is not None:
  483. return self._length
  484. try:
  485. self._length = len(self._iterable) # type: ignore
  486. except TypeError:
  487. iterable = [x async for x in self._iterator]
  488. self._iterator = self._to_iterator(iterable)
  489. self._length = len(iterable) + self.index + (self._after is not missing)
  490. return self._length
  491. @property
  492. async def revindex0(self) -> int: # type: ignore
  493. return await self.length - self.index
  494. @property
  495. async def revindex(self) -> int: # type: ignore
  496. return await self.length - self.index0
  497. async def _peek_next(self) -> t.Any:
  498. if self._after is not missing:
  499. return self._after
  500. try:
  501. self._after = await self._iterator.__anext__()
  502. except StopAsyncIteration:
  503. self._after = missing
  504. return self._after
  505. @property
  506. async def last(self) -> bool: # type: ignore
  507. return await self._peek_next() is missing
  508. @property
  509. async def nextitem(self) -> t.Union[t.Any, "Undefined"]:
  510. rv = await self._peek_next()
  511. if rv is missing:
  512. return self._undefined("there is no next item")
  513. return rv
  514. def __aiter__(self) -> "AsyncLoopContext":
  515. return self
  516. async def __anext__(self) -> t.Tuple[t.Any, "AsyncLoopContext"]:
  517. if self._after is not missing:
  518. rv = self._after
  519. self._after = missing
  520. else:
  521. rv = await self._iterator.__anext__()
  522. self.index0 += 1
  523. self._before = self._current
  524. self._current = rv
  525. return rv, self
  526. class Macro:
  527. """Wraps a macro function."""
  528. def __init__(
  529. self,
  530. environment: "Environment",
  531. func: t.Callable[..., str],
  532. name: str,
  533. arguments: t.List[str],
  534. catch_kwargs: bool,
  535. catch_varargs: bool,
  536. caller: bool,
  537. default_autoescape: t.Optional[bool] = None,
  538. ):
  539. self._environment = environment
  540. self._func = func
  541. self._argument_count = len(arguments)
  542. self.name = name
  543. self.arguments = arguments
  544. self.catch_kwargs = catch_kwargs
  545. self.catch_varargs = catch_varargs
  546. self.caller = caller
  547. self.explicit_caller = "caller" in arguments
  548. if default_autoescape is None:
  549. if callable(environment.autoescape):
  550. default_autoescape = environment.autoescape(None)
  551. else:
  552. default_autoescape = environment.autoescape
  553. self._default_autoescape = default_autoescape
  554. @internalcode
  555. @pass_eval_context
  556. def __call__(self, *args: t.Any, **kwargs: t.Any) -> str:
  557. # This requires a bit of explanation, In the past we used to
  558. # decide largely based on compile-time information if a macro is
  559. # safe or unsafe. While there was a volatile mode it was largely
  560. # unused for deciding on escaping. This turns out to be
  561. # problematic for macros because whether a macro is safe depends not
  562. # on the escape mode when it was defined, but rather when it was used.
  563. #
  564. # Because however we export macros from the module system and
  565. # there are historic callers that do not pass an eval context (and
  566. # will continue to not pass one), we need to perform an instance
  567. # check here.
  568. #
  569. # This is considered safe because an eval context is not a valid
  570. # argument to callables otherwise anyway. Worst case here is
  571. # that if no eval context is passed we fall back to the compile
  572. # time autoescape flag.
  573. if args and isinstance(args[0], EvalContext):
  574. autoescape = args[0].autoescape
  575. args = args[1:]
  576. else:
  577. autoescape = self._default_autoescape
  578. # try to consume the positional arguments
  579. arguments = list(args[: self._argument_count])
  580. off = len(arguments)
  581. # For information why this is necessary refer to the handling
  582. # of caller in the `macro_body` handler in the compiler.
  583. found_caller = False
  584. # if the number of arguments consumed is not the number of
  585. # arguments expected we start filling in keyword arguments
  586. # and defaults.
  587. if off != self._argument_count:
  588. for name in self.arguments[len(arguments) :]:
  589. try:
  590. value = kwargs.pop(name)
  591. except KeyError:
  592. value = missing
  593. if name == "caller":
  594. found_caller = True
  595. arguments.append(value)
  596. else:
  597. found_caller = self.explicit_caller
  598. # it's important that the order of these arguments does not change
  599. # if not also changed in the compiler's `function_scoping` method.
  600. # the order is caller, keyword arguments, positional arguments!
  601. if self.caller and not found_caller:
  602. caller = kwargs.pop("caller", None)
  603. if caller is None:
  604. caller = self._environment.undefined("No caller defined", name="caller")
  605. arguments.append(caller)
  606. if self.catch_kwargs:
  607. arguments.append(kwargs)
  608. elif kwargs:
  609. if "caller" in kwargs:
  610. raise TypeError(
  611. f"macro {self.name!r} was invoked with two values for the special"
  612. " caller argument. This is most likely a bug."
  613. )
  614. raise TypeError(
  615. f"macro {self.name!r} takes no keyword argument {next(iter(kwargs))!r}"
  616. )
  617. if self.catch_varargs:
  618. arguments.append(args[self._argument_count :])
  619. elif len(args) > self._argument_count:
  620. raise TypeError(
  621. f"macro {self.name!r} takes not more than"
  622. f" {len(self.arguments)} argument(s)"
  623. )
  624. return self._invoke(arguments, autoescape)
  625. async def _async_invoke(self, arguments: t.List[t.Any], autoescape: bool) -> str:
  626. rv = await self._func(*arguments) # type: ignore
  627. if autoescape:
  628. return Markup(rv)
  629. return rv # type: ignore
  630. def _invoke(self, arguments: t.List[t.Any], autoescape: bool) -> str:
  631. if self._environment.is_async:
  632. return self._async_invoke(arguments, autoescape) # type: ignore
  633. rv = self._func(*arguments)
  634. if autoescape:
  635. rv = Markup(rv)
  636. return rv
  637. def __repr__(self) -> str:
  638. name = "anonymous" if self.name is None else repr(self.name)
  639. return f"<{type(self).__name__} {name}>"
  640. class Undefined:
  641. """The default undefined type. This undefined type can be printed and
  642. iterated over, but every other access will raise an :exc:`UndefinedError`:
  643. >>> foo = Undefined(name='foo')
  644. >>> str(foo)
  645. ''
  646. >>> not foo
  647. True
  648. >>> foo + 42
  649. Traceback (most recent call last):
  650. ...
  651. jinja2.exceptions.UndefinedError: 'foo' is undefined
  652. """
  653. __slots__ = (
  654. "_undefined_hint",
  655. "_undefined_obj",
  656. "_undefined_name",
  657. "_undefined_exception",
  658. )
  659. def __init__(
  660. self,
  661. hint: t.Optional[str] = None,
  662. obj: t.Any = missing,
  663. name: t.Optional[str] = None,
  664. exc: t.Type[TemplateRuntimeError] = UndefinedError,
  665. ) -> None:
  666. self._undefined_hint = hint
  667. self._undefined_obj = obj
  668. self._undefined_name = name
  669. self._undefined_exception = exc
  670. @property
  671. def _undefined_message(self) -> str:
  672. """Build a message about the undefined value based on how it was
  673. accessed.
  674. """
  675. if self._undefined_hint:
  676. return self._undefined_hint
  677. if self._undefined_obj is missing:
  678. return f"{self._undefined_name!r} is undefined"
  679. if not isinstance(self._undefined_name, str):
  680. return (
  681. f"{object_type_repr(self._undefined_obj)} has no"
  682. f" element {self._undefined_name!r}"
  683. )
  684. return (
  685. f"{object_type_repr(self._undefined_obj)!r} has no"
  686. f" attribute {self._undefined_name!r}"
  687. )
  688. @internalcode
  689. def _fail_with_undefined_error(
  690. self, *args: t.Any, **kwargs: t.Any
  691. ) -> "te.NoReturn":
  692. """Raise an :exc:`UndefinedError` when operations are performed
  693. on the undefined value.
  694. """
  695. raise self._undefined_exception(self._undefined_message)
  696. @internalcode
  697. def __getattr__(self, name: str) -> t.Any:
  698. if name[:2] == "__":
  699. raise AttributeError(name)
  700. return self._fail_with_undefined_error()
  701. __add__ = __radd__ = __sub__ = __rsub__ = _fail_with_undefined_error
  702. __mul__ = __rmul__ = __div__ = __rdiv__ = _fail_with_undefined_error
  703. __truediv__ = __rtruediv__ = _fail_with_undefined_error
  704. __floordiv__ = __rfloordiv__ = _fail_with_undefined_error
  705. __mod__ = __rmod__ = _fail_with_undefined_error
  706. __pos__ = __neg__ = _fail_with_undefined_error
  707. __call__ = __getitem__ = _fail_with_undefined_error
  708. __lt__ = __le__ = __gt__ = __ge__ = _fail_with_undefined_error
  709. __int__ = __float__ = __complex__ = _fail_with_undefined_error
  710. __pow__ = __rpow__ = _fail_with_undefined_error
  711. def __eq__(self, other: t.Any) -> bool:
  712. return type(self) is type(other)
  713. def __ne__(self, other: t.Any) -> bool:
  714. return not self.__eq__(other)
  715. def __hash__(self) -> int:
  716. return id(type(self))
  717. def __str__(self) -> str:
  718. return ""
  719. def __len__(self) -> int:
  720. return 0
  721. def __iter__(self) -> t.Iterator[t.Any]:
  722. yield from ()
  723. async def __aiter__(self) -> t.AsyncIterator[t.Any]:
  724. for _ in ():
  725. yield
  726. def __bool__(self) -> bool:
  727. return False
  728. def __repr__(self) -> str:
  729. return "Undefined"
  730. def make_logging_undefined(
  731. logger: t.Optional["logging.Logger"] = None, base: t.Type[Undefined] = Undefined
  732. ) -> t.Type[Undefined]:
  733. """Given a logger object this returns a new undefined class that will
  734. log certain failures. It will log iterations and printing. If no
  735. logger is given a default logger is created.
  736. Example::
  737. logger = logging.getLogger(__name__)
  738. LoggingUndefined = make_logging_undefined(
  739. logger=logger,
  740. base=Undefined
  741. )
  742. .. versionadded:: 2.8
  743. :param logger: the logger to use. If not provided, a default logger
  744. is created.
  745. :param base: the base class to add logging functionality to. This
  746. defaults to :class:`Undefined`.
  747. """
  748. if logger is None:
  749. import logging
  750. logger = logging.getLogger(__name__)
  751. logger.addHandler(logging.StreamHandler(sys.stderr))
  752. def _log_message(undef: Undefined) -> None:
  753. logger.warning( # type: ignore
  754. "Template variable warning: %s", undef._undefined_message
  755. )
  756. class LoggingUndefined(base): # type: ignore
  757. __slots__ = ()
  758. def _fail_with_undefined_error( # type: ignore
  759. self, *args: t.Any, **kwargs: t.Any
  760. ) -> "te.NoReturn":
  761. try:
  762. super()._fail_with_undefined_error(*args, **kwargs)
  763. except self._undefined_exception as e:
  764. logger.error("Template variable error: %s", e) # type: ignore
  765. raise e
  766. def __str__(self) -> str:
  767. _log_message(self)
  768. return super().__str__() # type: ignore
  769. def __iter__(self) -> t.Iterator[t.Any]:
  770. _log_message(self)
  771. return super().__iter__() # type: ignore
  772. def __bool__(self) -> bool:
  773. _log_message(self)
  774. return super().__bool__() # type: ignore
  775. return LoggingUndefined
  776. class ChainableUndefined(Undefined):
  777. """An undefined that is chainable, where both ``__getattr__`` and
  778. ``__getitem__`` return itself rather than raising an
  779. :exc:`UndefinedError`.
  780. >>> foo = ChainableUndefined(name='foo')
  781. >>> str(foo.bar['baz'])
  782. ''
  783. >>> foo.bar['baz'] + 42
  784. Traceback (most recent call last):
  785. ...
  786. jinja2.exceptions.UndefinedError: 'foo' is undefined
  787. .. versionadded:: 2.11.0
  788. """
  789. __slots__ = ()
  790. def __html__(self) -> str:
  791. return str(self)
  792. def __getattr__(self, _: str) -> "ChainableUndefined":
  793. return self
  794. __getitem__ = __getattr__ # type: ignore
  795. class DebugUndefined(Undefined):
  796. """An undefined that returns the debug info when printed.
  797. >>> foo = DebugUndefined(name='foo')
  798. >>> str(foo)
  799. '{{ foo }}'
  800. >>> not foo
  801. True
  802. >>> foo + 42
  803. Traceback (most recent call last):
  804. ...
  805. jinja2.exceptions.UndefinedError: 'foo' is undefined
  806. """
  807. __slots__ = ()
  808. def __str__(self) -> str:
  809. if self._undefined_hint:
  810. message = f"undefined value printed: {self._undefined_hint}"
  811. elif self._undefined_obj is missing:
  812. message = self._undefined_name # type: ignore
  813. else:
  814. message = (
  815. f"no such element: {object_type_repr(self._undefined_obj)}"
  816. f"[{self._undefined_name!r}]"
  817. )
  818. return f"{{{{ {message} }}}}"
  819. class StrictUndefined(Undefined):
  820. """An undefined that barks on print and iteration as well as boolean
  821. tests and all kinds of comparisons. In other words: you can do nothing
  822. with it except checking if it's defined using the `defined` test.
  823. >>> foo = StrictUndefined(name='foo')
  824. >>> str(foo)
  825. Traceback (most recent call last):
  826. ...
  827. jinja2.exceptions.UndefinedError: 'foo' is undefined
  828. >>> not foo
  829. Traceback (most recent call last):
  830. ...
  831. jinja2.exceptions.UndefinedError: 'foo' is undefined
  832. >>> foo + 42
  833. Traceback (most recent call last):
  834. ...
  835. jinja2.exceptions.UndefinedError: 'foo' is undefined
  836. """
  837. __slots__ = ()
  838. __iter__ = __str__ = __len__ = Undefined._fail_with_undefined_error
  839. __eq__ = __ne__ = __bool__ = __hash__ = Undefined._fail_with_undefined_error
  840. __contains__ = Undefined._fail_with_undefined_error
  841. # Remove slots attributes, after the metaclass is applied they are
  842. # unneeded and contain wrong data for subclasses.
  843. del (
  844. Undefined.__slots__,
  845. ChainableUndefined.__slots__,
  846. DebugUndefined.__slots__,
  847. StrictUndefined.__slots__,
  848. )