]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
fix check for empty required block (#1858)
authorDavid Lord <davidism@gmail.com>
Thu, 1 Jun 2023 17:42:27 +0000 (10:42 -0700)
committerGitHub <noreply@github.com>
Thu, 1 Jun 2023 17:42:27 +0000 (10:42 -0700)
CHANGES.rst
src/jinja2/parser.py
tests/test_inheritance.py

index f609ab34a299953d01b1d20d259bd1f6d478f180..36db0843a5bf6a9f78d5f156bf2a592ada2f1983 100644 (file)
@@ -5,6 +5,9 @@ Version 3.1.3
 
 Unreleased
 
+-   Fix compiler error when checking if required blocks in parent templates are
+    empty. :pr:`1858`
+
 
 Version 3.1.2
 -------------
index cefce2dfa1d2a4171838b0d0135af8ea3ff7d62c..12703a97ad7cbdb492cdedbaade5ff27780e500b 100644 (file)
@@ -311,12 +311,14 @@ class Parser:
         # enforce that required blocks only contain whitespace or comments
         # by asserting that the body, if not empty, is just TemplateData nodes
         # with whitespace data
-        if node.required and not all(
-            isinstance(child, nodes.TemplateData) and child.data.isspace()
-            for body in node.body
-            for child in body.nodes  # type: ignore
-        ):
-            self.fail("Required blocks can only contain comments or whitespace")
+        if node.required:
+            for body_node in node.body:
+                if not isinstance(body_node, nodes.Output) or any(
+                    not isinstance(output_node, nodes.TemplateData)
+                    or not output_node.data.isspace()
+                    for output_node in body_node.nodes
+                ):
+                    self.fail("Required blocks can only contain comments or whitespace")
 
         self.stream.skip_if("name:" + node.name)
         return node
index 0c20d4da7d3c29e36bf8c7fb36c747b069b6f6e5..8398f4df589ddee38d641c07cabc8bb8e706357f 100644 (file)
@@ -287,26 +287,34 @@ class TestInheritance:
         env = Environment(
             loader=DictLoader(
                 {
-                    "default": "{% block x required %}data {# #}{% endblock %}",
-                    "default1": "{% block x required %}{% block y %}"
-                    "{% endblock %}  {% endblock %}",
-                    "default2": "{% block x required %}{% if true %}"
-                    "{% endif %}  {% endblock %}",
-                    "level1": "{% if default %}{% extends default %}"
-                    "{% else %}{% extends 'default' %}{% endif %}"
-                    "{%- block x %}CHILD{% endblock %}",
+                    "empty": "{% block x required %}{% endblock %}",
+                    "blank": "{% block x required %} {# c #}{% endblock %}",
+                    "text": "{% block x required %}data {# c #}{% endblock %}",
+                    "block": "{% block x required %}{% block y %}"
+                    "{% endblock %}{% endblock %}",
+                    "if": "{% block x required %}{% if true %}"
+                    "{% endif %}{% endblock %}",
+                    "top": "{% extends t %}{% block x %}CHILD{% endblock %}",
                 }
             )
         )
-        t = env.get_template("level1")
+        t = env.get_template("top")
+        assert t.render(t="empty") == "CHILD"
+        assert t.render(t="blank") == "CHILD"
 
-        with pytest.raises(
+        required_block_check = pytest.raises(
             TemplateSyntaxError,
             match="Required blocks can only contain comments or whitespace",
-        ):
-            assert t.render(default="default")
-            assert t.render(default="default2")
-            assert t.render(default="default3")
+        )
+
+        with required_block_check:
+            t.render(t="text")
+
+        with required_block_check:
+            t.render(t="block")
+
+        with required_block_check:
+            t.render(t="if")
 
     def test_required_with_scope(self, env):
         env = Environment(