[Python-projects] pylint: parse error on disable-msg comment in finally clause

Maarten ter Huurne maarten.ter.huurne at philips.com
Wed Jul 30 17:32:58 CEST 2008



Hi,

Running pylint on the following code:
===
try:
      pass
finally:
      # pylint: disable-msg=W0201
      pass
===
produces this error:
===
I:  4: Locally disabling W0201
Traceback (most recent call last):
  File "/usr/bin/pylint", line 4, in <module>
    lint.Run(sys.argv[1:])
  File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 901, in
__init__
    linter.check(args)
  File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 492, in
check
    self.check_astng_module(astng, checkers)
  File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 594, in
check_astng_module
    self.collect_block_lines(astng, orig_state)
  File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 428, in
collect_block_lines
    self.collect_block_lines(child, msg_state)
  File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 428, in
collect_block_lines
    self.collect_block_lines(child, msg_state)
  File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 437, in
collect_block_lines
    first, last = node.block_range(lineno)
  File "/usr/lib/python2.5/site-packages/logilab/astng/nodes.py", line 316,
in elsed_block_range
    if node.else_:
AttributeError: TryFinally instance has no attribute 'else_'
===

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.

pylint 0.14.0,
astng 0.17.2, common 0.22.1
Python 2.5.1 (r251:54863, Mar  7 2008, 03:41:45)

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.
The following patch to astng fixes the problem:
===
--- logilab-astng-0.17.2.org/nodes.py     2008-01-14 13:32:55.000000000
+0100
+++ logilab-astng-0.17.2/nodes.py   2008-07-30 17:13:40.000000000 +0200
@@ -313,10 +313,11 @@
     """
     if lineno == node.source_line():
         return lineno, lineno
-    if node.else_:
-        if lineno >= node.else_.source_line():
-            return lineno, node.else_.last_source_line()
-        return lineno, node.else_.source_line() - 1
+    block = node.final if isinstance(node, TryFinally) else node.else_
+    if block:
+        if lineno > node.body.last_source_line():
+            return lineno, block.last_source_line()
+        return lineno, block.source_line() - 1
     return lineno, last or node.last_source_line()

 TryFinally.block_range = elsed_block_range
===

Note that this patch changes two things:
1. use "node.final" instead of "node.else_" if node is of type TryFinally
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

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.

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".

Bye,
            Maarten
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.logilab.org/pipermail/python-projects/attachments/20080730/2639148b/attachment.htm 


More information about the Python-Projects mailing list