MacのPython開発環境を見直してみたら色々大変だったので備忘録メモ

Pythonは非常に優れた汎用プログラミング言語です。OSを問わず機械学習の分野は言うに及ばず、クラウドやWebプログラミングの分野にまで利用されています。また仮想環境管理ツールを導入すれば、複数のバージョンを使い分けたい場合に仮想環境を構築して管理出来ます。筆者は学生時代から愛用しているAnaconda[^conda]の`Conda Env`を使ってきました。ところがここで困った問題が有ります。Macユーザーの方でHomebrewをお使いの方は御存知だと思いますが、<font color='RED'>Hombrew[^brew]とAnacondaの相性は最悪</font>です。また、Conda Envは仮想環境の共有やリモート管理(Gitなどで管理)が考慮されておらずとても不便です。本記事ではそんなPythonの開発環境を見直してみようという試みについてまとめました。

# Anaconda @ Macの問題
1. Homebrewとの相性問題
2. 仮想環境情報の共有やリモート管理が難しい

## Homebrewとの相性問題
Homebrewの状態が見える`brew doctor`コマンドを実行すると以下の様な状態に。。。

<details><summary>brew doctorの警告文</summary><div>

```bash
$ brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: "config" scripts exist outside your system or Homebrew directories.
`./configure` scripts often look for *-config scripts to determine if
software packages are installed, and which additional flags to use when
compiling and linking.

Having additional scripts in your path can confuse software installed via
Homebrew if the config script overrides a system or Homebrew-provided
script of the same name. We found the following "config" scripts:
  /Users/user/anaconda3/bin/icu-config
  /Users/user/anaconda3/bin/krb5-config
  /Users/user/anaconda3/bin/freetype-config
  /Users/user/anaconda3/bin/xslt-config
  /Users/user/anaconda3/bin/libpng16-config
  /Users/user/anaconda3/bin/python3.7-config
  /Users/user/anaconda3/bin/libpng-config
  /Users/user/anaconda3/bin/xml2-config
  /Users/user/anaconda3/bin/python3.7m-config
  /Users/user/anaconda3/bin/python3-config
  /Users/user/anaconda3/bin/curl-config
  /Users/user/anaconda3/bin/ncursesw6-config
  /Users/user/anaconda3/bin/pcre-config
```
</div></details>

## 仮想環境の共有やリモート管理が難しい
Anacondaでは仮想環境(インストールしたパッケージなどの情報)を共有したり、リモートで管理することが困難な事情が有ります。理由は以下の3点です。

1. `conda create`コマンドで作成した仮想環境はディレクトリ単位で管理される為、その中身を全てバックアップ又は共有しなければならない。(`conda info -e`でリスト表示されるディレトリ群)
2. `conda install`だけで全てのパッケージをインストール出来る訳では無いため、結局`pip`など他のパッケージマネージャーの力を借りざるを得ず、パッケージ一覧の共有などを煩雑にさせる要因となる。
3. インストール済パッケージ一覧を`pip freeze`コマンドで取り出せるが、この方法でバックアップ・共有する方法は煩雑である。

# 新たなパッケージマネージャーを模索
新たなパッケージマネージャーの選定を行うこととします。以前職場でPythonを駆使している方や同期の友人にどのパッケージマネージャーを使用しているか聞いてみましたが、好みが分かれる為、結論が出ませんでした。。。まずPythonのパッケージマネージャーに要求する要件をまとめたいと思います。

1. 環境構築が簡単
2. 仮想環境(複数バージョンのPythonインタープリタ)を容易に構築出来る
3. 複数バージョンのパッケージを管理可能
4. パッケージ情報(requirements情報)を簡単に共有出来る
5. 仮想環境情報をGitなどで管理可能
6. AnacondaというPythonのディストリビューションの便利さは捨てたくない(Anaconda仮想環境を作れる)

本記事ではConda Env環境を一旦削除し、新しいパッケージマネージャーのインストールを実施した上で、再度Anacondaの仮想環境を構築することを目標とします。ネットで情報収集をしていた所、以下の様な比較表に出会いました。

## [A thoroughly biased feature table](https://github.com/David-OConnor/pyflow#a-thoroughly-biased-feature-table)

| Name | Pip + venv | Pipenv | Poetry | pyenv | pythonloc | Conda | Pyflow |
|:--|:--|:--|:--|:--|:--|:--|:--|
| Manages dependencies | ✓ | ✓ | ✓ |  |  | ✓ | ✓ |
| Resolves/locks deps |  | ✓ | ✓ |  |  | ✓ | ✓ |
| Manages Python installations |  |  |  | ✓ |  | ✓ | ✓ |
| Py-environment-agnostic |  |  |  | ✓ |  | ✓ | ✓ |
| Included with Python | ✓ |  |  |  |  |  |  |
| Stores deps with project |  |  | ✓ |  | ✓ |  | ✓ |
| Requires changing session state | ✓ |  |  | ✓ |  |  |  |
| Clean build/publish flow |  |  | ✓ |  |  |  | ✓ |
| Supports old Python versions | with virtualenv | ✓ | ✓ | ✓ | ✓ | ✓ |  |
| Isolated envs for scripts |  |  |  |  |  |  | ✓ |
| Runs project fns from CLI |  | ✓ | ✓ |  |  |  | ✓ |

この表は[Pyflow](https://github.com/David-OConnor/pyflow)という最近リリースされたパッケージマネージャーの公式GitHubで公開されているREADMEに掲載されている表です。この表からも分かる通り、Pyflowでは上述の欲しい機能が全て網羅されている様に見えます。Pyflow最強説？に則りまずはPyflowのインストールをやってみることにします。しかし、結論を先に述べるとPyflowとMacの相性は2020/4現在悪いと言わざるを得ません(後述)。故に`Pipenv + pyenv`のコンビをセットアップすることにしました。

# Anacondaのアンインストール
Anacondaはしばしば<font color='RED'>インストールは簡単だが、アンインストールでトラブル</font>と言われます。今回はAnacondaを安全に完全にアンインストールする方法を紹介します。以下の方法は[公式ドキュメント](https://docs.anaconda.com/anaconda/install/uninstall/)に従います。

* 検証環境: macOS Mojave 10.14.6

## condaコマンドのPathを確認
まず初めに`conda`コマンドのPathを確認します。

```bash
$ which conda
/Users/user/anaconda3/bin/conda
```

ドキュメントでは、anaconda3ディレクトリを削除してからconda-cleanをインストールし、実行と行程が説明されていますが、condaコマンドはanaconda3ディレクトリ配下にある為、conda-cleanを先に実行します。

## conda-cleanをインストール
Anaconda環境を完全に削除する為にconda-cleanをインストールします。

```bash
conda install anaconda-clean
```

## conda-cleanの実行
インストール後、今回は完全に削除する為、以下のコマンドを実行します。`Backup directory`が作成されますが後程削除します。

```bash
anaconda-clean --yes
```

削除する項目を選択しながら実行したい場合は以下の`--yes`オプションを外します。

## anaconda3ディレクトリの削除
以下のコマンドを実行し、Anaconda関連で保存されているファイルを完全に削除します。

```bash
rm -rf ~/anaconda3
```

削除後、`Backup directory`を削除します。

## dotfile内のAnacondaに関連する設定の削除
`.bashrc`又は`.bash_profile`内の以下の内容を削除します。

```bash
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/user/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/Users/user/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/Users/user/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/Users/user/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<
```

# PyflowとMacは相性が悪いという結論に至った検証

<details><summary>検証内容</summary><div>

# Pyflowのインストール
Pyflowは他のPython用パッケージマネージャとは異なり昨今注目されている[Rust](https://www.rust-lang.org/ja/)で開発されています。よって場合によっては`Rust`の知識を必要とするトラブルが発生する場合も有る様です。故にユーザーによってはRustと関わりたく無いと思われるかもしれませんが、筆者は`Rust`と仲良くなりたいと思っていた為、このまま前進有るのみです。

## Rustのインストール
MacでPyflowをインストールする場合、`Rust`をインストールして`cargo install`コマンド(Rustのパッケージマネージャー)でインストールする方法が推奨されています。Linuxの場合は`pip install`コマンドからインストール出来ますが、Macでは動作しません。(公式ドキュメントより)

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

途中オプション選択を求められますが、そのままインストールします。

```bash
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1
```

Pyflow 0.2.5がインストールされました。

## cargoでPyflowのインストール
ターミナルに再ログインして以下のコマンドを実行します。

```bash
cargo install pyflow
```

# Pyflowを実際に使ってみる
テストプロジェクトを作り、実際にPyflowを実行します。

```bash
mkdir test_python
cd test_python
```
Pyflowの初期化コマンドを実行します。

```bash
pyflow init
```

```bash:実行結果
Created `pyproject.toml`
🐍 Setting up Python...
```

## Pythonのインタープリタを起動してみる
Pythonのインタープリタを起動してみます。システムのデフォルトバージョン(ここでは2.7.16)が起動しました。AnacondaはインストールするとPathを書き換えてしまい、それがトラブルの原因となる場合が有りましたが、Pyflowにはそういった<font color='RED'>破壊的な変更</font>を起こす仕様は無い様です。

```bash
$ python
Python 2.7.16 (default, Jan 27 2020, 04:46:15) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

最新版のPythonのインタープリタを起動するには以下のコマンドを実行します。Python3のインタープリタが起動します。

```bash
$ pyflow python
Python 3.7.7 (default, Mar 10 2020, 15:43:03) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

それではPython3.8のインタープリタを起動してみます。通常は以下のコマンドで実行出来ます。

```bash
pyflow switch 3.8
```

しかし、以下の様なエラーが出力されました。

```bash
Switched to Python version 3.8
Automatic installation of Python 3.8 on Mac is currently unsupported. If you'd like to use this version of Python, please install it.
```

他のバージョンのPythonでもダメでした。MacではPyflowによるPythonのバージョン切り替えが非対応だということが分かりました。READMEを見る限り一言もそういった言及が無い為、注意が必要です。また、Linuxで検証した友人がAnacondaの環境を構築出来なかったと言っていたので、pyenvの様にPython及びAnacondaの混じった環境を複数作成するという機能は未完成と推察されます。新しい物≠良い物という典型例です。Pyflowは開発されて間も無い為、まだ機能の作り込みが不十分と判断しました。故にBack to square one!!振り出しに戻りました。再度先述の表を参考にパッケージマネージャーの選定を行うこととします。最後にPyflowの今後の発展を祈りつつアンインストールしておきます。

```bash
cargo uninstall pyflow
```

</div></details>

# 結果として: Pipenv + pyenvのコンビが最適と結論
先述の表より、Pyflow以外のツールで所望の仕様を満たす環境を構築する為にはパッケージマネージャーとして[Pipenv](https://github.com/pypa/pipenv)または[Poetry](https://github.com/python-poetry/poetry)を用い、複数のバージョンのPythonインタープリタの管理及びAnacondaの環境構築には[pyenv](https://github.com/pyenv/pyenv)を用いるという方法が良いのではないかと思いました。Poetryはこれまた最近リリースされたばかりである為、資料が少なくトラブル対処に難儀する可能性が有ります。その点Pipenvは歴史が古く、情報も豊富に出てくる為、良い意味で枯れているツールだと判断しました。またHomebrewによるインストールにも対応しています。故に、本記事ではPipenvとpyenvをインストールし、最終的にAnaconda仮想環境を構築するところまでを実施します。


# システムのPythonの扱い
システム上にインストールされているPythonは購入時からOSにインストールされている為、安易にアンインストール出来ません。かといってPython2.7環境のままという現状の環境も不便です。そこでシステム上のPython2.7は残しつつ複数のバージョンのPython(Anacondaを含)を管理出来るツールとしてpyenvをインストールすることとします。これはRubyのrbenvと同様の動作をします。インストール後、Anaconda環境を構築し、デフォルトのPython環境として利用出来る様にします。

## pyenvのインストール(2022/10/18追記)
pyenvのインストールには幾つか方法が有りますが、現状以下のanyenvを利用してインストールする方法が手軽でお勧めです。具体的な使い方も以下のページに詳しく記載されています。

https://github.com/anyenv/anyenv

<details><summary>旧情報</summary><div>

## pyenvのインストール

Pipenvと同様にHomebrewでインストールします。pyenv 1.2.18がインストールされました。

```bash
brew install pyenv
```

.bash_profile又は.bashrcに以下を追加します。(筆者は.bash_profileに追加)

```bash
eval "$(pyenv init -)"
```

```bash
source ~/.bash_profile
```

</div></details>

現時点でインストールされているバージョンを確認します。

```bash
$ pyenv versions
* system (set by /Users/user/.pyenv/version)
```

## Anaconda3のインストール
まず現時点でインストール可能なAnaconda3のバージョンを確認します。

```bash
$ pyenv install --list | grep anaconda3
  anaconda3-2.0.0
  anaconda3-2.0.1
  anaconda3-2.1.0
  anaconda3-2.2.0
  anaconda3-2.3.0
  anaconda3-2.4.0
  anaconda3-2.4.1
  anaconda3-2.5.0
  anaconda3-4.0.0
  anaconda3-4.1.0
  anaconda3-4.1.1
  anaconda3-4.2.0
  anaconda3-4.3.0
  anaconda3-4.3.1
  anaconda3-4.4.0
  anaconda3-5.0.0
  anaconda3-5.0.1
  anaconda3-5.1.0
  anaconda3-5.2.0
  anaconda3-5.3.0
  anaconda3-5.3.1
  anaconda3-2018.12
  anaconda3-2019.03
  anaconda3-2019.07
  anaconda3-2019.10
```

`anaconda3-2019.10`をインストールします。

```bash
pyenv install anaconda3-2019.10
```

再度バージョン一覧を確認します。

```bash
$ pyenv versions
* system (set by /Users/user/.pyenv/version)
  anaconda3-2019.10
```

`anaconda3-2019.10`に切り替えます。

```bash
pyenv global anaconda3-2019.10
```

切替が出来ているか確認します。無事切替が完了しました。

```bash
$ pyenv versions
  system
* anaconda3-2019.10 (set by /Users/user/.pyenv/version)
```

<details><summary>pip listコマンドで確認した結果</summary><div>

Anacondaに収録されているパッケージがインストールされていることが確認出来ました。

```bash
$ pip list
Package                            Version  
---------------------------------- ---------
alabaster                          0.7.12   
anaconda-client                    1.7.2    
anaconda-navigator                 1.9.7    
anaconda-project                   0.8.3    
appnope                            0.1.0    
appscript                          1.0.1    
asn1crypto                         1.0.1    
astroid                            2.3.1    
astropy                            3.2.2    
atomicwrites                       1.3.0    
attrs                              19.2.0   
Babel                              2.7.0    
backcall                           0.1.0    
backports.functools-lru-cache      1.5      
backports.os                       0.1.1    
backports.shutil-get-terminal-size 1.0.0    
backports.tempfile                 1.0      
backports.weakref                  1.0.post1
beautifulsoup4                     4.8.0    
bitarray                           1.0.1    
bkcharts                           0.2      
bleach                             3.1.0    
bokeh                              1.3.4    
boto                               2.49.0   
Bottleneck                         1.2.1    
certifi                            2019.9.11
cffi                               1.12.3   
chardet                            3.0.4    
Click                              7.0      
cloudpickle                        1.2.2    
clyent                             1.2.2    
colorama                           0.4.1    
conda                              4.7.12   
conda-build                        3.18.9   
conda-package-handling             1.6.0    
conda-verify                       3.4.2    
contextlib2                        0.6.0    
cryptography                       2.7      
cycler                             0.10.0   
Cython                             0.29.13  
cytoolz                            0.10.0   
dask                               2.5.2    
decorator                          4.4.0    
defusedxml                         0.6.0    
distributed                        2.5.2    
docutils                           0.15.2   
entrypoints                        0.3      
et-xmlfile                         1.0.1    
fastcache                          1.1.0    
filelock                           3.0.12   
Flask                              1.1.1    
fsspec                             0.5.2    
future                             0.17.1   
gevent                             1.4.0    
glob2                              0.7      
gmpy2                              2.0.8    
greenlet                           0.4.15   
h5py                               2.9.0    
HeapDict                           1.0.1    
html5lib                           1.0.1    
idna                               2.8      
imageio                            2.6.0    
imagesize                          1.1.0    
importlib-metadata                 0.23     
ipykernel                          5.1.2    
ipython                            7.8.0    
ipython-genutils                   0.2.0    
ipywidgets                         7.5.1    
isort                              4.3.21   
itsdangerous                       1.1.0    
jdcal                              1.4.1    
jedi                               0.15.1   
Jinja2                             2.10.3   
joblib                             0.13.2   
json5                              0.8.5    
jsonschema                         3.0.2    
jupyter                            1.0.0    
jupyter-client                     5.3.3    
jupyter-console                    6.0.0    
jupyter-core                       4.5.0    
jupyterlab                         1.1.4    
jupyterlab-server                  1.0.6    
keyring                            18.0.0   
kiwisolver                         1.1.0    
lazy-object-proxy                  1.4.2    
libarchive-c                       2.8      
lief                               0.9.0    
llvmlite                           0.29.0   
locket                             0.2.0    
lxml                               4.4.1    
MarkupSafe                         1.1.1    
matplotlib                         3.1.1    
mccabe                             0.6.1    
mistune                            0.8.4    
mkl-fft                            1.0.14   
mkl-random                         1.1.0    
mkl-service                        2.3.0    
mock                               3.0.5    
more-itertools                     7.2.0    
mpmath                             1.1.0    
msgpack                            0.6.1    
multipledispatch                   0.6.0    
navigator-updater                  0.2.1    
nbconvert                          5.6.0    
nbformat                           4.4.0    
networkx                           2.3      
nltk                               3.4.5    
nose                               1.3.7    
notebook                           6.0.1    
numba                              0.45.1   
numexpr                            2.7.0    
numpy                              1.17.2   
numpydoc                           0.9.1    
olefile                            0.46     
openpyxl                           3.0.0    
packaging                          19.2     
pandas                             0.25.1   
pandocfilters                      1.4.2    
parso                              0.5.1    
partd                              1.0.0    
path.py                            12.0.1   
pathlib2                           2.3.5    
patsy                              0.5.1    
pep8                               1.7.1    
pexpect                            4.7.0    
pickleshare                        0.7.5    
Pillow                             6.2.0    
pip                                19.2.3   
pkginfo                            1.5.0.1  
pluggy                             0.13.0   
ply                                3.11     
prometheus-client                  0.7.1    
prompt-toolkit                     2.0.10   
psutil                             5.6.3    
ptyprocess                         0.6.0    
py                                 1.8.0    
pycodestyle                        2.5.0    
pycosat                            0.6.3    
pycparser                          2.19     
pycrypto                           2.6.1    
pycurl                             7.43.0.3 
pyflakes                           2.1.1    
Pygments                           2.4.2    
pylint                             2.4.2    
pyodbc                             4.0.27   
pyOpenSSL                          19.0.0   
pyparsing                          2.4.2    
pyrsistent                         0.15.4   
PySocks                            1.7.1    
pytest                             5.2.1    
pytest-arraydiff                   0.3      
pytest-astropy                     0.5.0    
pytest-doctestplus                 0.4.0    
pytest-openfiles                   0.4.0    
pytest-remotedata                  0.3.2    
python-dateutil                    2.8.0    
pytz                               2019.3   
PyWavelets                         1.0.3    
PyYAML                             5.1.2    
pyzmq                              18.1.0   
QtAwesome                          0.6.0    
qtconsole                          4.5.5    
QtPy                               1.9.0    
requests                           2.22.0   
rope                               0.14.0   
ruamel-yaml                        0.15.46  
scikit-image                       0.15.0   
scikit-learn                       0.21.3   
scipy                              1.3.1    
seaborn                            0.9.0    
Send2Trash                         1.5.0    
setuptools                         41.4.0   
simplegeneric                      0.8.1    
singledispatch                     3.4.0.3  
six                                1.12.0   
snowballstemmer                    2.0.0    
sortedcollections                  1.1.2    
sortedcontainers                   2.1.0    
soupsieve                          1.9.3    
Sphinx                             2.2.0    
sphinxcontrib-applehelp            1.0.1    
sphinxcontrib-devhelp              1.0.1    
sphinxcontrib-htmlhelp             1.0.2    
sphinxcontrib-jsmath               1.0.1    
sphinxcontrib-qthelp               1.0.2    
sphinxcontrib-serializinghtml      1.1.3    
sphinxcontrib-websupport           1.1.2    
spyder                             3.3.6    
spyder-kernels                     0.5.2    
SQLAlchemy                         1.3.9    
statsmodels                        0.10.1   
sympy                              1.4      
tables                             3.5.2    
tblib                              1.4.0    
terminado                          0.8.2    
testpath                           0.4.2    
toolz                              0.10.0   
tornado                            6.0.3    
tqdm                               4.36.1   
traitlets                          4.3.3    
unicodecsv                         0.14.1   
urllib3                            1.24.2   
wcwidth                            0.1.7    
webencodings                       0.5.1    
Werkzeug                           0.16.0   
wheel                              0.33.6   
widgetsnbextension                 3.5.1    
wrapt                              1.11.2   
wurlitzer                          1.0.3    
xlrd                               1.2.0    
XlsxWriter                         1.2.1    
xlwings                            0.15.10  
xlwt                               1.3.0    
zict                               1.0.0    
zipp                               0.6.0
```

</div></details>

## Pipenvのインストール
Homebrewを用いてインストールを行います。以下のコマンドを実行します。pipenv version 2018.11.26がインストールされました。

```bash
brew install pipenv
```

.bash_profileまたｈ.bashrcに以下を登録します。(筆者は.bash_profileに登録)

```
eval "$(pipenv --completion)"
```

有効化します。

```bash
source ~/.bash_profile
```

## テストプロジェクトを作成し実行
テストプロジェクトディレクトリを作成し、pipenvを実際に使ってみます。

```bash
mkdir test_python
cd test_python
```

テストプロジェクトでPython3.7を有効化します。

```bash
pipenv --python 3.7
```

<details><summary>実行結果</summary><div>

```bash
$ pipenv --python 3.7
Creating a virtualenv for this project…
Pipfile: /Users/user/developing/test_python/Pipfile
Using /usr/local/bin/python3 (3.7.7) to create virtualenv…
⠋ Creating virtual environment...created virtual environment CPython3.7.7.final.0-64 in 1370ms
  creator CPython3Posix(dest=/Users/user/.local/share/virtualenvs/test_python-YWoj8_wO, clear=False, global=False)
  seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, via=copy, app_data_dir=/Users/user/Library/Application Support/virtualenv/seed-app-data/v1)
  activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

✔ Successfully created virtual environment! 
Virtualenv location: /Users/user/.local/share/virtualenvs/test_python-YWoj8_wO
Creating a Pipfile for this project…
```

```bash
$ ls
Pipfile
```

</div></details>

## Pythonインタープリタの起動(Python3の有効化)
まずこのままコンソールに`python`と打ち込みインタープリタを起動します。OS標準のPythonが起動しました。AnacondaはインストールするとPathを書き換えてしまい、それがトラブルの原因となる場合が有りましたが、Pipenvにはそういった<font color='RED'>破壊的な変更</font>を起こす仕様は無い様です。

```bash
$ python
Python 2.7.16 (default, Jan 27 2020, 04:46:15) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

PipenvでPython3.7を有効化します。まず、以下のコマンドを実行します。

```bash
pipenv install
```

<details><summary>実行結果</summary><div>

```bash
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (a65489)!
Installing dependencies from Pipfile.lock (a65489)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
```

</div></details>

続けて以下のコマンドを実行します。

```bash
pipenv shell
```

<details><summary>実行結果</summary><div>

```bash
$ pipenv shell
Launching subshell in virtual environment…
 . /Users/user/.local/share/virtualenvs/test_python-YWoj8_wO/bin/activate
user:~/developing/test_python $  . /Users/user/.local/share/virtualenvs/test_python-YWoj8_wO/bin/activate
```

コンソールの表示が変化しました。

```bash
(test_python) user:~/developing/test_python $
```

</div></details>

もう一度コンソールに`python`コマンドを入力し、実行します。無事Python3.7.7が有効になりました。

```bash
$ python
Python 3.7.7 (default, Mar 10 2020, 15:43:03) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

```bash
$ ls
Pipfile       Pipfile.lock
```

```bash
$ pipenv --venv 
/Users/user/.local/share/virtualenvs/test_python-YWoj8_wO
```

仮想環境から抜けます。

```bash
exit
```

今回テストで作成した仮想環境を削除します。

```bash
pipenv --rm
```

仮想環境のリストを見てみます。削除されていることが分かります。

```bash
$ pipenv --venv 
No virtualenv has been created for this project yet!
Aborted!
```

これで開発プロジェクト毎にPythonのバージョンの切り分け、パッケージ管理・共有が円滑に実施出来る様になりました。本記事での達成目標は無事達成されました。:dancer: :dancers: 

# 参考情報
## 2021/11/15追記: completionの有効化方法が変更
最新版のPipenvからcompletionの有効化方法(.bash_profile/.bashrcへの記載内容)が変更されています。ただ、Homebrewでアップデートするとcompletionが正常に動作しなくなります。動作させるにはcompletionのソースに手を加える必要が現状有ります。詳細は以下の記事にまとめました。

https://qiita.com/y-vectorfield/items/36120f1493634561ff42

## 2022/10/18追記: pyenv installが失敗する時の参考情報
pyenv installがエラー終了する場合の一例です．

https://qiita.com/y-vectorfield/items/d1dfce67cf111c3bfc5a

## 2022/10/18追記: pyenvを利用する時の前準備

https://qiita.com/y-vectorfield/items/10d7df02954aab199232#%E5%BF%85%E8%A6%81%E3%81%AA%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E8%BF%BD%E5%8A%A0


# Homebrewのエイリアス登録(2022/10/22更新)
環境変数PATHでHomebrewが管理しているPATH以外のPATHにconfigファイル等が格納されている場合、`brew doctor`コマンド実行時に警告が出ます。警告を出さない様に、.bashrcに以下のaliasを登録します。

```bash
alias brew="PATH=/opt/homebrew/bin brew"
```

* 登録前

```bash
$ brew doctor 
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: "config" scripts exist outside your system or Homebrew directories.
`./configure` scripts often look for *-config scripts to determine if
software packages are installed, and which additional flags to use when
compiling and linking.

Having additional scripts in your path can confuse software installed via
Homebrew if the config script overrides a system or Homebrew-provided
script of the same name. We found the following "config" scripts:
  /Users/user/.pyenv/shims/icu-config
  /Users/user/.pyenv/shims/krb5-config
  /Users/user/.pyenv/shims/libpng16-config
  /Users/user/.pyenv/shims/python3.7-config
  /Users/user/.pyenv/shims/python3.7m-config
  /Users/user/.pyenv/shims/python-config
  /Users/user/.pyenv/shims/python3-config
  /Users/user/.pyenv/shims/ncursesw6-config
  /Users/user/.pyenv/shims/pcre-config
```

* 登録後

```bash
$ brew doctor 
Your system is ready to brew.
```

これで全ての懸案が片付きました。

# まとめ
MacのPython開発環境の見直しを行いました。まずPyflowを試して没となり、Pipenv + pyenvコンビが筆者の環境では最適だと分かりセットアップを実施しました。今後はGitでパッケージ一覧をプロジェクト単位に管理出来る様になっただけで無く、システムにデフォルトでインストールされているPythonに影響を与えること無くAnacondaの環境も維持することが実現しました。PyflowはOSS有る有るですが、Macで使用するにはあまりにも貧弱(Python3.7以外は手動インストール)でしたので今回は没にしましたが、今後の発展を監視しつつ、Rustを勉強して開発に貢献してみるのも悪くない(そもそも筆者に出来るのかは疑問)と思いました。

# Reference
* [2020 年の Python パッケージ管理ベストプラクティス](https://qiita.com/sk217/items/43c994640f4843a18dbe)
* [pyenv をインストールしてると brew doctor で出る Warning を消す方法](https://qiita.com/takuya0301/items/695f42f6904e979f0152)


[^conda]: https://www.anaconda.com/
[^brew]: https://brew.sh/index_ja