Python

【Python】コードチェックツールの使い方

こんにちは。湖山です。

業務で「Python」を触ることになった今日この頃。
衝撃的だったのが簡単にコードチェックを行うツールが充実していたこと。

美しいコード。誰が書いても同じ形式になるようなコーディング規約。
それが「Python」が人気な理由なのでしょう。

コードレビュー前にチェックツールを実行!!(鉄則)

それでは、コードチェックツールの使い方を見ていきましょう。

サンプルコード(修正前)

コードチェックの為の簡単なサンプルコード「sample.py」を用意しました。
分数の計算を表示するだけのプログラムです。

import time
import sys
import fractions

def calculator_addition(varA, varB):
  '''
  return sum of a and b
  '''
  varC = 42
  return (varA + varB)

print('1/2 + 1/3 = ', calculator_addition(fractions.Fraction(1, 2), fractions.Fraction(1, 3)))



sys.exit(0)

プログラム自体にはエラーはないため、実行すると以下のように処理結果が表示されます。

$ python sample.py
1/2 + 1/3 =  5/6

このプログラムの問題点はどこでしょうか?
ぱっと見で全て修正できる方は素晴らしいですが、それは初心者にはハードルが高いです。

そこで次のようなコードチェックツールを使って問題点を修正していきます。

各種ツールの紹介

pycodestyle

用途:スタイルチェック
詳細PEP 8 で規定されているPython公式のスタイルガイドに違反する箇所を指摘する

$ pycodestyle sample.py
sample.py:5:1: E302 expected 2 blank lines, found 1
sample.py:6:3: E111 indentation is not a multiple of four
sample.py:9:3: E111 indentation is not a multiple of four
sample.py:10:3: E111 indentation is not a multiple of four
sample.py:12:1: E305 expected 2 blank lines after class or function definition, found 1
sample.py:12:80: E501 line too long (94 > 79 characters)
sample.py:16:1: E303 too many blank lines (3)
sample.py:16:12: W292 no newline at end of file

pydocstyle

用途:Docstring のスタイルチェック
詳細PEP 257 で規定されている Docstring の書き方に違反する箇所を指摘する

$ pydocstyle sample.py
sample.py:1 at module level:
        D100: Missing docstring in public module
sample.py:6 in public function `calculator_addition`:
        D200: One-line docstring should fit on one line with quotes (found 3)
sample.py:6 in public function `calculator_addition`:
        D300: Use """triple double quotes""" (found '''-quotes)
sample.py:6 in public function `calculator_addition`:
        D400: First line should end with a period (not 'b')
sample.py:6 in public function `calculator_addition`:
        D403: First word of the first line should be properly capitalized ('Return', not 'return')

pyflakes

用途:エラー解析
詳細:未使用なインポート・変数が残っている個所を指摘する

$ pyflakes sample.py 
sample.py:1:1 'time' imported but unused
sample.py:9:3 local variable 'varC' is assigned to but never used

flake8

用途:スタイルチェック + エラー解析 + 複雑度チェック
  (pycodestyle + pyflakes + mccabe(複雑度チェッカー)
詳細:コードチェックの複合型。コードチェックツールでは1番人気。

$ flake8 sample.py
sample.py:1:1: F401 'time' imported but unused
sample.py:5:1: E302 expected 2 blank lines, found 1
sample.py:6:3: E111 indentation is not a multiple of four
sample.py:9:3: E111 indentation is not a multiple of four
sample.py:9:3: F841 local variable 'varC' is assigned to but never used
sample.py:10:3: E111 indentation is not a multiple of four
sample.py:12:1: E305 expected 2 blank lines after class or function definition, found 1
sample.py:12:80: E501 line too long (94 > 79 characters)
sample.py:16:1: E303 too many blank lines (3)
sample.py:16:12: W292 no newline at end of file

pylint

用途:スタイルチェック + エラー解析
詳細:更に強力なコードチェックツール。最後に10点満点のスコア表示。

$ pylint sample.py
No config file found, using default configuration
************* Module sample
W:  6, 0: Bad indentation. Found 2 spaces, expected 4 (bad-indentation)
W:  9, 0: Bad indentation. Found 2 spaces, expected 4 (bad-indentation)
W: 10, 0: Bad indentation. Found 2 spaces, expected 4 (bad-indentation)
C: 10, 0: Unnecessary parens after 'return' keyword (superfluous-parens)
C: 16, 0: Final newline missing (missing-final-newline)
C: 16, 0: Mixed line endings LF and CRLF (mixed-line-endings)
C:  1, 0: Missing module docstring (missing-docstring)
C:  5, 0: Argument name "varA" doesn't conform to snake_case naming style (invalid-name)
C:  5, 0: Argument name "varB" doesn't conform to snake_case naming style (invalid-name)
C:  9, 2: Variable name "varC" doesn't conform to snake_case naming style (invalid-name)
W:  9, 2: Unused variable 'varC' (unused-variable)
W:  1, 0: Unused import time (unused-import)

--------------------------------------------------------------------
Your code has been rated at -5.00/10 (previous run: -5.00/10, +0.00)

autopep8

用途:コード自動修正
詳細PEP 8スタイルガイドに準拠するように自動的にフォーマットするツール

$ autopep8 -i sample.py

サンプルコード(修正後)

各チェックツールの指摘を修正したコードが以下のようになります。

"""Calculator."""

import sys
import fractions


def calc(var_a, var_b):
    """Return sum of a and b."""
    return var_a + var_b


print('1/2 + 1/3 = ', calc(fractions.Fraction(1, 2), fractions.Fraction(1, 3)))


sys.exit(0)

まとめ

コーディングが完了したらレビュー前に以下のコマンドを最低限実行しましょう。

pycodestyle sample.py
flake8 sample.py
pylint sample.py
ABOUT ME
湖山 貴裕
はじめまして。 二児のお父さんプログラマーです。最近キャンプにも興味あり。夏には庭でキャンプしようともくろみ中。ボドゲ好き。チョコ好き。茶道経験者。 2012年大学卒業→IT企業就職 Java,VB.NET, C#, javascript等の企業向けシステム開発/主にバックエンドを担当/AWSを少しかじる→2020年フリーランスエンジニアへ転身 広島でAWS案件にて楽しく活動中