HomebrewでPythonをインストールし、pyenvとvenvを使用する方法（Mac M1）

# 概要
* Mac M1にて、HomebrewでPythonをインストールしたので、表示されたエラーメッセージなども含めてその方法を記しておく。

## 環境・前提
* Mac
    * 機種ID：MacBookPro18,3
    * macOS：Monterey
    * チップ：Apple M1 Pro
    * メモリ：16GB

* Pythonをインストールする方法は以下の3通りがあるが、今回はHomebrewを利用したインストールとする。Homebrewとは、ソフトウェアの導入をシンプルに行うことができるパッケージ管理システム。
    * Homebrew版Python環境（pipでパッケージ管理が可能）
    * 公式版Python環境（pipによるパッケージ管理が可能・Windows版は推奨）
    * AnacondaやMiniconda（condaによるパッケージ管理・pipと併用できない）

* 元々、Python勉強用の講座でanaconda3を導入していたが、pipで管理したいことから、anacondaディレクトリを削除してから実施することとした。

* 複数バージョンのPythonを利用していくことを考え、pyenvというソフトウェアもインストールする。pyenvとは、Pythonのバージョン管理を行うソフトウェア。

* 仮想環境ごとにpipでパッケージ管理して作業することも考え、venvを使用してみることとする。venvとは、Python の仮想実行環境を作成するための標準モジュール。
    * Python3.3以降では「venv」が同梱されている。それ以前は、サードパーティ製virtualenvが使われることが多かったらしいです。

# Homebrewインストール手順
* 公式サイトの[Homebrew](https://brew.sh/index_ja)の指示に従ってインストール

# Pythonインストール手順
* ターミナルで以下コマンドを実行する。

```terminal
brew install python3
```

* `python3`と実行したところ、python入力画面にならず、`zsh: command not found: brew`」と表示されてエラーとなったが、以下サイトを参考に再起動してもう一度実施したら解決。
    * [【M1】MacにHomebrewがインストールできない「zsh: command not found: brew」](https://qiita.com/___fff_/items/17655df4e80ebadd8fc3)
    * 手順は以下の通り。

> ファインダーの検索窓で 「ターミナル」 と検索
出てきたターミナルを右クリックして、 「情報を見る」 をクリック
「Rosseta使用して開く」 （またはRosseta2） 左横のチェックボックスにチェックを入れる
ターミナルを再起動

* 上記実施後、`python3`と打てばpython入力画面になること確認。
    
# pyenvのインストール
* pyenvは、複数のバージョンのPythonを併用したい場合に便利。
    * ソースのgithubはこちら：[pyenv](https://github.com/pyenv/pyenv)
* `brew install pyenv`でインストール実施したところ、以下エラーが表示された。

```terminal
error: Not a valid ref: refs/remotes/origin/master
```

*  [homebrewのインストールで error: Not a valid ref: refs/remotes/origin/master が出た時の対処法](https://hiropon-drg.hatenablog.com/entry/2021/02/28/000256)　を参考に以下コマンドを実行。
    *  ` rm -fr $(brew --repo homebrew/core)`
    * `brew tap homebrew/core`

* `brew -v`と打てば、`Homebrew 3.6.5-6-gf30f68b`が表示されること確認。

* PATHを通すため、以下を順番に実行する
 
```
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
```

* 最後に`source ~/.bashrc`でbashに反映させる。
    * zshrcを利用する場合は、bashrcの部分を書き換えてください

* `which pyenv`と入力すると以下が表示された。

```
pyenv () {
local command
command="${1:-}"
if [ "$#" -gt 0 ]
then
shift
fi
case "$command" in
(rehash | shell) eval "$(pyenv "sh-$command" "$@")" ;;
(*) command pyenv "$command" "$@" ;;
esac
}
```

* 翌日に対応しようと思って翌日PCを立ち上げて`which pyenv`をすると、無事に出てきた。再起動の問題か。
```
/usr/local/bin/pyenv
```

# バージョンを指定したPythonのインストール
* `pyenv install 3.8.7`と`pyenv install 3.9.9`を実施
* `pyenv versions`と入力すると以下確認できる

```
  system
  3.8.7
* 3.9.9 (set by /Users/xxxxxxx/.pyenv/version)
```

* なお、`python -V`と入力しても`zsh: command not found: python`と表示されてしまったので、[pythonコマンドが使えない 〜zsh: command not found: pythonの解消〜](https://zenn.dev/otohbk_ky/articles/b9b7d26255db78)を参考に`vi ~/.zshrc`で以下を実施したところ、`python -V`でも正常に表示されるようになった。

```
alias python='python3'
alias pip='pip3'
```

* ただし、これはエイリアスでの対応であって、抜本的な解決ではない。翌日また対応策を調べよう。
↓
* homebrewの保存先をviを利用して以下に変更
```
/opt/homebrew/bin/brew
```

* brewをアップグレードする
```terminal
brew update
brew upgrade
```

* brew upgrade後、以下エラーメッセージが表示された

```
Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:
    arch -arm64 brew install ...
To install under x86_64, install Homebrew into /usr/local.
```

* やっぱりM1チップはRossettaが関係してくるっぽい。「Rosseta使用して開く」 についてはチェックを外して、再度ターミナル開いて実施したらエラーメッセージは表示されなく無くなった。

* `python3`の場所を以下で確認。

```terminal
/usr/bin/python3
```

* あれ、Homebrew以下にない模様。

* もう一度、`brew install python3`を実施、bashでPATHを更新し、`which python3`を実行したところ、

```terminal
/opt/homebrew/bin/python3
```

となった。homebrew以下に置けたみたい。

which brewでもちろん以下を確認。

```terminal
/opt/homebrew/bin/brew
```

* `python -V`コマンドも実行できていること確認。

# グローバルとローカルの指定
* 使用したいPythonのバージョンが3.9.9の場合、以下コマンドを実行する。これにより、どこのディレクトリでも3.9.9が呼び出されるようになる。

```terminal
pyenv global 3.9.9
```

* 特定のディレクトリ下でのみ（=ローカルで）、例えば3.8.7を使用したい場合は、cdで対象ディレクトリに移動後、以下localオプションを実行する。

```terminal
pyenv local 3.8.7
```

* globalとlocalのバージョンは以下で確認可能
    *  `pyenv global`
    *  `pyenv local`
    *  local設定のほうがglobalより優先される

# globalが反映されない場合の対処法
* globalでバージョン指定したものが、`python --version`で反映されないことがありました。その時は、[[Dev] pyenvを使って Python のバージョン変更ができないとき](https://sideblue.net/archives/9714)のサイトを参考に、以下コマンドを追記したら直りました。また、そもそも通したPATHが合っているかどうかは、`pyenv init`で`# the following to`以降のパスを確認してから実行した方が良いと思います。

```terminal
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi
```

# 仮想環境（venv）の使用方法
* venvにより、実際に使っているpackage listをvenv下にインストールすることができる。これにより、実際に使っているpackageの不具合などを検証できたり、誰かと同じpackageの状態で作業できたりすることができることが利点。
* requirements.txtに一覧さえ作っておけば、誰でもすぐに同じpackage listの環境が作れるのが良い。

* 仮想環境作成
    * `python3 -m venv env`
    * もしくは`python -m venv env`
    * envは仮想環境名。実行後、envディレクトリが自動生成される
* 仮想環境起動（有効化・アクティベート）
    * `source env/bin/activate`
    * PATHの内容をbinに置き換えることでが、Python系コマンドは仮想環境内で動作するようになる
* 　`(env) xxxx@xxxxxxxx ~ %` と表示されれば、起動できている

* ライブラリのインストール
    * `pip install -r requirements.txt`
    * requirementがない場合はインストールされない
    * `pip freeze > requirements.txt`コマンドで、自動生成も可能
* 無効化する場合は`deactivate`を実行する