Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pylint: can inherited public methods be exclude from statistics?

Tags:

python

pylint

Pylint keeps reporting an error (R: 73,0:MyLogging: Too many public methods (22/20)) for the following code:

class MyLogging(logging.Logger):

    def foo(self):
        pass

    def bar(self):
        pass

At first I thought it was a bug in Pylint since the MyLogging class had exactly 22 lines of code, but then I realized, that it was including all public methods from the base class logging.Logger as well, which added 20 to the statistics.

Is it possible to exclude base classes' public methods from Pylint statistics?

PS.: I'm aware I can change max-public-methods to a higher number, or add a one-time exception with # pylint: disable=R0904

like image 795
Jovik Avatar asked Jan 15 '13 13:01

Jovik


2 Answers

There are ways, but none of them are good.

This is not configurable: you can check the code in Pylint's design_analysis.MisdesignChecker, within def leave_class:

for method in node.methods():
    if not method.name.startswith('_'):
        nb_public_methods += 1

The above code simply iterates over all methods not starting with "_" and counts them as public methods.

Consequently, I see two ways to do what you want to do:

  1. fork Pylint and modify this method:

     for method in node.methods():
         if not method.name.startswith('_') and method.parent == node:
             nb_public_methods += 1
    

    method.parent - the class node where this function is defined; also in your leave_class function you have a parameter node - which is the class node.

    Comparing them you can understand if it is the current class or not.

  2. disable this rule in the Pylint configuration and create you own plugin:

     MAX_NUMBER_PUBLIC_METHODS = 3
     class PublicMethodsChecker(BaseChecker):
         __implements__ = (IASTNGChecker,)
    
         name = 'custom-public-methods-checker'
    
         msgs = {
             "C1002": ('Too many public methods (%s/%s)',
                   'Used when class has too many public methods, try to reduce \
                    this to get a more simple (and so easier to use) class.'),
         }
    
         def leave_class(self, node):
             """check number of public methods"""
             nb_public_methods = 0
             print type(node)
             for method in node.methods():
                 if not method.name.startswith('_') and method.parent == node:
                     nb_public_methods += 1
             if nb_public_methods > MAX_NUMBER_PUBLIC_METHODS:
                  self.add_message('C1002',
                              node=node,
                              args=(nb_public_methods, MAX_NUMBER_PUBLIC_METHODS))
    

    Basically, this implementation is the slightly modified excerpt of design_analysis.MisdesignChecker from the Pylint source code.

For more information about plugins, see Helping pylint to understand things it doesn't, and in the Pylint source code.

like image 121
RomanI Avatar answered Nov 15 '22 20:11

RomanI


There is currently no configuration in pylint allowing to ignore parent methods. You may do what Romanl is suggesting to by pass the problem until the issue I've created for your pb is resolved upstream (http://www.logilab.org/ticket/116963)

like image 45
sthenault Avatar answered Nov 15 '22 22:11

sthenault