導入
Pythonは導入だけで言えば非常に簡単な言語です。公式のインストーラを入れるもよし、brew install python
などするもよしでしょう。パッケージを入れたくなったらpip install ...
だけで済みますし、そしてコンパイルの必要もありません。
が、いざチームで開発したり、リポジトリをcloneすると吸収しきれないOSの違い・Pythonバージョンの差異・依存パッケージのバージョンの差異などなどで困らされることも少なくありません。
というわけで私は書き捨てのコードを書く以上の目的で使いづらいという印象が拭えずにいたのですが、いつの間にかすごいツールが現れてPythonの開発環境は以前より格段に整えやすくなっていました。
想定読者
- MacOSのプリインストールPythonや、Pythonの仮想環境を大量に作りすぎて困ったことがある人1
- 複数のプロジェクトでPythonを使う時Pythonやパッケージのバージョンで困ったことがある人
-
venv
,poetry
,pyenv
,Anaconda
などなどに遭遇して頭がパンクしたことがある人 - 久々にPython触ってツールを選択しようとしている人
- Curious Cat
TL;DR
- ryeはPython周りで面倒なことを全部やってくれます
- Pythonのバージョン管理
- Python仮想環境の生成
- 依存ライブラリの管理
- Ruffは高速なPython用Linter/Formatter
rye
ryeとは
rye とは、Flaskなどの開発者として知られるArmin Ronacher氏が開発したone-stop-shop
ツールです。
これまでPythonでは複数のツールを組み合わせて管理していた以下の管理をまとめてやってくれます(これがone-stop-shop
と呼ばれている理由です)
- Pythonのインストール管理
-
pyproject.toml
の管理 - 依存のインストール/アンインストール
- 仮想環境の管理
プロジェクトが公開されるに至った経緯は
Should rye Exist?に熱く記されています。暇な時に読んでみてください。
インストール
shが動く環境では
curl -sSf https://rye-up.com/get | bash
Windowsにはバイナリが用意されています。
また、homebrewからもインストール出来ました。
brew install rye
基本的な操作
プロジェクトの新規作成
新規のプロジェクトを作る場合はinit
コマンドを呼び出します。
以下、プロジェクト名はhello_rye_ruff
で進めていきます。
~ % rye init hello_rye_ruff
pyproject.toml
などなど、↓のようなフォルダが出来上がります。
hello_rye_ruff % git ls-files --exclude-standard -o | tree --fromfile
.
├── .gitignore
├── .python-version
├── README.md
├── pyproject.toml
└── src
└── hello_rye_ruff
└── __init__.py
requirements.txt
が既存のプロジェクトを取り込みたい場合、-r
オプションで指定してあげると、pyproject.toml
に取り込んでくれます。他にもオプションが数多くあります。
rye init -r requirements.txt
仮想環境の作成
init
が済んだら、次はsync
を実行しましょう。
プロジェクトフォルダ内に.venv
が生成され、仮想環境が生成されます。
作成した仮想環境にはrye shell
で入ることができます。
hello_rye_ruff % rye shell
Spawning virtualenv shell from /<path>/hello_rye_ruff/.venv
Leave shell with 'exit'
カレントディレクトリがpyproject.toml
を含むディレクトリの配下でない場合は仮想環境に入れません。
~ % rye shell
error: did not find pyproject.toml
依存パッケージの管理
プロジェクトで使用したい依存パッケージはpyproject.toml
で管理します。
ryeでは、pyproject.toml
を下のコマンドで操作することができます。
rye add # パッケージの追加
rye remove # パッケージの削除
rye sync
することで、依存を解決したrequirements.lock
・requirements-dev.lock
を自動生成します。
Pythonバージョンの固定
もしプロジェクトでPythonのバージョンを固定したい場合はrye pin
を使います。
デフォルトの場合、OSプリインストールのPythonになっている場合があります(特にMacOSでは注意が必要です)。これを回避したい場合、pinしておく方が良いでしょう。
rye pin 3.12
のようにバージョンを引数に設定すると、バージョンファイルが書き換えられます。
3.12.0
rye sync
をした後に仮想環境に入るとpythonのバージョンは指定したバージョンになっています。
hello_rye_ruff % rye shell
Spawning virtualenv shell from /<path>/hello_rye_ruff/.venv
Leave shell with 'exit'
hello_rye_ruff % python --version
Python 3.12.0
Ruff
Ruffとは
Ruffは、Rust製Linter/Formatterです。
LintとFormatの両方を持っており、超高速を謳っています。
GitHubのreadmeより。
LinterにFlake8
、FormatterにBlack
を、といった構成などは少なからず見てきましたが、こちらもRuffで将来的にまとめられそうです。
GitHub Starsは既に21kStarsに達しています。
インストール
RuffはCLI/各種エディターのプラグイン/GitHub Actionsに対応しています。
が、ここでは開発環境向けにCLI/VSCode拡張に絞って紹介します。
CLI インストール
homebrew
、pacman
などからインストールが可能です。
brew install ruff
pip
からもインストール可能なので、当然rye
経由でもインストールできます。
rye install ruff
VSCode 拡張機能
RuffにはVSCode用の拡張機能が用意されています。
これを入れるだけです。簡単ですね。
Lintルールの設定
設定はpyproject.toml
もしくはruff.toml
に記載していきます。
デフォルトでも設定値があるので、あまり多くを設定する必要はないかもしれません。
全ては記述しきれないので頻繁に使うものだけ下に紹介します。
# Lint/Formatter非依存のルール
[tool.ruff]
# 除外したいファイル
# excludeを設定するとデフォルトで設定されている.venv配下などの設定が上書きされるため要注意
extend-exclude = ["src/something.py"]
# 行文字数
line-length = 88
# インデント幅
indent-width = 4
# Linterのルール
[tool.ruff.lint]
# Lintルール
# https://docs.astral.sh/ruff/rules/ に記載されているルールのうち、Codeが前方一致するルールが適用されます
select = ["E", "F", "I", "PLR"]
# 除外するLintルール
# selectで選択したルールから除外したいものを指定できます
ignore = ["PLR2004"]
# auto fixの対象にするルール
fixable = ["ALL"]
# auto fixから除外するルール
# editor.formatOnSaveを使う際に自動でFixされると困るものを指定できます
unfixable = ["F401"]
# Formatterのルール
[tool.ruff.format]
# 文字列をダブルクォートに統一
quote-style = "double"
# インデントをタブ文字(\t)からスペースに変換
indent-style = "space"
Ruffは豊富な設定とpycodestyle
/pyflakes
/isort
など700以上のルールに対応しています。
設定する際はSettingsとRulesを見るようにしましょう。
VSCodeの設定
後は保存時にRuffを実行するようにすれば、設定された内容でLint/Formatが自動で実行されます。
{
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
}
}
あとがき
以前は開発環境整える作業でカロリーを消費しがちだったPython開発ですが、ryeとRuffの登場によって非常に快適な構築ができました。同じような経験をしてきた人が少しでも楽な開発環境を組む一助になれば幸いです。
-
筆者がこの記事を書いた理由は先日MacOSのプリインストールPythonに痛い目に遭わされたからです。 ↩