I've always been a big fan of static analysis. While I was working with C and C++, I was scaning my code with:

For a longer list of static analyzers for each language, look at wikipedia

As I'm now mostly programing in Python (I'm working on LAVA), I had a closer look at the avaiable static analyzers for this language.

I haven't found any static analyzer for Python as powerful as the one available for C or /C++. However the ones listed in this article must be used on your Python code. That's the bare minimum.

PEP

The first tool to run on any Python source code would be pep8. You can also give a try to pep256.

pep8 is a simple tool that only check for coding style. Python does advice the use of a standardize code style: PEP8. It's recommanded to use the same coding style in order to keep a common style among the Python community.

However, you can obviously configure pep8 to match your coding style.

def main():
  print("Hello" + " World")

if __name__ == "__main__":
    main()

If you run pep8 on this file you will get:

pep8 code.py
code.py:2:3: E111 indentation is not a multiple of four

Pylint

Pylint is more of a static anylizer than pep8 as it actually check for some Python common errors. For instance, on this example:

def append(data=[]):
    data.append(1)
    return data

print(append())
[1]
print(append())
[1, 1]
print(append())
[1, 1, 1]

This is usualy not what your are expecting. Pylint will warn you:

pylint code.py
No config file found, using default configuration
************* Module code
C:  1, 0: Missing module docstring (missing-docstring)
W:  1, 0: Dangerous default value [] as argument (dangerous-default-value)
C:  1, 0: Missing function docstring (missing-docstring)
[...]
Global evaluation
-----------------
Your code has been rated at 0.00/10

As you can see, Pylint is rating the source code (and show the evolution of this rate).

Vulture

Vulture is specialized in dead code elimination. Due to the dynamic nature of Python, such task is not as easy as it is with C. So don't expect any tool to find all dead code.

def append(data=[]):
    data.append(1)
    return data

def unused():
    for i in range(0, 10):
        append()

def main():
    append()

if __name__ == '__main__':
    main()

Running vulture will give:

vulture code.py
code.py:5: Unused function 'unused'
code.py:6: Unused variable 'i'

Pychecker

Another useful tool: Pychecker does provide some interesting information. However, it only works with Python2.

code.py:2: Modifying parameter (data) with a default value may have unexpected consequences
code.py:6: Local variable (i) not used

Prospector

I discovered prospector some weeks ago and that's now the only one I'm using. In fact, it uses all the other static analyzers (dodgy, pep257, pep8, pyflakes, pylint, vulture, pyroma, frosted) and provides a nice report.

Messages
========

code.py
  Line: 1
    pylint: dangerous-default-value / Dangerous default value [] as argument
  Line: 6
    pylint: unused-variable / Unused variable 'i' (col 8)



Check Information
=================
         Started: 2016-05-13 17:29:31.466860
        Finished: 2016-05-13 17:29:31.553182
      Time Taken: 0.09 seconds
       Formatter: grouped
        Profiles: default, no_doc_warnings, no_test_warnings, strictness_medium, strictness_high, strictness_veryhigh, no_member_warnings
      Strictness: None
  Libraries Used: 
       Tools Run: dodgy, mccabe, pep8, profile-validator, pyflakes, pylint
  Messages Found: 2

My advice would be to run prospector regularly to track common mistakes. It does sometime found real bugs.


type() vs isinstance()

mar. 03 mai 2016 by Rémi Duraffort

When running pylint on your Python source code, you might encounter this message:

Using type() instead of isinstance() for a typecheck. (unidiomatic-typecheck)

This message will be raised for this kind of code:

d = dict()
if type(d) == dict:
    print("d is a dict")

The code is valid but pylint does ...

read more

Migrating from Python2 to Python3

mar. 19 avril 2016 by Rémi Duraffort

Porting code from Python 2 to Python 3 is made easier by using 2to3. This application will find patterns that should be changed to keep the same behavior in Python 2 and 3.

However, 2to3 is sometime too conservative, trying to keep the exact same semantic.

For instance, dictionaries functions ...

read more

@FOSDEM

mer. 08 janvier 2014 by Rémi Duraffort

We will be at FOSDEM to talk about PRoot and some other tools based on it.

Cedric will do a Lightning talk saturday about syscall instrumentation. He will present some tools, based on syscall instrumentation, that we develop and use at STMicroelectronics:

  • PRoot, emulate chroot, bind mount and binfmt_misc for ...
read more

Pretending to be root inside PRoot

jeu. 21 novembre 2013 by Rémi Duraffort

While working on PRoot to improve the extension that fake the root user, I (re)discovered an old article that I never published before. So let's focus on the fake_id0 feature and on how it allows to use package manager directly inside the root file systems.

Some root causes ...

read more

PRoot now in Debian

mar. 20 août 2013 by Rémi Duraffort

A really short message to inform you that PRoot is now part of Debian Sid.

You can now install PRoot with apt-get install proot.

Enjoy !

read more

Scaling the time

lun. 24 septembre 2012 by Rémi Duraffort

Using valgrind on time-dependent softwares like VLC media player is often a nightmare and leads to poor results. Let's present a simple and elegant way to workaround this issue

Valgrind and realtime softwares

Valgrind is a really useful tool that checks for memory leaks, wrong memory access and many ...

read more

Making VLC at home

ven. 04 mai 2012 by Rémi Duraffort

In my previous article, I showed a way to setup and jump into a root file system in order to test a software in this environment.

Using PRoot, such task looks really easy and does not require any privileges. We will now finish this setup in order to build and ...

read more

PRoot sorcery

lun. 16 avril 2012 by Rémi Duraffort

A good practice for software developer is to provide a test suite while developing a software. When developing for Linux, it's also a good practice to compile the software and run the test suite on many distributions like Debian, Ubuntu, Fedora, ArchLinux, Centos, Slackware and for both i386 and ...

read more

Born to be PRoot

lun. 09 avril 2012 by Rémi Duraffort

It's been a long time since my last post on thit blog. To start again in a good shape I will seize the opportunity of a new version of PRoot to present this open source software in a cycle of articles.

What is PRoot about?

PRoot is a user-space ...

read more