thibaudcolas / curlylint

Experimental HTML templates linting for Jinja, Nunjucks, Django templates, Twig, Liquid
https://www.curlylint.org/
MIT License
239 stars 25 forks source link

TypeError: can only concatenate str (not "Parser") to str #146

Open symroe opened 2 years ago

symroe commented 2 years ago

Describe the bug

parse.py contains the following on line 565 at time of writing:

yield P.fail("expected `{% if " + content + " %}`")

Some HTML input can cause content to be of type Parser not str, causing the error in the title.

I suspect there are two bugs here:

  1. That the type of content can change seems to indicate a deeper bug than I'm able to understand at the moment. I think pulling at that thread will help with the "proper" fix
  2. I'm not 100% sure the input file is wrong, so there might be a parser error that's causing this to be raised in the first place (see samples below).

Which terms did you search for in the documentation and issue tracker?

"concatenate"

Environment

Steps to reproduce

I have two samples:

To re-produce the actual bug

Write the below to example.html and then curlylint example.html with no other config

{% for area_url, area_name in areas %}
    {% if forloop.first %}
        <ul>
    {% endif %}
            <li><a href="{{ area_url }}">{{ area_name }}</a></li>
    {% if forloop.last %}
        </ul>
    {% endif %}
{% empty %}
    <p>
        No areas found of type {{ area_type.name }}.
    </p>
{% endfor %}

Stripped down example that I don't think should be an error

{% for area_url, area_name in areas %}
    {% if forloop.first %}
        <ul>
    {% endif %}
{% endfor %}

In this example, the <ul> is opened but not closed, however I don't think this should be a linting error...as you can see from the above example, it is closed later in the template.

(None of this is to say that the template is good, but I don't think it should raise this exception!)

Expected behavior

For sample 1, I think it shouldn't blow up. I fixed this by adding str() around content, but like I say, I think we should understand why content isn't a string already, like it's clearly expecting.

For sample 2: this might be more complex and could be punted to a different issue, but I don't think it should error.

To be clear in example 2, the error is "correct" in that I get

curlylint example.html
example.html
4:3 Parse error: expected one of 'autoescape', 'block', 'blocktrans', 'comment', 'filter', 'for', 'if', 'ifchanged', 'ifequal', 'ifnotequal', 'not an intermediate Jinja tag name', 'spaceless', 'verbatim', 'with' at 4:3  parse_error

Oh no! 💥 💔 💥
1 error reported
uberfresh commented 1 year ago

I have same issue here:


{% for s in status_list %}
  {% if s.name == "OPEN" %}
  <optgroup class="border-bottom border-primary"> 
  {% endif %} 
  <option {% if status == s.name %} selected {% endif %} >{{ s }}</option>
  {% if s.name == "CLOSED" %} 
  </optgroup> 
  {% endif %}
{% endfor %}