LoginSignup
2
8

More than 3 years have passed since last update.

プロご用達 Pythonコードの質を保つために入れておきたいパッケージ4選

Posted at

プロご用達 Pythonコードの質を保つために入れておきたいパッケージ4選

flake8 ... コードチェック
black ... コード自動整形
isort ... インポートをソート
mypy ... 静的型チェック

全部 pip で入る。
コミットタイミングでJenkinsなどでチェックするのが良い。
レビューのコストが下がり、コードの品質が保たれるのでやったほうがいい

flake

以下のような気持ち悪いコード、見ると吐き気がしますね。。。

from flask import Blueprint

sample = Blueprint("sample1", __name__)

@sample.route("/")
def index():
    print(

        "sample.index"
    )
    return "sample.index"

flakeコマンドを実行すると修正すべき箇所が表示される。

$ flake8 ./app/views/sample.py
./app/views/sample.py:5:1: E302 expected 2 blank lines, found 1
./app/views/sample.py:8:1: W293 blank line contains whitespace

black

flakeはコードチェックだけで修正まではしてくれません
blackはコード自動整形を行いflakeの修正箇所を修正

$ black ./app/views/sample.py
reformatted app/views/sample.py
All done! ✨ 🍰 ✨
1 file reformatted.

修正後のコードいい感じに

from flask import Blueprint

sample = Blueprint("sample1", __name__)


@sample.route("/")
def index():
    print("sample.index")
    return "sample.index"

isort

公式サイトより、このようなコード殺意覚えますね。。。

from my_lib import Object

print("Hey")

import os

from my_lib import Object3

from my_lib import Object2

import sys

from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14

import sys

from __future__ import absolute_import

from third_party import lib3

print("yo")

isort コマンド実行

$ isort ./app/views/sample2.py
Fixing /Users/takashimorita/Sites/weekend-hackathon/app/views/sample2.py

このように綺麗にまとめてくれる。

from my_lib import Object

print("Hey")

from __future__ import absolute_import

import os
import sys

from my_lib import Object2, Object3
from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9,
                         lib10, lib11, lib12, lib13, lib14, lib15)

print("yo")

mypy

mypyはそのままだと警告が出るので、許容すべきオプションを付けて実行すると良い。
下のオプションは一例

--ignore-missing-imports ... import先のチェックはしない
--no-warn-no-return ... returnが無くても警告しない
--disallow-untyped-calls ... アノテーションされていない関数呼出しを禁止する。
--disallow-untyped-defs ... アノテーションされていない関数を禁止する。
--strict-optional ... None に関する型チェック

def main(num):
    return num + 1


if __name__ == "__main__":
    main(123)

このサンプルに対してmypyを実行すると
main関数の返り値とmain関数の引数にアノテーションがないので警告される

$ mypy -i --ignore-missing-imports --no-warn-no-return --disallow-untyped-calls --disallow-untyped-defs --strict-optional ./app/views/sample3.py
app/views/sample3.py:1: error: Function is missing a type annotation
app/views/sample3.py:6: error: Call to untyped function "main" in typed context
Found 2 errors in 1 file (checked 1 source file)

アノテーションを設定する

def main(num: int) -> int:
    return num + 1


if __name__ == "__main__":
    main(123)

再度、mypyを実行すると成功する

$ mypy -i --ignore-missing-imports --no-warn-no-return --disallow-untyped-calls --disallow-untyped-defs --strict-optional ./app/views/sample3.py
Success: no issues found in 1 source file
2
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
8