PyChecker is a cool tool for checking Python scripts for bugs. It works with Python 2.0 – 2.7. In this article, we will write some crappy code to see what PyChecker can pick up on. Then we’ll improve the code according to what we find until the code checks out. According to PyChecker’s website, it can detect the following problems:

  • No global found (e.g., using a module without importing it)
  • Passing the wrong number of parameters to functions/methods/constructors
  • Passing the wrong number of parameters to builtin functions & methods
  • Using format strings that don’t match arguments
  • Using class methods and attributes that don’t exist
  • Changing signature when overriding a method
  • Redefining a function/class/method in the same scope
  • Using a variable before setting it
  • self is not the first parameter defined for a method
  • Unused globals and locals (module or variable)
  • Unused function/method arguments (can ignore self)
  • No doc strings in modules, classes, functions, and methods

Getting Started

We won’t test everything that it can detect, but we can make some pretty messy code for PyChecker to check. Let’s start coding!

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"

This code doesn’t really do much of anything and is only for illustration purposes. According to PyChecker, there are four problems with this code. Can you see the issues? If not, then let’s find out how to use PyChecker to expose them! Once you have installed PyChecker and put it on your path (see PyChecker’s documentation), you should be able to do the following command:


C:\Users\Mike\Documents\My Dropbox\Scripts\code analysis>pychecker bad.py

Note: The above only works if you have pychecker on your system path on Windows. Technically, on Windows you will be using pychecker.bat

If you do this, you’ll end up with something like the following:

Hopefully you can tell what that all means, but we’ll break it down just in case you don’t. There are four problems that it has identified. The first issue it found is that we import the sys module, but we don’t use it. The second issue is the opposite of the first. We refer to the platform module, but it’s not actually imported! Thirdly, we call our getWeight method and it reports that we passed it too many parameters. I think PyChecker may have a bug here as our method should accept one method, not zero. The “this” parameter must confuse PyChecker. Fortunately, the last problem it finds is that getWeight doesn’t have self as the first parameter. This kind of rectifies the bug I mentioned. While the first method doesn’t require us to name it “self”, that is the normal naming convention for the first parameter in a class method.

Other Tips

PyChecker doesn’t just work on the command line. You can also use it directly in your code! All you have to do is import PyChecker at the top of your module, like this:

import pychecker.checker

This will make PyChecker check all the following imported modules, although it won’t do the main module. What does that mean? It means that if you stick that line in the example we used, you won’t see any errors related to that code. The PyChecker documentation says that you can also set PyChecker’s option via os.environ. Here’s an example:

os.environ['PYCHECKER'] = 'command line options here'

Speaking of which, here are the common command line options:

OptionsDescriptionDefault
--onlyonly warn about files passed on the command lineno
-#, --limitthe maximum number of warnings to be displayed 10
--no-shadowbuiltincheck if a variable shadows a builtinoff
-q, --stdlibignore warnings from files under standard libraryoff
-T, --argsusedunused method/function argumentson

If you’d like a full list of commands, type the following: pychecker -h

NOTE: PyChecker’s docstring checking is off by default, so if you want it you need to pass the “-m -f” commands. This only found the class module’s empty docstring. There seems to be a minor bug with “-f” in which it thinks empty doc strings are ok. I have alerted the PyChecker team to that.

Wrapping Up

I think PyChecker is pretty cool and it looks like it could be a handy tool. Give it a try and see what you think!

Additional Reading

  • PyChecker official website
  • PyLint - another project that’s in the same vein as PyChecker
  • pyflakes – another similar project
  • Doug Hellman’s review of Python Static Code Analyzers from the Python Magazine
Print Friendly