pyenv-virtualenvとcondaを共存させる

# 要約

色々な意見が飛び交っているが，condaのバージョンを古くしておけばうまく共存できる．
[このissue](https://github.com/pyenv/pyenv-virtualenv/issues/178)を読めばなんとなく解決する．

# はじめに

[pyenv](https://github.com/pyenv/pyenv)はとっても便利なPythonバージョン管理ツールなので，新しいマシンでPythonを使うときにはまずpyenvを入れたくなる．

pyenvは単体でも悪くないが，自分が本当にやりたいことは，例えば「とりあえずこのプログラムのために環境を構築してみて，何かあったときにはちまちま原因を探るのではなくとりあえず環境ごとぶっ飛ばす」とかなので，同じバージョンのPythonを複数の環境にインストールできてほしい．
そこで，[pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv)プラグインを用いて，pyenvのインターフェースでPythonの仮想環境を作れるようにする．venvとかvirtualenvとか，[似たような名前の別人がたくさんいるので混同しないでほしい](https://qiita.com/maskedw/items/aaa2fd7abfd493cf2820)．

ところが，世の中にはpyenv-virtualenvではなく，[パッケージマネージャとしてcondaを強く推奨してくる輩](http://pytorch.org/ "PyTorch")がいる．（pyenv-virtualenvはパッケージマネージャではないが，condaは強気なので[バージョン管理も引き受けようとする](https://qiita.com/y__sama/items/5b62d31cb7e6ed50f02c#conda%E3%81%A8%E3%81%AF)）．
condaも悪くないのだが，```pyenv local foo-env```などとできるpyenvのインターフェースに慣れてしまうと，いちいち```activate```するのはダサく思えてしまう．

同じ考えの人はたくさんいるので，世の中には多くのpyenv・pyenv-virtualenv・conda共存推奨記事がある[[1]](https://qiita.com/y4m3/items/19246624d3ba4d299313)[[2]](https://qiita.com/y__sama/items/f732bb7bec2bff355b69)[[3]](http://karaage.hatenadiary.jp/entry/2016/04/04/073000)．
しかし，試してみるとどうもうまくいかない．

```bash:mac
$ pyenv --version
pyenv 1.2.2
$ pyenv virtualenv --version
pyenv-virtualenv 1.1.1 (virtualenv 15.1.0)

# 書いてあるとおりにインストールしてみる
$ pyenv install miniconda3-latest
...
$ pyenv shell miniconda3-latest
$ conda create python=3.6.4 -n test
...

# うまくできたか確かめる
$ pyenv virtualenvs
* miniconda3-latest (created from /path-to-your-.pyenv/versions/miniconda3-latest)
# ↑ここでminiconda3-latest/envs/test が表示されてほしい
$ pyenv shell test
pyenv: version 'test' not installed
$ pyenv shell miniconda3-latest/envs/test
# 問題なく実行できるように見えるが
$ echo $VIRTUAL_ENV
# virtualenvに認識されていない
$ conda --version
pyenv: conda: command not found
...
# ダメっぽい
```

```bash:ubuntu
$ pyenv --version
pyenv 1.2.1-7-gf114557
$ pyenv virtualenv --version
pyenv-virtualenv 1.1.1 (virtualenv unknown)

$ pyenv install miniconda3-latest
...
$ pyenv shell miniconda3-latest
$ conda create python=3.6.4 -n test
...

$ pyenv virtualenvs
* miniconda3-latest (created from /path-to-your-.pyenv/versions/miniconda3-latest)
$ pyenv shell test
pyenv: version 'test' not installed
$ pyenv shell miniconda3-latest/envs/test
$ echo $VIRTUAL_ENV
$ conda --version
pyenv: conda: command not found
...
# 同じくダメっぽい
```

納得行かない．私はpyenv-virtualenvと共に生きていきたい．でもcondaでしか入らないパッケージも使いたい．

# 解決方法

色々悩んだが，灯台下暗し，普通に公式のissueがあった．
https://github.com/pyenv/pyenv-virtualenv/issues/178

## 最新のcondaではなく，古いcondaを入れる

condaのアップデートとpyenv-virtualenvの対応はいたちごっこなので，古いcondaを入れておけばpyenv-virtualenvが変な挙動をすることはない．
Python自体はpyenvで最新のものを入れるので，condaが古くて困ることは特にない．

私はminiconda3-3.9.1を使っているが，今のところはうまく動いている．

```bash
pyenv install miniconda3-3.9.1
```

## 環境の作成

環境を作る時は，

1. ```pyenv install```で（古い）condaをインストール
2. ```pyenv shell```でインストールしたcondaに環境を移す
3. ```conda create -n env-name python=3.6.4```で新しい環境を作る

3.でpythonのバージョンを指定しないとpyenv-virtualenvが認識してくれないので注意．

## 環境の切り替え

切り替えはpyenv-virtualenvですべて賄うことができる．
```pyenv shell miniconda3-3.9.1/envs/env-name```というように，condaからのパスを指定する．補完が効くので見た目ほどタイプ量はグロくない（ダサいけど）．

## 環境の破棄

環境を破棄する時は，単に```pyenv uninstall miniconda3-3.9.1/envs/env-name```とすればよい．conda側からなにかする必要はない．



# 結果

```bash:mac
$ pyenv --version
pyenv 1.2.2
$ pyenv virtualenv --version
pyenv-virtualenv 1.1.1 (virtualenv 15.1.0)

# インストールしてみる
$ pyenv install miniconda3-3.9.1
...
$ pyenv shell miniconda3-3.9.1
$ conda create python=3.6.4 -n test2
...

# うまくできたか確かめる
$ pyenv virtualenvs
  miniconda3-latest (created from /path-to-your-.pyenv/versions/miniconda3-latest)
* miniconda3-3.9.1 (created from /path-to-your-.pyenv/versions/miniconda3-3.9.1)
  miniconda3-3.9.1/envs/test2 (created from /path-to-your-.pyenv/versions/miniconda3-3.9.1/envs/test2)
$ pyenv shell miniconda3-3.9.1/envs/test2
$ echo $VIRTUAL_ENV
/path-to-your-.pyenv/versions/miniconda3-3.9.1/envs/test2
# きちんと認識されている
$ conda --version
conda 4.3.30
# 若干古いけど仕方ない

# きちんと環境を分けられているかテスト
$ pyenv shell miniconda3-3.9.1/envs/test2
$ python -c "import tqdm"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'tqdm'
# まだインストールしてないのでエラー
$ conda install tqdm
$ python -c "import tqdm"
# エラーは出ない
$ pyenv shell miniconda3-3.9.1
$ python -c "import tqdm"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'tqdm'
# 別の環境ではちゃんと未インストール状態のままになっている
```

# さいごに

issueにもある通り，pyenv-virtualenvの人たち（というよりpyenvの人たち）は日々頑張ってくれているので，pyenvとpyenv-virtualenvを更新すれば最新のcondaに対してもpyenvがうまく動くかもしれない．
ただ，condaの新しいバージョンが出たときにまた動かなくなる可能性は大いに考えられるので，とりあえずconda-latestをインストールしようとするのは危険かもしれないよ，という話でした．

「pyenv-virtualenvをやめろ」以外の任意のマサカリを歓迎します．