runtime.py 33 KB

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