| 687 | @internalcode |
| 688 | @pass_eval_context |
| 689 | def __call__(self, *args: t.Any, **kwargs: t.Any) -> str: |
| 690 | # This requires a bit of explanation, In the past we used to |
| 691 | # decide largely based on compile-time information if a macro is |
| 692 | # safe or unsafe. While there was a volatile mode it was largely |
| 693 | # unused for deciding on escaping. This turns out to be |
| 694 | # problematic for macros because whether a macro is safe depends not |
| 695 | # on the escape mode when it was defined, but rather when it was used. |
| 696 | # |
| 697 | # Because however we export macros from the module system and |
| 698 | # there are historic callers that do not pass an eval context (and |
| 699 | # will continue to not pass one), we need to perform an instance |
| 700 | # check here. |
| 701 | # |
| 702 | # This is considered safe because an eval context is not a valid |
| 703 | # argument to callables otherwise anyway. Worst case here is |
| 704 | # that if no eval context is passed we fall back to the compile |
| 705 | # time autoescape flag. |
| 706 | if args and isinstance(args[0], EvalContext): |
| 707 | autoescape = args[0].autoescape |
| 708 | args = args[1:] |
| 709 | else: |
| 710 | autoescape = self._default_autoescape |
| 711 | |
| 712 | # try to consume the positional arguments |
| 713 | arguments = list(args[: self._argument_count]) |
| 714 | off = len(arguments) |
| 715 | |
| 716 | # For information why this is necessary refer to the handling |
| 717 | # of caller in the `macro_body` handler in the compiler. |
| 718 | found_caller = False |
| 719 | |
| 720 | # if the number of arguments consumed is not the number of |
| 721 | # arguments expected we start filling in keyword arguments |
| 722 | # and defaults. |
| 723 | if off != self._argument_count: |
| 724 | for name in self.arguments[len(arguments) :]: |
| 725 | try: |
| 726 | value = kwargs.pop(name) |
| 727 | except KeyError: |
| 728 | value = missing |
| 729 | if name == "caller": |
| 730 | found_caller = True |
| 731 | arguments.append(value) |
| 732 | else: |
| 733 | found_caller = self.explicit_caller |
| 734 | |
| 735 | # it's important that the order of these arguments does not change |
| 736 | # if not also changed in the compiler's `function_scoping` method. |
| 737 | # the order is caller, keyword arguments, positional arguments! |
| 738 | if self.caller and not found_caller: |
| 739 | caller = kwargs.pop("caller", None) |
| 740 | if caller is None: |
| 741 | caller = self._environment.undefined("No caller defined", name="caller") |
| 742 | arguments.append(caller) |
| 743 | |
| 744 | if self.catch_kwargs: |
| 745 | arguments.append(kwargs) |
| 746 | elif kwargs: |