Dump the function def of a macro or call block.
(self, node, frame)
| 503 | return 'def %s' % name |
| 504 | |
| 505 | def macro_body(self, node, frame): |
| 506 | """Dump the function def of a macro or call block.""" |
| 507 | frame = frame.inner() |
| 508 | frame.symbols.analyze_node(node) |
| 509 | macro_ref = MacroRef(node) |
| 510 | |
| 511 | explicit_caller = None |
| 512 | skip_special_params = set() |
| 513 | args = [] |
| 514 | for idx, arg in enumerate(node.args): |
| 515 | if arg.name == 'caller': |
| 516 | explicit_caller = idx |
| 517 | if arg.name in ('kwargs', 'varargs'): |
| 518 | skip_special_params.add(arg.name) |
| 519 | args.append(frame.symbols.ref(arg.name)) |
| 520 | |
| 521 | undeclared = find_undeclared(node.body, ('caller', 'kwargs', 'varargs')) |
| 522 | |
| 523 | if 'caller' in undeclared: |
| 524 | # In older Jinja2 versions there was a bug that allowed caller |
| 525 | # to retain the special behavior even if it was mentioned in |
| 526 | # the argument list. However thankfully this was only really |
| 527 | # working if it was the last argument. So we are explicitly |
| 528 | # checking this now and error out if it is anywhere else in |
| 529 | # the argument list. |
| 530 | if explicit_caller is not None: |
| 531 | try: |
| 532 | node.defaults[explicit_caller - len(node.args)] |
| 533 | except IndexError: |
| 534 | self.fail('When defining macros or call blocks the ' |
| 535 | 'special "caller" argument must be omitted ' |
| 536 | 'or be given a default.', node.lineno) |
| 537 | else: |
| 538 | args.append(frame.symbols.declare_parameter('caller')) |
| 539 | macro_ref.accesses_caller = True |
| 540 | if 'kwargs' in undeclared and not 'kwargs' in skip_special_params: |
| 541 | args.append(frame.symbols.declare_parameter('kwargs')) |
| 542 | macro_ref.accesses_kwargs = True |
| 543 | if 'varargs' in undeclared and not 'varargs' in skip_special_params: |
| 544 | args.append(frame.symbols.declare_parameter('varargs')) |
| 545 | macro_ref.accesses_varargs = True |
| 546 | |
| 547 | # macros are delayed, they never require output checks |
| 548 | frame.require_output_check = False |
| 549 | frame.symbols.analyze_node(node) |
| 550 | self.writeline('%s(%s):' % (self.func('macro'), ', '.join(args)), node) |
| 551 | self.indent() |
| 552 | |
| 553 | self.buffer(frame) |
| 554 | self.enter_frame(frame) |
| 555 | |
| 556 | self.push_parameter_definitions(frame) |
| 557 | for idx, arg in enumerate(node.args): |
| 558 | ref = frame.symbols.ref(arg.name) |
| 559 | self.writeline('if %s is missing:' % ref) |
| 560 | self.indent() |
| 561 | try: |
| 562 | default = node.defaults[idx - len(node.args)] |
no test coverage detected