Pylint, PyChecker or PyFlakes? [closed]
Asked Answered
D

2

409

I would like to get some feedback on these tools on:

  • features;
  • adaptability;
  • ease of use and learning curve.
Deenadeenya answered 15/9, 2009 at 18:24 Comment(4)
Shouldn't the title be edited to include pep8 as an option? At first, I thought you guys were talking about the proposition, not an actual PyPI package.Trombone
I suggest you start with something very strict, make it less strict at first for obviously painful cases, use it for a while, then get stricter later on by adding back rules (not all at the same time). Do it slowly but do it.Tooley
Just mentioning prospector ;)Handfasting
I'd just like to raise an objection to the closure of this question, as this is an unfortunate tendency in SO to continually anticipate opinion based answers, even before any answers have been submitted. It's kind of sad to have to say it, but of course answers to questions like this can be submitted based on technical pros and cons that are inherent in the feature sets of the software under investigation. How else are folks going to get answers on which packages experienced and knowledgeable devs are using for particular purposes? E.g. why not use Pylint? Maybe it breaks code sometimes?Jehovist
D
295

Well, I am a bit curious, so I just tested the three myself right after asking the question ;-)

Ok, this is not a very serious review, but here is what I can say:

I tried the tools with the default settings (it's important because you can pretty much choose your check rules) on the following script:

#!/usr/local/bin/python
# by Daniel Rosengren modified by e-satis

import sys, time
stdout = sys.stdout

BAILOUT = 16
MAX_ITERATIONS = 1000

class Iterator(object) :

    def __init__(self):

        print 'Rendering...'
        for y in xrange(-39, 39):
            stdout.write('\n')
            for x in xrange(-39, 39):
                if self.mandelbrot(x/40.0, y/40.0) :
                    stdout.write(' ')
                else:
                    stdout.write('*')


    def mandelbrot(self, x, y):
        cr = y - 0.5
        ci = x
        zi = 0.0
        zr = 0.0

        for i in xrange(MAX_ITERATIONS) :
            temp = zr * zi
            zr2 = zr * zr
            zi2 = zi * zi
            zr = zr2 - zi2 + cr
            zi = temp + temp + ci

            if zi2 + zr2 > BAILOUT:
                return i

        return 0

t = time.time()
Iterator()
print '\nPython Elapsed %.02f' % (time.time() - t)

As a result:

  • PyChecker is troublesome because it compiles the module to analyze it. If you don't want your code to run (e.g, it performs a SQL query), that's bad.
  • PyFlakes is supposed to be light. Indeed, it decided that the code was perfect. I am looking for something quite severe so I don't think I'll go for it.
  • PyLint has been very talkative and rated the code 3/10 (OMG, I'm a dirty coder !).

Strong points of PyLint:

  • Very descriptive and accurate report.
  • Detect some code smells. Here it told me to drop my class to write something with functions because the OO approach was useless in this specific case. Something I knew, but never expected a computer to tell me :-p
  • The fully corrected code run faster (no class, no reference binding...).
  • Made by a French team. OK, it's not a plus for everybody, but I like it ;-)

Cons of Pylint:

  • Some rules are really strict. I know that you can change it and that the default is to match PEP8, but is it such a crime to write 'for x in seq'? Apparently yes because you can't write a variable name with less than 3 letters. I will change that.
  • Very very talkative. Be ready to use your eyes.

Corrected script (with lazy doc strings and variable names):

#!/usr/local/bin/python
# by Daniel Rosengren, modified by e-satis
"""
Module doctring
"""


import time
from sys import stdout

BAILOUT = 16
MAX_ITERATIONS = 1000

def mandelbrot(dim_1, dim_2):
    """
    function doc string
    """
    cr1 = dim_1 - 0.5
    ci1 = dim_2
    zi1 = 0.0
    zr1 = 0.0

    for i in xrange(MAX_ITERATIONS) :
        temp = zr1 * zi1
        zr2 = zr1 * zr1
        zi2 = zi1 * zi1
        zr1 = zr2 - zi2 + cr1
        zi1 = temp + temp + ci1

        if zi2 + zr2 > BAILOUT:
            return i

    return 0

def execute() :
    """
    func doc string
    """
    print 'Rendering...'
    for dim_1 in xrange(-39, 39):
        stdout.write('\n')
        for dim_2 in xrange(-39, 39):
            if mandelbrot(dim_1/40.0, dim_2/40.0) :
                stdout.write(' ')
            else:
                stdout.write('*')


START_TIME = time.time()
execute()
print '\nPython Elapsed %.02f' % (time.time() - START_TIME)

Thanks to Rudiger Wolf, I discovered pep8 that does exactly what its name suggests: matching PEP8. It has found several syntax no-nos that Pylint did not. But Pylint found stuff that was not specifically linked to PEP8 but interesting. Both tools are interesting and complementary.

Eventually I will use both since there are really easy to install (via packages or setuptools) and the output text is so easy to chain.

To give you a little idea of their output:

pep8:

./python_mandelbrot.py:4:11: E401 multiple imports on one line
./python_mandelbrot.py:10:1: E302 expected 2 blank lines, found 1
./python_mandelbrot.py:10:23: E203 whitespace before ':'
./python_mandelbrot.py:15:80: E501 line too long (108 characters)
./python_mandelbrot.py:23:1: W291 trailing whitespace
./python_mandelbrot.py:41:5: E301 expected 1 blank line, found 3

Pylint:

************* Module python_mandelbrot
C: 15: Line too long (108/80)
C: 61: Line too long (85/80)
C:  1: Missing docstring
C:  5: Invalid name "stdout" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C: 10:Iterator: Missing docstring
C: 15:Iterator.__init__: Invalid name "y" (should match [a-z_][a-z0-9_]{2,30}$)
C: 17:Iterator.__init__: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)

[...] and a very long report with useful stats like :

Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |0        |=          |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000    |=          |
+-------------------------+------+---------+-----------+
Deenadeenya answered 15/9, 2009 at 19:21 Comment(13)
The purpose of pyflakes is to statically analyze your code to make sure there will be no name errors or unused variables/imports.Mcnamee
Am I getting this wrong or is there no strong/weak point for PyChecker nor PyFlakes?Firn
Strong/weak points for PyChecker and PyFlakes is given here: stackoverflow.com/a/44996/452885Viewpoint
also try pyhint if you’ve since found that pylint is a pain in the ass and ovely finnicky ;)Menstrual
"Strongs points : Very descriptive and accurate report." Which report? Is this section about all the tools or just one?Peachey
I wonder. I abviously wrote the whole pro/con only about PyLint. I have no idea why I wrote in this stupid way. Hangover maybe ? Sorry guys.Deenadeenya
flake8 covers both pyflakes and pep8. Strongly suggest it over just using one or the other.Trombone
“PyChecker is troublesome because it compiles the module to analyze it. If you don't want your code to run […] that's bad.”: you know, an if __name__ == '__main__': doesn't cost much ;-) .Clower
@Clower It may not cost much, but that's a bizarre comment to make about a tool whose very purpose is to check for mistakes.Your
FYI For pylint you could use: pylint --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" to get the same unix style output messageTractable
FYI For pylint you could use: pylint -rn to avoid the report outputTractable
pylint is talkative but it really do its jobs. Some rules are quite trick, like variable name cannot be shorter than 3 characters or import must be before any code even sys.path.append()Assentation
Exactery. Why isn't flake8 in the mix here?Jehovist
E
95

pep8 was recently added to PyPi.

  • pep8 - Python style guide checker
  • pep8 is a tool to check your Python code against some of the style conventions in PEP 8.

It is now super easy to check your code against pep8.

See http://pypi.python.org/pypi/pep8

Empery answered 16/9, 2009 at 8:45 Comment(5)
There is IMO better package. flake8, it combines the two and adds conditional complexity, works on directories and is generally good.Him
Running flake8 for the first time taught me that I jumped right into a project without learning that Python strongly prefers spaces for some reason. I had to use --ignore W191 to make the output useful.Depressed
Note that recent versions of pep8 are now called pycodestyle; see pypi.org/project/pycodestyle @Depressed : python strongly prefers spaces because that is what's specified by the style guidelines. Spaces aren't necessarily superior, but consistency across the community is a great advantage, and the community has decided on spaces, so do that.Diabolic
How do I best configure my editor (either BBEdit or vim) to use spaces for Python and tabs for absolutely everything else? It seems that (at least for BBEdit) it’s a global setting.Depressed
@Depressed In vim, you can do :set et (short for expandtabs) and then :retab to convert all tabs in the current buffer into spaces. It may also be useful to set ts=4 sts=4 sw=4 (tabstop, softtabstop, shiftwidth) first. As far as a general approach, I prefer using editorconfig.org and its plugins to set the right settings in a repo, so you don't have to worry about reconfiguring your editor for different codebases.Rosalie

© 2022 - 2024 — McMap. All rights reserved.