nikkie-ftnextの日記

イベントレポートや読書メモを発信

Python開発環境共有、今の私はtaskipyで一連のコマンドをつないでいます

はじめに

みんなすげーPython開発環境持ってていいなア!! じゃあ、開発環境バトルしようぜ! Python開発環境バトル!! nikkieです。

最近の開発環境の共有です。
先日素振りしたtaskipyを実戦投入し始めています。
個人的にイチ推しのポイントを共有していきます。

あくまで執筆時点の暫定解です。また、もっといいやり方やオススメのやり方あったらぜひぜひ教えてください〜

目次

Python開発環境にまつわる私のプチお悩み:いろんなコマンドを流す必要があるよね

Python自体は環境構築できていて、Pythonで開発を進めていく中での悩みです。
見た目が整った(さらに、将来の開発者に意図を伝える1Pythonを書いていくために、開発を助けてくれるいろいろなライブラリを使いますよね。
例えば

  • フォーマットはblack
    • import順だけisortで整える
  • flake8で静的解析
  • mypyで型チェック

といった具合です。
これって、一連のコマンドを流すことになるわけですが、

$ black -l 79 src
$ isort --profile black -l 79 src
$ flake8 src
$ mypy src

人が覚えて実行しようとすると学習コストは大きいですし、ヌケモレも発生します。
「もうちょっといいやり方あるんじゃないかな〜」と感じていました。

taskipyを使った解決案

taskipyPython向けのタスクランナーです。

taskipyにはフックという仕組みがあります(Pre Task HookPost Task Hook)。

  • awesomeタスクの前に実行したいタスクはpre_awesome
  • 後に実行したいタスクはpost_awesome

これを使って、テストの前にフォーマット、テストの後に静的解析とまとめられます

[tool.taskipy.tasks]
test = "pytest"
pre_test = "task format"
post_test = "task check"

フォーマットや静的解析のタスクの中は && を使って、タスクを組合せられます2

現在のpyproject.toml

ばーん!

[tool.taskipy.tasks]
pre_test = "task format"
test = "pytest"
post_test = "task check"
format = "task format_autoflake && task format_pyupgrade && task format_black && task format_isort"
format_autoflake = "autoflake --in-place --remove-all-unused-imports $(find awesome_lib tests -name '*.py') setup.py"
format_pyupgrade = "pyupgrade $(find awesome_lib tests -name '*.py') setup.py"
format_black = "black -l 79 awesome_lib tests setup.py"
format_isort = "isort --profile black -l 79 awesome_lib tests setup.py"
check = "task check_flake8 && task check_mypy"
check_flake8 = "flake8 awesome_lib tests"
check_mypy = "mypy awesome_lib tests"

(追記 2023/06/13)
pyproject.tomlではツールの引数も指定できると認識しているので、こちらが最終版ではなく、pyproject.tomlを使いこなしてよりよくできる伸び代を認識しています。
(追記終わり)

pyproject.tomlに上記のように書いたら3、あとはtask testを走らせるだけでOK!
コマンドはわずか9文字です、簡単!

設定しているライブラリについて紐解いていきます。

taskipyでまとめたライブラリたち

フォーマッタ

4つをまとめて、テストの前に流しています。

autoflake

使っていないimportの削除を目的に使っています。

  • --in-place:ファイルを書き換える
  • --remove-all-unused-imports:標準ライブラリ以外の未使用のimportも削除する

findコマンドを使っているのは、ディレクトリのパスを渡せないようだからで、.pyファイルのパスを列挙して渡しています。

pyupgrade

Pythonの古い書き方を新しい書き方に変えてくれるライブラリです。
今風なPythonを書いていきたいので使っています。

autoflake同様ディレクトリのパスを渡せないようなので、findコマンドでパスを列挙して渡しています。

black

かなり市民権を得ている感のあるフォーマッタblack
カスタマイズできないのが利点という認識です。
議論の余地がないフォーマッタという点を私は気に入っています。
black「俺が、ルールだ!」

isort

import順をソートしてくれるライブラリ。
ここはblackの手の届かないところですし、PEP 8に書かれた順番4に人が頑張るのはツラいのでお願いしています。

テストランナー

pytest

標準ライブラリのunittestを使うこともありますが、最近はpytestを試すようにしています。

テスト実行順がランダムになるpytest-randomlyと合わせて使っています。

静的解析ツールたち

2つをまとめて、テストの後に流しています。

flake8

こちらも結構使っている人は多いのではないかという静的解析ツール。

最近はRuffというのが出てきているんですよね(Rustだから速いと聞きます)。

mypy

将来の開発者に意図を伝えるPythonに書かせないのが型ヒント。
そのチェックに型チェッカの出番です。

mypyを流すようにすると、「この書き方は型チェッカ的にNGなのか〜」など分かって興味深いです。
小さくハマりつつも怒られない型ヒントの書き方をちょっとずつ知っていく感じです。

終わりに

開発を助けてくれる各種ライブラリのコマンドをtaskipyでつなぐ開発環境を共有しました。
taskipyのフックやタスクの合成でtask testにまとまります。
taskipyはレゴブロックのような小さなタスクを定義でき、それらを組合せて複雑なタスクを実装できる点が私には非常に馴染みます。

短いコマンドにまとまるという点では過去にpysenも見かけましたし、

ぽえぽえもよさそうだな〜と思います。

私の立場としては、どのような技術選定にも良し悪しがあると思っています。
私にはたまたまtaskipyが馴染みましたが、大きい主語で「Python使いはみんなtaskipyを使うべき!」とまで言う気はさらさらありません。
好みは人それぞれですし、私がまだ知らないツールもたくさんあると思います。
なので、この記事を読んだ方のオススメの開発環境も教えてほしいなア!

P.S. 6/15(木)のみんなのPython勉強会でLTします

6月は環境月間らしく、stapyもPython開発環境にフォーカスします。

この記事で取り上げたtaskipyを使った開発環境の例についてLTします。
よろしければ〜


  1. ロバストPython』を念頭に置いています。
  2. https://github.com/taskipy/taskipy/tree/1.11.0#grouping-subtasks-together
  3. 実際のpyproject.tomlの例:https://github.com/ftnext/the-solitary-castle-in-the-mirror-cli/blob/a91d99167760af2213eda0f4867b7f63b97aad66/pyproject.toml#L23-L34
  4. 標準ライブラリ、サードパーティライブラリ、ローカルライブラリで分け、それぞれアルファベット順(さらに、importが先でfrom importが後)という理解です。https://peps.python.org/pep-0008/#imports