看下面的模板代码:
set_property verilog_define {
{%- for k, v in vlogdefine.items() %}{{ k }}={{ v|param_value_str }} {% endfor -%}
} [get_filesets sources_1]
直到Jinja2 2.10.3,这都会导致类似
set_property verilog_define {vlogdefine_bool=1 vlogdefine_int=42 vlogdefine_str=hello } [get_filesets sources_1]
该代码具有lstrip_blocks = True
。
现在,使用2.11.0时,代码将如下所示:
set_property verilog_define {vlogdefine_bool=1vlogdefine_int=42vlogdefine_str=hello} [get_filesets sources_1]
@towoe将行为更改https://github.com/pallets/jinja/commit/7d00a40465c89bee141ab5a3db545a20e7d30509 (作者@ petee-d在https://github.com/pallets/jinja/issues/857)
根据文档
lstrip_blocks
如果将其设置为True,则前导空格和制表符将从行的开头剥离到一个块。 默认为False。
我不认为应该在endfor
之前删除空格,因为这不是“从行首开始”的空格。 我是不是误解了,还是新版本引入了意想不到的行为更改?
Python 3.7.3(但在CI中的3.5上也会发生)
我会进行调查,对于造成您链接的令人困惑的调试会话的事件,我们深表歉意! 乍一看,现在的行为看起来更加一致,并且我们没有对以前的行为进行测试,但是我必须进行检查。 您是否可以使用{%+ endfor -%}
显式声明保留空白?
@davidism感谢您的关注。
是的,我们可以通过多种方式(使用+
,切换到lstrip_blocks = False
等等)来对edalize(使用Jinja的库)进行更改,但是我想首先确保我们对预期的行为有共同的理解。
这也以与原始海报相同的方式影响我。 对我来说,文档似乎很清楚2.11的行为是错误的。 从https://github.com/pallets/jinja/blob/2.11.x/docs/templates.rst#whitespace -control:
(如果在该块的开头之前还有其他字符,则不会删除任何内容。)
这是由于#858,它解决了解析空间中的一个很大的速度问题。 对于解决此问题,我很好,但是我不想仅还原该更改。 如果有人想在词法分析器中使用正则表达式并解决此问题,我很乐意对其进行复习。
很抱歉,该修复程序破坏了lstrip_blocks的预期行为,我记得对于应该执行的操作有点困惑,并且无法为其找到合适的文档。 我不确定Google为什么不带我去链接到文档部分的@kenyon ,这很奇怪。 因此,我最终从测试和实现中弄清了预期的行为,显然错过了这一点。
正如@davidism所说,还原该修补程序还会导致其他麻烦,因此需要设计一个新的修补程序。 我将在本周争取时间。
from jinja2 import Template
t = Template(
"{% if x %}{{ x }} {% endif %}y",
lstrip_blocks=True,
)
out = t.render(x="x")
assert out == "x y"
这是问题。 当此模板被标记化时, find("\n")
是仅包含{{ x }}
和{% endif %}
之间的空格的递交文本,看不到换行符,然后从文本开头删除。
将"\n" in text
到elif
会使一堆测试失败,因为模板的第一行不包含换行符,但是如果模板只有空格,则应将其删除。 如果我们变得更聪明一点并跟踪我们是否在第一行,那么如果还启用了trim_blocks
,它仍然会失败,因为这会将正则表达式中的换行符删除。
似乎{%- raw %} {% endraw -%}
的行为也受到影响。 在2.11.0之前,这将在该位置强制留出空格。 现在,该空间已删除。
from jinja2 import Template
t = Template(
"{{x}}\n{%- raw %} {% endraw -%}\n{{ y }}",
lstrip_blocks=True,
)
out = t.render(x="x", y="y")
assert out == "x y"
@ petee-d有机会您有时间再看一遍吗? 否则,我将其还原为2.11.2。
哎呀,完全忘记了这一点。 将尝试在本周实际抽出时间,否则在副作用严重时将其恢复。
我的暂定计划是在周六放映。 让我知道您是否正在努力,如果可以,我可以将其推迟。
我想我有个解决办法。 我试图不受您先前@davidism的评论的
首先,我认为如果l_pos = text.rfind("\n") + 1
没有找到任何换行符,但后来却忘记了它,我本来打算使修正的行为有所不同。 因此,如果text
没有换行符,我将不再进行剥离。 然后,我还尝试解决source
第一行仍然需要删除的问题,但我没有使用or pos == 0
,而是使用了一个line_starting
布尔值标记为True的布尔值。 然后,根据匹配的字符串是否以换行符结尾,在处理完每个令牌后,我就设置了该标志,并且还解决了trim_blocks问题。 请参阅#1183中的修复程序。
当前的测试套件通过了,明天我还将针对此问题以及我能想到的其他情况添加新的测试。 我还将运行有关从我的项目中收集的新收集的5GB用户创建的模板集的原始版本,第一个修复程序和第二个修复程序,比较解析树和性能。
添加了测试,性能测试没有显示降级,所以这是从我这边完成的。 :)
刚刚发布了2.11.2。
最有用的评论
刚刚发布了2.11.2。