<html><body>
<p>Hi,<br>
<br>
Running pylint on the following code:<br>
===<br>
try:<br>
        pass<br>
finally:<br>
        # pylint: disable-msg=W0201<br>
        pass<br>
===<br>
produces this error:<br>
===<br>
I: 4: Locally disabling W0201<br>
Traceback (most recent call last):<br>
File "/usr/bin/pylint", line 4, in <module><br>
lint.Run(sys.argv[1:])<br>
File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 901, in __init__<br>
linter.check(args)<br>
File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 492, in check<br>
self.check_astng_module(astng, checkers)<br>
File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 594, in check_astng_module<br>
self.collect_block_lines(astng, orig_state)<br>
File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 428, in collect_block_lines<br>
self.collect_block_lines(child, msg_state)<br>
File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 428, in collect_block_lines<br>
self.collect_block_lines(child, msg_state)<br>
File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 437, in collect_block_lines<br>
first, last = node.block_range(lineno)<br>
File "/usr/lib/python2.5/site-packages/logilab/astng/nodes.py", line 316, in elsed_block_range<br>
if node.else_:<br>
AttributeError: TryFinally instance has no attribute 'else_'<br>
===<br>
<br>
The problem is caused by the "disable-msg" comment. The exact ID used in the comment doesn't matter, as long as its a number of an existing message.<br>
<br>
pylint 0.14.0,<br>
astng 0.17.2, common 0.22.1<br>
Python 2.5.1 (r251:54863, Mar 7 2008, 03:41:45)<br>
<br>
The problem is that the "finally" clause is expected in an attribute named "else_" of the "TryFinally" node, but the attribute is named "final" instead.<br>
The following patch to astng fixes the problem:<br>
===<br>
--- logilab-astng-0.17.2.org/nodes.py        2008-01-14 13:32:55.000000000 +0100<br>
+++ logilab-astng-0.17.2/nodes.py        2008-07-30 17:13:40.000000000 +0200<br>
@@ -313,10 +313,11 @@<br>
"""<br>
if lineno == node.source_line():<br>
return lineno, lineno<br>
- if node.else_:<br>
- if lineno >= node.else_.source_line():<br>
- return lineno, node.else_.last_source_line()<br>
- return lineno, node.else_.source_line() - 1<br>
+ block = node.final if isinstance(node, TryFinally) else node.else_<br>
+ if block:<br>
+ if lineno > node.body.last_source_line():<br>
+ return lineno, block.last_source_line()<br>
+ return lineno, block.source_line() - 1<br>
return lineno, last or node.last_source_line()<br>
<br>
TryFinally.block_range = elsed_block_range<br>
===<br>
<br>
Note that this patch changes two things:<br>
1. use "node.final" instead of "node.else_" if node is of type TryFinally<br>
2. the check whether the given line is in the body or in the else/finally clause is done versus the last line of the body instead of the first line of else/finally clause<br>
<br>
The reason for 2 is that the number given for the first line of the else/finally clause is the number of the first line with a statement on it, while the "lineno" argument is the number of the line with the "# pylint: disable-msg" comment on it, which can be located before the first statement in the block.<br>
<br>
I just realized I used the Python 2.5 style "if" here; if astng supports older Python versions as well, please replace it with a traditional "if".<br>
<br>
Bye,<br>
                Maarten<br>
</body></html>