diff --git a/doc/build/unreleased/146.rst b/doc/build/unreleased/146.rst new file mode 100644 index 00000000..85ec87a8 --- /dev/null +++ b/doc/build/unreleased/146.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, codegen + :tickets: 146 + + Fixed unexpected error when use control lines which the + first control block with no bodies other than comments, + as `pass` is now added to the first empty block. + Pull request courtesy Hai Zhu. diff --git a/mako/codegen.py b/mako/codegen.py index ce6f83aa..b9fea937 100644 --- a/mako/codegen.py +++ b/mako/codegen.py @@ -838,13 +838,24 @@ def visitControlLine(self, node): text = node.text self.printer.writeline(text) children = node.get_children() - # this covers the three situations where we want to insert a pass: - # 1) a ternary control line with no children, - # 2) a primary control line with nothing but its own ternary - # and end control lines, and - # 3) any control line with no content other than comments - if not children or ( - all( + + # this covers the four situations where we want to insert a pass: + # 1) a ternary control line with no children, + # 2) a primary control line with nothing but its own ternary + # and end control lines, and + # 3) any control line with no content other than comments + # 4) the first control block with no content other than comments + def _search_for_control_line(): + for c in children: + if isinstance(c, parsetree.Comment): + continue + elif isinstance(c, parsetree.ControlLine): + return True + return False + + if ( + not children + or all( isinstance(c, (parsetree.Comment, parsetree.ControlLine)) for c in children ) @@ -853,6 +864,7 @@ def visitControlLine(self, node): for c in children if isinstance(c, parsetree.ControlLine) ) + or _search_for_control_line() ): self.printer.writeline("pass") diff --git a/test/test_template.py b/test/test_template.py index e03415e2..cd7d89e5 100644 --- a/test/test_template.py +++ b/test/test_template.py @@ -1036,6 +1036,47 @@ def test_blank_control_8(self): template_args={"ctx": ctx}, ) + def test_blank_control_9(self): + self._do_memory_test( + """ + % if True: + % elif False: + false + % else: + broken + % endif + """, + "", + filters=lambda s: s.strip(), + template_args={"ctx": ctx}, + ) + + def test_blank_control_10(self): + self._do_memory_test( + """ + % if True: + % else: + test + % endif + """, + "", + filters=lambda s: s.strip(), + template_args={"ctx": ctx}, + ) + + def test_blank_control_11(self): + self._do_memory_test( + """ + % try: + % except: + error + % endtry + """, + "", + filters=lambda s: s.strip(), + template_args={"ctx": ctx}, + ) + def test_commented_blank_control_1(self): self._do_memory_test( """ @@ -1135,6 +1176,36 @@ def test_commented_blank_control_8(self): template_args={"ctx": ctx}, ) + def test_commented_blank_control_9(self): + self._do_memory_test( + """ + % if True: + ## comment + % elif False: + false + % else: + broken + % endif + """, + "", + filters=lambda s: s.strip(), + template_args={"ctx": ctx}, + ) + + def test_commented_blank_control_10(self): + self._do_memory_test( + """ + % try: + ## comment + % except: + error + % endtry + """, + "", + filters=lambda s: s.strip(), + template_args={"ctx": ctx}, + ) + def test_multiline_control(self): t = Template( """