Python開発環境の整え方(Mac)

MacでPythonの開発環境を整えるとき、私はこうしてますっていう話です。
何百番煎じかわかりませんが、自分の備忘録も兼ねて。

Macのpython、いまだにデフォルトのPythonは2です。シンジラレナイ:person_frowning:[^1]
かと言って、デフォルトのPythonを弄ると不具合が出るかもしれないと思ってしまうので、pyenvに頼ります。[^2]
グローバルなPythonにバシバシパッケージ追加するのもよくないですしね。

パッケージ管理ツールはpoetryを使います。
昔はpipenv使ってましたが、pipenvの更新が1年以上停止していた時期があった事もあって、私はpoetryに乗り換えました。
（pipenvの方が一括でvenvまで作ってくれて楽だった記憶もありますが、もはやpyenv+poetryに慣れてしまった）

なお、Homebrewは入っている前提で書きます。

# pyenvの導入
[pyenv](https://github.com/pyenv/pyenv)はPythonのバージョン管理ツールです。


インストールは公式に記載されている[git cloneを使った手順](https://github.com/pyenv/pyenv#basic-github-checkout)で行います。
過去、homebrewで入れたときに追従が遅かったので。
以下に公式の手順を抜粋しますが、基本的には公式の最新情報を参照です。

```zsh
# pyenvをクローン
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
# パスを通す設定など
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zprofile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zprofile
echo 'eval "$(pyenv init --path)"' >> ~/.zprofile
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
# 設定の反映
source ~/.zprofile
source ~/.zshrc
```

[この手順](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)はやったか忘れましたが、xcodeは別途導入し、opensslとxzはbrewで入れてました。
以下のように、pyenv installの時に使っているので、もしpyenv installが失敗したら上記手順を実施してみると良いと思います。

```zsh:pyenvインストール時のログ
(略)
python-build: use openssl from homebrew
(略)
python-build: use zlib from xcode sdk
```

ちなみに、導入後のバージョンアップは[git pullするだけ](https://github.com/pyenv/pyenv#upgrading)です。

# poetryの導入
poetryはパッケージの依存関係管理ツールです。

pyenvと同じく[インストール手順](https://python-poetry.org/docs/master/#installation)抜粋です。[^3]

```zsh
# インストール
curl -sSL https://install.python-poetry.org | python3 -
# パスを通す設定
echo "PATH=$PATH:$HOME/.local/bin" >> ~/.zshrc
# カレントシェルに設定を反映
source ~/.zshrc
```

[コマンドの補完](https://python-poetry.org/docs/master/#enable-tab-completion-for-bash-fish-or-zsh)をしたい人は、その設定もしましょう。
私は今まで補完を使ったことなかったので、以下を実施しました。

```zsh
# .zfuncディレクトリ作成
mkdir ~/.zfunc
# poetryの補完設定
poetry completions zsh > ~/.zfunc/_poetry
# ~/.zshrcに設定を追加
echo "fpath+=~/.zfunc" >> ~/.zshrc
echo "autoload -Uz compinit && compinit" >> ~/.zshrc
# カレントシェルに設定を反映
source ~/.zshrc
```

ちなみに、導入後のバージョンアップは`poetry self update`を実行するだけです。

# poetryの設定
poetryではプロジェクト単位で仮想環境が準備されます。
仮想環境が準備されるパスはどこなのか、というのは、以下のコマンドを実行して、poetryのconfigを見れば分かります。[^4]

```zsh
poetry config --list | grep path
```

ただ、個人的にはプロジェクト外に仮想環境が出来るのはあまり好ましくないので、プロジェクト直下の`.venv`に仮想環境が用意されるように、以下のコマンドで[設定](https://python-poetry.org/docs/configuration#virtualenvsin-project)を変更しています。

```zsh
poetry config virtualenvs.in-project true
```

もしgit管理のプロジェクトとする場合、`.venv`をpushするとあまりよろしくないので、`.gitignore`に`.venv`を追加することを忘れないようにしましょう。
それをプロジェクト毎にやるのが面倒であれば、poetryのデフォルトパスのままにするのもアリです。

# pyenv+poetryで開発環境を構築
では環境を用意していきましょう。

#### Pythonバージョンの切り替え
まず、プロジェクトのディレクトリに移動し、Pythonのバージョンをpyenvを利用して切り替えます。
(プロジェクトディレクトリとバージョンは適宜読み替えてください）

```zsh
#　プロジェクトディレクトリに移動
cd project_dir
# 事前にPythonバージョン確認
python -V
# ローカルのPythonを変更
pyenv local 3.10.0
# Pythonのバージョンが変わったことを確認
python -V
```

この時、当該バージョンがインストールされていない場合はinstallコマンドを実行します。

```zsh
# インストール可能なpythonのバージョンを調べる
pyenv install --list | grep '^  3'
# インストール
pyenv install 3.10.2
# インストールされたかチェック
pyenv versions
```

#### poetryによる仮想環境の準備
次に、poetryでプロジェクトの初期設定を行います。

```zsh
# プロジェクトの初期設定を実行
poetry init
```

実行すると、pyproject.tomlに記載する内容をインタラクティブに質問されます。
が、後からpyproject.tomlを編集すればいいので、回答は毎回以下にしてます。

```zsh
# パッケージ名
Package name -> <そのままEnter>
# バージョン
Version -> <そのままEnter>
# 説明
Description -> <そのままEnter>
# 作者
Author -> n
# ライセンス
License -> <そのままEnter>
# 互換性のあるPythonバージョン
Compatible Python versions -> <そのままEnter>
# その場でパッケージをインタラクティブに入れるかどうか(後で落ち着いて入れたいのでno)
Would you like to define your main dependencies interactively? -> no
# その場で開発用パッケージをインタラクティブに入れるかどうか(後で落ち着いて入れたいのでno)
Would you like to define your development dependencies interactively? -> no
# 出力内容の最終確認(yesにしないとpyproject.tomlが作られない)
Do you confirm generation? -> yes
```

この段階ではまだ仮想環境は出来ていません。
管理対象のパッケージを追加するタイミングで、仮想環境が準備されていなければ作るようです。[^5]
パッケージ追加は以下のコマンドで行います。

```zsh
# パッケージ追加
poetry add <パッケージ名>
# 開発用パッケージ追加(blackとかpytestとか開発やテストの時だけ使うものはこちらで追加)
poetry add -D <パッケージ名>
```

パッケージを追加しないプロジェクトはあまりないと思いますが、もしパッケージ追加なしで仮想環境を準備したい場合は`poetry install`を実行しましょう。

#### 開発環境の利用
poetryでは、runコマンドを利用してpythonのコードを実行するか、shellコマンドで仮想環境にログインするかの二通りがあります。
個人的には、毎回`poetry run`で色々なファイルを実行するのは面倒なので、`poetry shell`でログインしてしまって直接コードを実行してしまっています。

```zsh
# シェルを起動。プロンプトの先頭が(.venv) になる。
poetry shell
# pythonを実行
python a.py
```

ここまでこれば、とりあえずMacの環境は汚さずにPythonでの開発ができるようになっているはずです。
お疲れ様でした。

[^1]: python3って打てばいいんですけど、なんか違う。
[^2]: CentOSのPythonをいじった結果、yumが動かなくなったというトラウマを抱えて生きてます。
[^3]: 昔の方式と若干変わってました。
[^4]: ~/Library/Caches/pypoetry/virtualenvsとかになっていると思います。いちいちそこまで行って不要な環境を消したりするのが面倒。
[^5]: パッケージのインストールに失敗しても作られました。