[Python-projects] pylint: parse error on disable-msg commentin finally clause (retry)

Maarten ter Huurne maarten.ter.huurne at philips.com
Thu Jul 31 13:35:11 CEST 2008


syt at logilab.fr wrote on 2008-07-31 08:36:33 AM:

> On Wed, Jul 30, 2008 at 05:40:30PM +0200, Maarten ter Huurne wrote:
> > 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.
>
> great! I've applied the patch in the astng repository. Thank you very
> mutch.

Our nightly regression test found a problem in the patch. It's supposed to
test our code, but indirectly it tests pylint too :)

There is an improved patch:
===
--- 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-31 13:22:15.000000000 +0200
@@ -308,15 +308,16 @@
 TryExcept.block_range = try_except_block_range

 def elsed_block_range(node, lineno, last=None):
-    """handle block line numbers range for try/finally, for and while
+    """handle block line numbers range for try/finally, if, for and while
     statements
     """
     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 >= block.fromlineno:
+            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
===

The problem was that elsed_block_range() can be called on "if" blocks too,
and these do not have a "body" attribute. The fix is to get the actual
first line of the "else/finally" block instead of the last line before it.
The "fromlineno" attribute seems to provide this (unlike source_line(),
which returns the line of the first statement inside the block).

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


More information about the Python-Projects mailing list