Indent filter fails confusing if input is not string
alex-harvey-z3q opened this issue · 3 comments
Description
When calling the indent filter when the input is not a string (e.g. dict input), the filter fails with a confusing error message:
unsupported operand type(s) for +=: 'dict' and 'str'"
To reproduce
See the test I wrote:
def test_indent_dict(self, env):
self._test_indent_multiline_template(env)
t = env.from_string('{{ mydict|indent }}')
with pytest.raises(FilterArgumentError):
t.render(mydict={"foo":"bar"})
Expected behaviour
An error message that advises that the filter has been called with unexpected inputs is expected.
Environment:
- Python version: 3.10
- Jinja version: latest
In general, Python does not do type checking just to show special error messages. If you pass in wrong data to something it might fail in weird ways at a weird spot. This filter isn't special in this regard.
@davidism If you look through the code, you have yourself already added a number of FilterArgumentExceptions
—correctly, according to good design—to ensure that failures are graceful. Also, the idea that Python programmers normally don't bother to handle their exceptions and just let things blow up confusingly is .... not true.
Here's the standard library's own indent
function, failing on invalid input without talking about str
. Most other functions result in similar behavior. Convince the cpython maintainers that they should add runtime type checks for the arguments of each function they maintain, and I'll consider adding them all over the place in Jinja too.
>>> import textwrap
>>> textwrap.indent({}, " ")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.10/textwrap.py", line 488, in indent
return ''.join(prefixed_lines())
File "/usr/local/lib/python3.10/textwrap.py", line 486, in prefixed_lines
for line in text.splitlines(True):
AttributeError: 'dict' object has no attribute 'splitlines'