diff options
author | Kevin Brown <kevin@kevin-brown.com> | 2020-05-16 15:55:56 -0400 |
---|---|---|
committer | Kevin Brown <kevin@kevin-brown.com> | 2020-05-16 17:08:09 -0400 |
commit | a3aa821a5f3b3cffd7a166ead8794279d8cc645c (patch) | |
tree | cc251ff998071fcf68b73963c53f96c41013c097 | |
parent | 140297e5473b217bda3ee2ff5027bff65fab8982 (diff) | |
download | jinja2-a3aa821a5f3b3cffd7a166ead8794279d8cc645c.tar.gz |
Add proper parsing for {% for %} parameters
Previously a lot of the parsing was done through implicit variable
tuples, but that ended up causing a lot of special cases because we
were only allowing variables in those tuples. Now that we are going
to move towards having tuples be handled consitently, whether they
are identifier tuples or tuple literals, the logic for handling the
`{% for %}` block needed to be cleaned up.
-rw-r--r-- | src/jinja2/new_parser.py | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/src/jinja2/new_parser.py b/src/jinja2/new_parser.py index ea1117b..6d0fb90 100644 --- a/src/jinja2/new_parser.py +++ b/src/jinja2/new_parser.py @@ -233,7 +233,6 @@ def parse_block_filter(ast): )
def parse_block_for(ast):
- target = None
iter = None
body = ast['contents']
else_ = []
@@ -242,39 +241,76 @@ def parse_block_for(ast): block_parameters = ast['start']['parameters']
- if block_parameters[0]['value']['operator'] == 'in':
- block_parameters[0:1] = [
- {
- "value": block_parameters[0]['value']['left']
- },
- {
- "value": {
- "variable": "in"
- }
- },
- {
- "value": block_parameters[0]['value']['right']
- },
- ]
+ target = []
+ for param_number, param in enumerate(block_parameters):
+ if param['value']['variable'] == 'in':
+ break
+
+ if param['value']['operator'] == 'in':
+ block_parameters[param_number:param_number + 1] = [
+ {
+ "value": param['value']['left']
+ },
+ {
+ "value": {
+ "variable": "in"
+ }
+ },
+ {
+ "value": param['value']['right']
+ },
+ ]
+
+ target.append(
+ parse_variable(
+ param['value']['left'],
+ variable_context='store'
+ )
+ )
- if block_parameters[1]['value']['variable'] != 'in':
- raise
+ break
- target = parse_variable(block_parameters[0]['value'], variable_context='store')
- iter = parse_variable(block_parameters[2]['value'])
+ target.append(parse_variable(param['value'], variable_context='store'))
+
+ if len(target) == 0:
+ raise TemplateSyntaxError(
+ "expected token 'in'",
+ lineno=lineno_from_parseinfo(ast['start']['parseinfo'])
+ )
- if not isinstance(target, (nodes.Name, nodes.Tuple)):
+ if len(target) == len(block_parameters):
raise TemplateSyntaxError(
"expected token 'in'",
- lineno=target.lineno
+ lineno=target[1].lineno
)
- if len(block_parameters) > 3:
- if block_parameters[3]['value']['variable'] == 'if':
- test = parse_conditional_expression(block_parameters[4]['value'])
+ if len(target) == 1:
+ target = target[0]
+ else:
+ target = nodes.Tuple(
+ target,
+ 'store',
+ lineno=target[0].lineno
+ )
+ param_number += 2
+
+ iter = parse_variable(block_parameters[param_number]['value'])
+ param_number += 1
+
+ if len(block_parameters) > param_number + 1:
+ if block_parameters[param_number]['value']['variable'] == 'if':
+ param_number += 1
+
+ test = parse_conditional_expression(
+ block_parameters[param_number]['value']
+ )
+ param_number += 1
+
+ if len(block_parameters) > param_number + 2:
+ raise
- if len(block_parameters) > 3:
- recursive = block_parameters[-1]['value']['variable'] == 'recursive'
+ if len(block_parameters) == param_number + 1:
+ recursive = block_parameters[param_number]['value']['variable'] == 'recursive'
else_ = _split_contents_at_block(ast['contents'], 'else')
|