Skip to content

Commit

Permalink
Allow '{%+' to be valid syntax (but NOP) when lstrip_blocks == False. F…
Browse files Browse the repository at this point in the history
…ixes pallets#748.
  • Loading branch information
markroth8 authored and davidism committed Jul 20, 2019
1 parent 55cb0e7 commit 1e71e31
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Expand Up @@ -16,8 +16,11 @@ unreleased
- 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


Expand All @@ -28,6 +31,7 @@ _Unreleased_

- Fix Python 3.7 deprecation warnings.


Version 2.10.1
--------------

Expand Down
44 changes: 27 additions & 17 deletions jinja2/lexer.py
Expand Up @@ -445,22 +445,21 @@ def __init__(self, environment):

# 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,
Expand All @@ -474,10 +473,21 @@ def __init__(self, environment):
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
Expand Down
8 changes: 8 additions & 0 deletions tests/test_lexnparse.py
Expand Up @@ -503,6 +503,14 @@ def test_no_lstrip(self, env):
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(
Expand Down

0 comments on commit 1e71e31

Please sign in to comment.