Pythonのimport文の並び順のフォーマットについて【isort】
前回の記事に続いて、Pythonのimport文の並び順のフォーマットについて書く。
isortについて
Pythonにはisortというimport文のフォーマッターが存在する。
機能概要としては、import文を以下のセクション順にソートしてくれる。
また、各セクション内のimport文の並び順はアルファベット順にソートしてくれる。
公式ドキュメントより引用
isort parses specified files for global level import lines (imports outside of try / except blocks, functions, etc..) and puts them all at the top of the file grouped together by the type of import:
- Future
- Python Standard Library
- Third Party
- Current Python Project
- Explicitly Local (. before import, as in: from . import x)
- Custom Separate Sections (Defined by forced_separate list in configuration file)
- Custom Sections (Defined by sections list in configuration file)
Inside of each section the imports are sorted alphabetically. isort automatically removes duplicate python imports, and wraps long from imports to the specified line length (defaults to 79).
この記事ではisortの基本的な使い方について確認していく。
その前に
そもそも、Pythonの各種フォーマッター(black、yapf、autopep8)とは別にimport文のソート専用のライブラリが存在することに違和感を持った。
※ 例えばJavaではフォーマッターがimport文のソート機能も提供しているので、import文のソートだけ別のフォーマッターが必要ということはない。
そこで、Pythonの各種フォーマッター(black、yapf、autopep8)はimport文のソート機能を提供していないのか検証してみることにした。
PEP8に記載されているimport文のルール
各種フォーマッターの検証に移る前に、Pythonのフォーマットルールの原則はPEP8なので、まずは、import文のルールはPEP8に明文化されているのか?ということから確認する。
isortのソートルールと重なる部分に関して、PEP8における記載は以下
★記載されていること
- import文は以下の順番でグループ化するべき
- 1.標準ライブラリ
- 2.サードパーティに関連するもの
- 3.ローカルな アプリケーション/ライブラリ に特有のもの
- 上のグループそれぞれの間には、1行空白を置くべき。
★記載されていないこと
- import文の並び順はアルファベット順であるべき
PEP8(日本語訳)より引用
import文 は次の順番でグループ化すべきです:
- 標準ライブラリ
- サードパーティに関連するもの
- ローカルな アプリケーション/ライブラリ に特有のもの
上のグループそれぞれの間には、1行空白を置くべきです。
従って、import文を
のセクション順に並べるということに関しては、PEP8に明文化されている。
各種フォーマッターにおける検証
isortの公式ドキュメントの以下のサンプルをそれぞれのフォーマッターでソートできるか実験していく。
from my_lib import Object 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("Hey") print("yo")
isortを使うと以下のようにソートされる。
from __future__ import absolute_import import os import sys from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14, lib15) from my_lib import Object, Object2, Object3 print("Hey") print("yo")
black
・実行コマンド
$ black sample.py
・結果
一行が長いimport文の改行は行われたが、import文のソートは行われていない。
yapf
・実行コマンド
yapf -i -vv sample.py
・結果
フォーマット箇所0
autopep8
・実行コマンド
autopep8 -i -a -a -v sample.py
・結果
フォーマット箇所0
検証結果
black、yapf、autopep8はimport文のソート機能は提供していない。
従って、やはりimport文のsortにはisortが必要ということになる。(2020/4/28時点)
尚、blackには以下のissueが上っていたので、blackでもsort機能を提供してほしいという要望はあるようである。
github.com
isortのコマンドラインからの使い方
前置きが長くなったが、isortのコマンドラインからの使い方は以下
・インストール方法
$ pip install isort
・実行方法(ファイル単位)
$ isort target_file.py
・実行方法(ディレクトリ配下全て)
$ isort -rc target_dir
・実行例(フォーマットが行われた場合)
$ isort sample.py Fixing /path/to/dir/sample.py $
・実行例(フォーマットが必要な箇所が存在しなかった場合)
$ isort sample.py $
・フォーマット内容
例えば以下のようにフォーマットされる。(右がフォーマット後)