From a1d04fc7513fe59acba24aa4da53ac7be93c1bbf Mon Sep 17 00:00:00 2001 From: SapirBaruch Date: Tue, 2 Jun 2026 10:30:14 +0300 Subject: [PATCH 1/2] Fix indent filter ignoring blank=False for empty first line When first=True is set, the indent filter was unconditionally prepending the indentation to the whole string, even when blank=False and the first line was empty. Now the first-line indentation is skipped when blank=False and the first line has no content. Fixes #2176 --- CHANGES.rst | 2 ++ src/jinja2/filters.py | 2 +- tests/test_filters.py | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 338dc9966..9565c8d28 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,6 +13,8 @@ Unreleased - Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``. :pr:`1793` - Use ``flit_core`` instead of ``setuptools`` as build backend. +- Fix ``indent`` filter not respecting ``blank=False`` for the first line + when ``first=True`` is set. :issue:`2176` Version 3.1.6 diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py index c46e20c10..897cfb331 100644 --- a/src/jinja2/filters.py +++ b/src/jinja2/filters.py @@ -860,7 +860,7 @@ def do_indent( indention + line if line else line for line in lines ) - if first: + if first and (blank or rv.split("\n", 1)[0]): rv = indention + rv return rv diff --git a/tests/test_filters.py b/tests/test_filters.py index 4601469a6..f80967b5a 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -166,7 +166,7 @@ def _test_indent_multiline_template(env, markup=False): t = env.from_string("{{ foo|indent(2, false, true) }}") assert t.render(foo=text) == '\n foo bar\n "baz"\n ' t = env.from_string("{{ foo|indent(2, true, false) }}") - assert t.render(foo=text) == ' \n foo bar\n "baz"\n' + assert t.render(foo=text) == '\n foo bar\n "baz"\n' t = env.from_string("{{ foo|indent(2, true, true) }}") assert t.render(foo=text) == ' \n foo bar\n "baz"\n ' @@ -179,6 +179,19 @@ def test_indent(self, env): t = env.from_string('{{ "jinja"|indent(blank=true) }}') assert t.render() == "jinja" + def test_indent_first_blank(self, env): + # ``blank=False`` (the default) must suppress indentation of the first + # line when it is empty, even when ``first=True``. Regression for + # https://github.com/pallets/jinja/issues/2176 + t = env.from_string("{% filter indent(4, first=true) %}{% endfilter %}") + assert t.render() == "" + # A leading blank line is not indented when blank=False. + t = env.from_string('{{ "\nhello"|indent(4, first=true) }}') + assert t.render() == "\n hello" + # blank=True still indents the first line even when it is empty. + t = env.from_string("{% filter indent(4, first=true, blank=true) %}{% endfilter %}") + assert t.render() == " " + def test_indent_markup_input(self, env): """ Tests cases where the filter input is a Markup type From bf7b0e8ba77d74790cc287db4992d8303e68ad6f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 07:31:46 +0000 Subject: [PATCH 2/2] [pre-commit.ci lite] apply automatic fixes --- tests/test_filters.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_filters.py b/tests/test_filters.py index f80967b5a..58d85a811 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -189,7 +189,9 @@ def test_indent_first_blank(self, env): t = env.from_string('{{ "\nhello"|indent(4, first=true) }}') assert t.render() == "\n hello" # blank=True still indents the first line even when it is empty. - t = env.from_string("{% filter indent(4, first=true, blank=true) %}{% endfilter %}") + t = env.from_string( + "{% filter indent(4, first=true, blank=true) %}{% endfilter %}" + ) assert t.render() == " " def test_indent_markup_input(self, env):