From: Armin Ronacher Date: Tue, 3 Jan 2017 17:19:31 +0000 (+0100) Subject: Changed behavior of macro defaults to be frame bound X-Git-Tag: 2.9~30^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b2a4f49c61dc81c51db1a3f30aeb90e4c700ecd;p=thirdparty%2Fjinja.git Changed behavior of macro defaults to be frame bound --- diff --git a/jinja2/compiler.py b/jinja2/compiler.py index 955828fe..9e850176 100644 --- a/jinja2/compiler.py +++ b/jinja2/compiler.py @@ -496,8 +496,25 @@ class CodeGenerator(NodeVisitor): frame.symbols.analyze_node(node) self.writeline('%s(%s):' % (self.func('macro'), ', '.join(args)), node) self.indent() + self.buffer(frame) self.enter_frame(frame) + + for idx, arg in enumerate(node.args): + self.writeline('if %s is missing:' % frame.symbols.ref(arg.name)) + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline('%s = undefined(%r, name=%r)' % ( + frame.symbols.ref(arg.name), + 'parameter %r was not provided' % arg.name, + arg.name)) + else: + self.writeline('%s = ' % frame.symbols.ref(arg.name)) + self.visit(default, frame) + self.outdent() + self.blockvisit(node.body, frame) self.return_buffer_contents(frame) self.leave_frame(frame, with_python_scope=True) @@ -511,16 +528,9 @@ class CodeGenerator(NodeVisitor): name = getattr(macro_ref.node, 'name', None) if len(macro_ref.node.args) == 1: arg_tuple += ',' - self.write('Macro(environment, macro, %r, (%s), (' % - (name, arg_tuple)) - for arg in macro_ref.node.defaults: - self.visit(arg, frame) - self.write(', ') - self.write('), %r, %r, %r)' % ( - bool(macro_ref.accesses_kwargs), - bool(macro_ref.accesses_varargs), - bool(macro_ref.accesses_caller) - )) + self.write('Macro(environment, macro, %r, (%s), %r, %r, %r)' % + (name, arg_tuple, macro_ref.accesses_kwargs, + macro_ref.accesses_varargs, macro_ref.accesses_caller)) def position(self, node): """Return a human readable position for the node.""" diff --git a/jinja2/runtime.py b/jinja2/runtime.py index 67908aed..15f89d15 100644 --- a/jinja2/runtime.py +++ b/jinja2/runtime.py @@ -397,14 +397,13 @@ class LoopContextIterator(object): class Macro(object): """Wraps a macro function.""" - def __init__(self, environment, func, name, arguments, defaults, + def __init__(self, environment, func, name, arguments, catch_kwargs, catch_varargs, caller): self._environment = environment self._func = func self._argument_count = len(arguments) self.name = name self.arguments = arguments - self.defaults = defaults self.catch_kwargs = catch_kwargs self.catch_varargs = catch_varargs self.caller = caller @@ -423,11 +422,7 @@ class Macro(object): try: value = kwargs.pop(name) except KeyError: - try: - value = self.defaults[idx - self._argument_count + off] - except IndexError: - value = self._environment.undefined( - 'parameter %r was not provided' % name, name=name) + value = missing arguments.append(value) # it's important that the order of these arguments does not change diff --git a/tests/test_core_tags.py b/tests/test_core_tags.py index 5391354f..058bf85e 100644 --- a/tests/test_core_tags.py +++ b/tests/test_core_tags.py @@ -308,13 +308,11 @@ class TestMacros(): '{% macro bar() %}{{ varargs }}{{ kwargs }}{% endmacro %}' '{% macro baz() %}{{ caller() }}{% endmacro %}') assert tmpl.module.foo.arguments == ('a', 'b') - assert tmpl.module.foo.defaults == () assert tmpl.module.foo.name == 'foo' assert not tmpl.module.foo.caller assert not tmpl.module.foo.catch_kwargs assert not tmpl.module.foo.catch_varargs assert tmpl.module.bar.arguments == () - assert tmpl.module.bar.defaults == () assert not tmpl.module.bar.caller assert tmpl.module.bar.catch_kwargs assert tmpl.module.bar.catch_varargs diff --git a/tests/test_regression.py b/tests/test_regression.py index 066adbf6..e3793f07 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -322,9 +322,9 @@ class TestBug(): env = Environment() env.globals['get_int'] = lambda: 42 t = env.from_string(''' - {% macro test(arg1=get_int()) %} - {{ arg1 }} - {% endmacro %} - {{ test(1) }}|{{ test() }} + {% macro test(a, b, c=get_int()) -%} + {{ a + b + c }} + {%- endmacro %} + {{ test(1, 2) }}|{{ test(1, 2, 3) }} ''') - assert t.render().strip() == '1|42' + assert t.render().strip() == '45|6'