From 4c0f67f0bcecf2c4bc352463752b003bad03d570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dlouh=C3=BD?= Date: Wed, 22 Jul 2026 17:48:05 +0200 Subject: [PATCH] Fix #70: don't measure comment contents in inheriting templates In a template that {% extends %} another, a {% comment %} opener placed outside of any {% block %} was skipped by the 'extends and not inblock' continue before the comment flag was set. Variable tokens inside the comment were then recorded as executable lines, and reported as missing forever - they can never run. Set the comment flag before the extends-skip, mirroring how {% endcomment %} is already handled earlier in the loop. Co-Authored-By: Claude Opus 4.8 --- django_coverage_plugin/plugin.py | 9 ++++++--- tests/test_extends.py | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/django_coverage_plugin/plugin.py b/django_coverage_plugin/plugin.py index 45bb83b..0fd5e9a 100644 --- a/django_coverage_plugin/plugin.py +++ b/django_coverage_plugin/plugin.py @@ -309,13 +309,16 @@ def lines(self): if extends: continue + if token.contents == "comment": + # Set this before the extends-skip below: in an inheriting + # template a comment outside the blocks must still suppress + # measurement of its contents (issue #70). + comment = True + if extends and not inblock: # In an inheriting template, ignore all tags outside of # blocks. continue - - if token.contents == "comment": - comment = True if token.contents.startswith("end"): continue elif token.contents in ("else", "empty"): diff --git a/tests/test_extends.py b/tests/test_extends.py index e665335..0729e80 100644 --- a/tests/test_extends.py +++ b/tests/test_extends.py @@ -106,6 +106,31 @@ def test_inheriting_with_unused_blocks(self): self.assert_analysis([1, 2, 3], name="base.html") self.assert_analysis([1, 4, 8], [8], name="specific.html") + def test_inheriting_with_comment_outside_blocks(self): + # https://github.com/coveragepy/django_coverage_plugin/issues/70 + # A {% comment %} outside the blocks of an inheriting template was + # skipped before the comment flag was set, so {{ vars }} inside the + # comment were measured as executable lines that can never run. + self.make_template(name="base.html", text="""\ + Hello + {% block second_line %}second{% endblock %} + """) + + self.make_template(name="specific.html", text="""\ + {% extends "base.html" %} + {% comment %} + {{ this.line.was.reported.missing }} + {% endcomment %} + {% block second_line %} + SECOND + {% endblock %} + """) + + text = self.run_django_coverage(name="specific.html") + self.assertEqual(text, "Hello\n\nSECOND\n\n") + self.assert_analysis([1, 2], name="base.html") + self.assert_analysis([1, 6], name="specific.html") + def test_empty_parent_block_on_new_line_when_extended(self): """ When a block is empty and extended, endblock should not appear