Dump the function def of a macro or call block.
(
self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame
)
| 612 | return fclass="st">"{self.choose_async()}def {name}" |
| 613 | |
| 614 | def macro_body( |
| 615 | self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame |
| 616 | ) -> t.Tuple[Frame, MacroRef]: |
| 617 | class="st">""class="st">"Dump the function def of a macro or call block."class="st">"" |
| 618 | frame = frame.inner() |
| 619 | frame.symbols.analyze_node(node) |
| 620 | macro_ref = MacroRef(node) |
| 621 | |
| 622 | explicit_caller = None |
| 623 | skip_special_params = set() |
| 624 | args = [] |
| 625 | |
| 626 | for idx, arg in enumerate(node.args): |
| 627 | if arg.name == class="st">"caller": |
| 628 | explicit_caller = idx |
| 629 | if arg.name in (class="st">"kwargs", class="st">"varargs"): |
| 630 | skip_special_params.add(arg.name) |
| 631 | args.append(frame.symbols.ref(arg.name)) |
| 632 | |
| 633 | undeclared = find_undeclared(node.body, (class="st">"caller", class="st">"kwargs", class="st">"varargs")) |
| 634 | |
| 635 | if class="st">"caller" in undeclared: |
| 636 | class="cm"># In older Jinja versions there was a bug that allowed caller |
| 637 | class="cm"># to retain the special behavior even if it was mentioned in |
| 638 | class="cm"># the argument list. However thankfully this was only really |
| 639 | class="cm"># working if it was the last argument. So we are explicitly |
| 640 | class="cm"># checking this now and error out if it is anywhere else in |
| 641 | class="cm"># the argument list. |
| 642 | if explicit_caller is not None: |
| 643 | try: |
| 644 | node.defaults[explicit_caller - len(node.args)] |
| 645 | except IndexError: |
| 646 | self.fail( |
| 647 | class="st">"When defining macros or call blocks the " |
| 648 | &class="cm">#x27;special class="st">"caller" argument must be omitted ' |
| 649 | class="st">"or be given a default.", |
| 650 | node.lineno, |
| 651 | ) |
| 652 | else: |
| 653 | args.append(frame.symbols.declare_parameter(class="st">"caller")) |
| 654 | macro_ref.accesses_caller = True |
| 655 | if class="st">"kwargs" in undeclared and class="st">"kwargs" not in skip_special_params: |
| 656 | args.append(frame.symbols.declare_parameter(class="st">"kwargs")) |
| 657 | macro_ref.accesses_kwargs = True |
| 658 | if class="st">"varargs" in undeclared and class="st">"varargs" not in skip_special_params: |
| 659 | args.append(frame.symbols.declare_parameter(class="st">"varargs")) |
| 660 | macro_ref.accesses_varargs = True |
| 661 | |
| 662 | class="cm"># macros are delayed, they never require output checks |
| 663 | frame.require_output_check = False |
| 664 | frame.symbols.analyze_node(node) |
| 665 | self.writeline(fclass="st">"{self.func(&class="cm">#x27;macro')}({', '.join(args)}):", node) |
| 666 | self.indent() |
| 667 | |
| 668 | self.buffer(frame) |
| 669 | self.enter_frame(frame) |
| 670 | |
| 671 | self.push_parameter_definitions(frame) |
no test coverage detected