• No results found

Verifying code quality, pep8, pyflakes,

In document Mastering Python (Page 57-60)

and more

There are many tools for checking code quality in Python. The simplest ones, such as pep8, just validate a few simple PEP8 errors. The more advanced ones, such as pylint, do advanced introspections to detect potential bugs in otherwise working code. A large portion of what pylint offers is a bit over the top for many projects, but still interesting to look at.

flake8

The flake8 tool combines pep8, pyflakes, and McCabe to set up a quality standard for code. The flake8 tool is one of the most important packages for maintaining code quality in my packages. All the packages that I maintain have a 100% flake8 compliance requirement. It does not promise readable code, but at least it requires a certain level of consistency, which is very important when writing on a project with multiple programmers.

Pep8

One of the simplest tools used to check the quality of Python code is the pep8 package. It doesn't check everything that is in the PEP8 standard, but it goes a long way and is still updated regularly to add new checks. Some of the most important things checked by pep8 are as follows:

• Too much whitespace, such as def eggs(spam = 123): • Too many or too few blank lines

• Too long lines

• Syntax and indentation errors

• Incorrect and/or superfluous comparisons (not in, is not, if spam is True, and type comparisons without isinstance)

The conclusion is that the pep8 tool helps a lot with testing whitespace and some of the more common styling issues, but it is still fairly limited.

pyflakes

This is where pyflakes comes in. pyflakes is a bit more intelligent than pep8 and warns you about style issues such as:

• Unused imports

• Wildcard imports (from module import *) • Incorrect __future__ imports (after other imports)

But more importantly, it warns about potential bugs, such as the following: • Redefinitions of names that were imported

• Usage of undefined variables

• Referencing variables before assignment • Duplicate argument names

• Unused local variables

The last bit of PEP8 is covered by the pep8-naming package. It makes sure that your naming is close to the standard dictated by PEP8:

• Class names as CapWord

• Function, variable, and argument names all in lowercase • Constants as full uppercase and being treated as constants

• The first argument of instance methods and class methods as self and cls, respectively

McCabe

Lastly, there is the McCabe complexity. It checks the complexity of code by looking at the Abstract Syntax Tree (AST). It finds out how many lines, levels, and statements are there and warns you if your code has more complexity than a preconfigured threshold. Generally, you will use McCabe through flake8, but a manual call is possible as well. Using the following code:

def spam(): pass def eggs(matrix): for x in matrix: for y in x: for z in y: print(z, end='') print() print()

McCabe will give us the following output: # pip install mccabe

...

# python -m mccabe cabe_test.py 1:1: 'spam' 1 5:1: 'eggs' 4

Your maximum threshold is configurable, of course, but the default is 10. The McCabe test returns a number that is influenced by parameters such as the size of a function, the nested depths, and a few others. If your function reaches 10, it might be time to refactor the code.

flake8

All of this combined is flake8, a tool that combines these tools and outputs a single report. Some of the warnings generated by flake8 might not fit your taste, so each and every one of the checks can be disabled, both per file and for the entire project if needed. For example, I personally disable W391 for all my projects, which warns about blank lines at the end of a file. This is something I find useful while working on code so that I can easily jump to the end of the file and start writing code instead of having to append a few lines first.

Here is a demonstration with some poorly formatted code: def spam(a,b,c):

print(a,b+c) def eggs(): pass

It results in the following: # pip install flake8 ...

# flake8 flake8_test.py

flake8_test.py:1:11: E231 missing whitespace after ',' flake8_test.py:1:13: E231 missing whitespace after ',' flake8_test.py:2:12: E231 missing whitespace after ','

flake8_test.py:2:14: E226 missing whitespace around arithmetic operator flake8_test.py:4:1: E302 expected 2 blank lines, found 1

Pylint

pylint is a far more advanced—and in some cases better—code quality checker. The power of pylint does come with a few drawbacks, however. Whereas flake8 is a really fast, light, and safe quality check, pylint has far more advanced introspection and is much slower for this reason. In addition, pylint will most likely give you a large number of warnings, which are irrelevant or even wrong. This could be seen as a flaw in pylint, but it's actually more of a restriction of passive code analysis. Tools such as pychecker actually load and execute your code. In many cases, this is safe, but there are cases where it is not. Just think of what could happen when executing a command that deletes files.

While I have nothing against pylint, in general I find that most important problems are handled by flake8, and others can easily be avoided with some proper

coding standards. It can be a very useful tool if configured correctly, but without configuration, it is very verbose.

In document Mastering Python (Page 57-60)

Related documents