]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
Changed behavior of macro defaults to be frame bound
authorArmin Ronacher <armin.ronacher@active-4.com>
Tue, 3 Jan 2017 17:19:31 +0000 (18:19 +0100)
committerArmin Ronacher <armin.ronacher@active-4.com>
Tue, 3 Jan 2017 22:45:30 +0000 (23:45 +0100)
jinja2/compiler.py
jinja2/runtime.py
tests/test_core_tags.py
tests/test_regression.py

index 955828febd42fcb65c8412458785da3c0423642a..9e850176503108291c5d09d4f89c3c966eabd29b 100644 (file)
@@ -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."""
index 67908aedf26951ea28c857aca154642ed273dd61..15f89d155c3eebfdb2d3fad77b55bdd140ef983d 100644 (file)
@@ -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
index 5391354f05fd74edba5e9c41cd75ed29f90c9073..058bf85e68cb005c0643d05880589ee1f6fd8504 100644 (file)
@@ -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
index 066adbf6b7e7fa09043f1c652fa21dd2c3074e80..e3793f07b185892cebb1629a17a474ecfa9b66dd 100644 (file)
@@ -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'