- The ``map`` filter in async mode now automatically awaits
- Added a new ``ChainableUndefined`` class to support getitem
and getattr on an undefined object. (`#977`_)
+- Allow `'{%+'` syntax (with NOP behavior) when
+ `lstrip_blocks == False` (`#748`_)
.. _#765: https://github.com/pallets/jinja/issues/765
+.. _#748: https://github.com/pallets/jinja/issues/748
.. _#977: https://github.com/pallets/jinja/issues/977
- Fix Python 3.7 deprecation warnings.
+
Version 2.10.1
--------------
# strip leading spaces if lstrip_blocks is enabled
prefix_re = {}
+ no_lstrip_re = e('+')
+ # detect overlap between block and variable or comment strings
+ block_diff = c(r'^%s(.*)' % e(environment.block_start_string))
+ # make sure we don't mistake a block for a variable or a comment
+ m = block_diff.match(environment.comment_start_string)
+ no_lstrip_re += m and r'|%s' % e(m.group(1)) or ''
+ m = block_diff.match(environment.variable_start_string)
+ no_lstrip_re += m and r'|%s' % e(m.group(1)) or ''
+ # detect overlap between comment and variable strings
+ comment_diff = c(r'^%s(.*)' % e(environment.comment_start_string))
+ m = comment_diff.match(environment.variable_start_string)
+ no_variable_re = m and r'(?!%s)' % e(m.group(1)) or ''
+
if environment.lstrip_blocks:
# use '{%+' to manually disable lstrip_blocks behavior
- no_lstrip_re = e('+')
- # detect overlap between block and variable or comment strings
- block_diff = c(r'^%s(.*)' % e(environment.block_start_string))
- # make sure we don't mistake a block for a variable or a comment
- m = block_diff.match(environment.comment_start_string)
- no_lstrip_re += m and r'|%s' % e(m.group(1)) or ''
- m = block_diff.match(environment.variable_start_string)
- no_lstrip_re += m and r'|%s' % e(m.group(1)) or ''
-
- # detect overlap between comment and variable strings
- comment_diff = c(r'^%s(.*)' % e(environment.comment_start_string))
- m = comment_diff.match(environment.variable_start_string)
- no_variable_re = m and r'(?!%s)' % e(m.group(1)) or ''
-
lstrip_re = r'^[ \t]*'
block_prefix_re = r'%s%s(?!%s)|%s\+?' % (
lstrip_re,
no_variable_re,
e(environment.comment_start_string),
)
- prefix_re['block'] = block_prefix_re
- prefix_re['comment'] = comment_prefix_re
else:
- block_prefix_re = '%s' % e(environment.block_start_string)
+ # If lstrip_blocks is False, then '{%+' is allowed but a NOP
+ block_prefix_re = r'%s(?!%s)|%s\+?' % (
+ e(environment.block_start_string),
+ no_lstrip_re,
+ e(environment.block_start_string),
+ )
+ comment_prefix_re = r'%s%s|%s\+?' % (
+ e(environment.comment_start_string),
+ no_variable_re,
+ e(environment.comment_start_string),
+ )
+
+ prefix_re['block'] = block_prefix_re
+ prefix_re['comment'] = comment_prefix_re
self.newline_sequence = environment.newline_sequence
self.keep_trailing_newline = environment.keep_trailing_newline
tmpl = env.from_string(''' {%+ if True %}\n {%+ endif %}''')
assert tmpl.render() == " \n "
+ def test_lstrip_blocks_false_with_no_lstrip(self, env):
+ # Test that + is a NOP (but does not cause an error) if lstrip_blocks=False
+ env = Environment(lstrip_blocks=False, trim_blocks=False)
+ tmpl = env.from_string(''' {% if True %}\n {% endif %}''')
+ assert tmpl.render() == " \n "
+ tmpl = env.from_string(''' {%+ if True %}\n {%+ endif %}''')
+ assert tmpl.render() == " \n "
+
def test_lstrip_endline(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
tmpl = env.from_string(