the line number of python block is wrong in traceback

476 views
Skip to first unread message

Youngrok Pak

unread,
Dec 21, 2011, 2:32:31 PM12/21/11
to Mako Templates for Python
See this codes,

1 <h1>hello</h1>
2
3 <%
4 a = 5
5 a = b # error
6 %>

traceback should point line 5, but it points line 3.

mako/codegen.py may be the cause. here is visitCode method in
codegen.py

def visitCode(self, node):
if not node.ismodule:
self.write_source_comment(node)
self.printer.write_indented_block(node.text)

node contains whole python block, so write_source_comment is called
only one time for one python block. If it is called by line, it can be
fixed. However I don't understand 'node' object yet, I wasn't able to
fix it.

There is one more problem. When using module level block, <%! %>, it
doesn't even show error lines with
exceptions.html_error_template().render()

Michael Bayer

unread,
Dec 21, 2011, 5:19:16 PM12/21/11
to mako-d...@googlegroups.com

On Dec 21, 2011, at 2:32 PM, Youngrok Pak wrote:

> See this codes,
>
> 1 <h1>hello</h1>
> 2
> 3 <%
> 4 a = 5
> 5 a = b # error
> 6 %>
>
> traceback should point line 5, but it points line 3.
>
> mako/codegen.py may be the cause. here is visitCode method in
> codegen.py
>
> def visitCode(self, node):
> if not node.ismodule:
> self.write_source_comment(node)
> self.printer.write_indented_block(node.text)
>
> node contains whole python block, so write_source_comment is called
> only one time for one python block. If it is called by line, it can be
> fixed. However I don't understand 'node' object yet, I wasn't able to
> fix it.

I wouldn't want to fix it that way, as we'd need to fully parse and re-render the Python code within blocks which is an extremely complicated task and would greatly destabilize the code. Also there would be Python comments on every line, which itself would throw off line numbers and would also interfere with multiline statements.

It's a little tricky here but perhaps some extra directives in the comment would help, based on the type of node:

# SOURCE LINE 3 PYTHON_BLOCK

so that when we calculate the "line map", we know we can give successive template_ln assignments within the loop at exceptions.py line 170. Just a thought...

>
> There is one more problem. When using module level block, <%! %>, it
> doesn't even show error lines with
> exceptions.html_error_template().render()

this is a more complex issue. I'd consider working patches if they don't add excess complexity or any backwards incompatibility.

Youngrok Pak

unread,
Dec 21, 2011, 11:17:19 PM12/21/11
to mako-d...@googlegroups.com


2011/12/22 Michael Bayer <mik...@zzzcomputing.com>


On Dec 21, 2011, at 2:32 PM, Youngrok Pak wrote:

> See this codes,
>
> 1 <h1>hello</h1>
> 2
> 3 <%
> 4 a = 5
> 5 a = b # error
> 6 %>
>
> traceback should point line 5, but it points line 3.
>
> mako/codegen.py may be the cause. here is visitCode method in
> codegen.py
>
>    def visitCode(self, node):
>        if not node.ismodule:
>            self.write_source_comment(node)
>            self.printer.write_indented_block(node.text)
>
> node contains whole python block, so write_source_comment is called
> only one time for one python block. If it is called by line, it can be
> fixed. However I don't understand 'node' object yet, I wasn't able to
> fix it.

I wouldn't want to fix it that way, as we'd need to fully parse and re-render the Python code within blocks which is an extremely complicated task and would greatly destabilize the code.   Also there would be Python comments on every line, which itself would throw off line numbers and would also interfere with multiline statements.

It's a little tricky here but perhaps some extra directives in the comment would help, based on the type of node:

# SOURCE LINE 3 PYTHON_BLOCK

so that when we calculate the "line map", we know we can give successive template_ln assignments within the loop at exceptions.py line 170.   Just a thought...


I see your point. However, you may not need to specify the type of node in comment. What if use the condition template_line.startswith('<%') ?

I tried some code on exceptions.py, line 180

            # calculate line number offset for python block

            lineno_offset = 0

            if template_line.startswith('<%'):

                while line_map[lineno - lineno_offset] == template_ln:

                    lineno_offset += 1

                template_ln = template_ln + lineno_offset - 1

                if template_ln <= len(template_lines):

                    template_line = template_lines[template_ln - 1]

                else:

                    template_line = None

The code looks somewhat ugly, but it worked for me. If you wish, I'll send pull request through github. 

 
>
> There is one more problem. When using module level block, <%! %>, it
> doesn't even show error lines with
> exceptions.html_error_template().render()

this is a more complex issue.   I'd consider working patches if they don't add excess complexity or any backwards incompatibility.



--
You received this message because you are subscribed to the Google Groups "Mako Templates for Python" group.
To post to this group, send email to mako-d...@googlegroups.com.
To unsubscribe from this group, send email to mako-discuss...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mako-discuss?hl=en.


Michael Bayer

unread,
Dec 22, 2011, 10:50:36 AM12/22/11
to mako-d...@googlegroups.com
On Dec 21, 2011, at 11:17 PM, Youngrok Pak wrote:


I see your point. However, you may not need to specify the type of node in comment. What if use the condition template_line.startswith('<%') ?

well that means you're re-parsing the template, it could be in a <%text> element, it could be in the middle of the line, its better that the lexer maintains that job.

The code looks somewhat ugly, but it worked for me. If you wish, I'll send pull request through github. 

right I think we're still stuck with mercurial/bitbucket for the moment, the github thing hasn't been working out as of yet....
Reply all
Reply to author
Forward
0 new messages