You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1104 lines
34KB

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