[Python-projects] Pylint: Disable-msg for a block or statement?

Benjamin Niemann pink at odahoda.de
Tue Apr 4 10:16:04 CEST 2006


On Thursday 16 March 2006 16:11, Sylvain Thénault wrote:
> On Thursday 16 March à 09:57, Pierre_Rouleau at ImpathNetworks.com wrote:
> > Mirko Friedenhagen wrote:
> > > googling I found this topic has been discussed a few months ago
> > > (http://lists.logilab.org/pipermail/python-projects/2005-June/000359.ht
> > >ml).
> >
> > Sylvain, has the facility described in the above URL been incorporated
> > inside the official build of pylint?
>
> I also would like such a feature into pylint but I didn't incorporated
> the provided patch because I thought at this time (and I still do) that
> there were better way to do it. However I didn't find the time to do it
> yet :( Since then, I've seen that Ned Batchelder's pycoverage module
> seems to have a way to disable coverage analysis for a portion of code
> similar to what I would like to have... Anyone interested in writting a
> patch for pylint based on this code and the referenced patch ?
> Anyway I'll give a higher priority to  this feature since a lot of people
> want it.

I finally found the time for a new try on this. Patches for pylint 0.10.0 and
astng 0.15.1 are attached.

"# pylint: disable-msg=..." and "# pylint: enable-msg=..." can now be
used everywhere in the source code and affects the statement (usually
a block) that 'contains' it - the comment must be between the first
and last line of the statement.

1  class foo:
2    # pylint: disable-msg=W1234
3    def bar(self):
4      # pylint: disable-msg=W4321
5      pass
6    def gnurz(self):
7      pass

W4321 is disable for the block 3-5, W1234 for block 1-7.

Implementation
--------------

PyLinter.process_tokens() collects the line numbers of all #pylint:
directives. Then a bottom-up ast walk computes the first and last line
of each statement, checks if there is a directive inbetween and sets
the msg state of all lines of the statement. My first thought was to
apply this only to block statements, but by applying it to all nodes,
you get extra stuff for free like

some_statement  # pylint: disable-msg=Ennn

which only affects this single line.

MessagesHandlerMixIn._module_msgs_state is now a dict of dicts
{ 'W0123': { 10: False, 11: True, ..., 25: True }, ... }
The msg code dictionaries contain entries for each line number where a
module-level enable-msg or disable-msg is active.
MessagesHandlerMixIn.is_message_enabled will lookup, if there's an
entry for the affected line (thus a 'line' argument was added).

This implementation is a 'superset' of the current
semantics. Directives at the top of the module apply to the 'block'
they are contained in, which happens to be the whole module.

A new method has been added to astng.nodes.NodeNG, which calculates
the last line number for a node and its children.

Issues
------

Performance: PyLinter.process_tokens() has to scan the complete file in
order to find all directives. Then an additional ast walk has to be performed
in order to collect the line numbers of the containing blocks. I didn't do
 any real performance testing to measure the impact - just a simple test:

Original V0.10.0:

pink at bateau:~/projects/pylint/pylint/test$ PYTHONPATH=../.. /usr/bin/time
python2.3 func_test.py
.............................................................................
.............................................................................
.............................................................................
. ---------------------------------------------------------------------- Ran
 232 tests in 6.993s

OK
6.57user 0.27system 0:07.84elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+4705minor)pagefaults 0swaps

Patched version:

pink at bateau:~/projects/pylint/pylint/test$ PYTHONPATH=../.. /usr/bin/time
python2.3 func_test.py
.............................................................................
.............................................................................
.............................................................................
. ---------------------------------------------------------------------- Ran
 232 tests in 7.304s

OK
7.06user 0.26system 0:08.13elapsed 90%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+4720minor)pagefaults 0swaps


Testsuite: unittest_lint.py/PyLinterTC.test_enable_message broken

P.S.: the tests 'func_noerror_staticmethod_as_decorator' and 'func_format'
fail with python2.4 but not 2.3. Known issue?

P.P.S.: took me a while to fix this, although I don't understand why: if I
change the lines in astng.nodes.NodeNG.last_source_line()

    try:
        return self.__dict__['_cached_last_source_line']
    except KeyError:
        ...

to

    try:
        return self._cached_last_source_line
    except AttributeError:
        ...

(which should be the obvious implementation), the test
'func_bad_assigment_to_exception_var' failed with two missing messages. Even
if every other change was removed, just calling walking the ast and calling
last_source_line() on the nodes caused this (and only this) test to fail.
Any explanation?

--
Benjamin Niemann
Email: pink at odahoda dot de
WWW: http://pink.odahoda.de/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: astng.patch
Type: text/x-diff
Size: 839 bytes
Desc: not available
URL: <http://lists.logilab.org/pipermail/python-projects/attachments/20060404/a9b55f93/attachment-0168.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pylint.patch
Type: text/x-diff
Size: 7402 bytes
Desc: not available
URL: <http://lists.logilab.org/pipermail/python-projects/attachments/20060404/a9b55f93/attachment-0169.patch>


More information about the Python-Projects mailing list