pyflakes – the passive checker of Python programs

Posted by Mike on June 13th, 2012 filed in Cross-Platform, Python, Testing

There are several code analysis tools for Python. The most well known is pylint. Then there’s pychecker and now we’re moving on to pyflakes. The pyflakes project is a part of something known as the Divmod Project. Pyflakes doesn’t actually execute the code it checks, unlike pychecker. Of course, pylint also doesn’t execute the code. Regardless, we’ll take a quick look at it and see how pyflakes works and if it’s better than the competition.

Getting Started

As you have probably guessed, pyflakes is not a part of the Python distribution. You will need to download it from PyPI or from the project’s launchpad page. Once you have it installed, you can run it against some of your own code. Or you can follow along and see how it works with our test script.

Running pyflakes

We’ll be using a super simple and pretty silly example script. In fact, it’s the same one we used for the pylint and pychecker articles. Here it is again for your viewing pleasure:

import sys
 
########################################################################
class CarClass:
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, color, make, model, year):
        """Constructor"""
        self.color = color
        self.make = make
        self.model = model
        self.year = year
 
        if "Windows" in platform.platform():
            print "You're using Windows!"
 
        self.weight = self.getWeight(1, 2, 3)
 
    #----------------------------------------------------------------------
    def getWeight(this):
        """"""
        return "2000 lbs"

As was noted in the other articles, this dumb code has 4 issues, 3 of which would stop the programming from running. Let’s see what pyflakes can find! Try running the following command and you’ll see the following output:


C:\Users\mdriscoll\Desktop>pyflakes crummy_code.py
crummy_code.py:1: 'sys' imported but unused
crummy_code.py:15: undefined name 'platform'

While pyflakes was super fast at returning this output, it didn’t find all the errors. The getWeight method call is passing too many arguments and getWeight method itself is defined incorrectly as it doesn’t have a “self” argument. Well, you can actually call the first argument anything you want, but by convention it’s usually called “self”. If you fixed your code according to what pyflakes told you, your code still wouldn’t work.

Wrapping Up

The pyflakes website claims that pyflakes is faster than pychecker and pylint. I didn’t test this, but anyone who wants to can do so pretty easily by just running it against some big files. Maybe grab the BeautifulSoup file or run it (and the others) against something complex like PySide or SQLAlchemy and see how they compare. I personally am disappointed that it didn’t catch all the issues I was looking for. I think for my purposes, I’ll be sticking with pylint. This might be a handy tool for a quick and dirty test or just to make you feel better after a particularly poor result from a pylint scan.

Further Reading

Print Friendly

  • http://javarevisited.blogspot.sg/2011/06/10-examples-of-grep-command-in-unix-and.html Rajiv

    has any one tried 
    PyChecker ? If I am using 
    pylint , what am I missing ? 

  • Piotr Skamruk

    try http://pypi.python.org/pypi/flake8
    it integrates pyflakes with pep8
    it can be easly integrated with vim

  • driscollis

    I wrote an article on PyChecker as well. I don’t think it really adds much to PyLint though.

  • JadKik

    “getWeight method itself is defined incorrectly as it doesn’t have a “self” argument. “, that’s not true! “self” is passed as a positional argument, not as a keyword argument, so it doesn’t matter what it is called, as long as it is the first one. However, it’s true that pyflakes should have told you about it, because everybody use “self”.

  • driscollis

    Sorry about that. I must have been distracted when I wrote that sentence.

  • Phil Frost

    Is the call to getWeight an error? Only if you didn’t subclass CarClass and override getWeight. Also only if you don’t have a metaclass in play that transmutes getWeight methods. Or, maybe raising ArgumentError is the desired behavior.

    A human can read this code and see that none of these are the case, and there’s an error here. But, a computer that isn’t an AI can’t know for sure. It can’t extract the specified behavior out of the comments. It can’t make good decisions on how things should be. It can say there’s *probably* an error, but then you introduce the possibility of false positives. It also can’t know what your style preference is. From PEP 20, the Zen of Python:

    “In the face of ambiguity, refuse the temptation to guess.”

    Pyflakes’s refusal to complain about anything that isn’t *positively* an error is its distinguishing feature. It’s why it has no options to disable checks: there are no checks you’d ever want to disable.