cygwinでpyenvを使う

以前, [Anacondaをcygwinで使うための記事](https://qiita.com/birdwatcher/items/0265098e5f8c1e0f8aa4)を書きましたが, pyenvに乗り換えたので, cygwinでpyenvを使う方法を紹介します. 
前回のAnacondaのときの知識をフル活用して, 自己流で設定を完了させました. 
(Anacondaはアンインストール済みで, この記事の初期段階で入っているpythonはcygwinのpythonだけです. )

※pyenv-win==2.64.11で確認したもので、最新バージョンだとまた変わっており、動かなくなってました(2022/12/30)

# 導入手順
## pyenvインストール
cygwinターミナルから, windows用にカスタマイズされた`pyenv-win`を`pip3`でインストールします. 
```bash
pip3 install pyenv-win --target $HOME/.pyenv
```
`--target`には, pyenv関連のファイルを置きたい場所を設定します. 

chmodで実行権限を付与します. 
```bash
chmod 744 $HOME/.pyenv/pyenv-win/bin/pyenv*
```

cygwinの`.bashrc`に以下を追記します. 
```bash
PYENV=$HOME/.pyenv/pyenv-win
export PATH=$PYENV/bin:$PYENV/shims:$PATH
```

## winptyインストール
上記の設定のままでは, スクリプト実行はできるが, インタラクティブに弱く, cygwinから`python.bat`を呼んでも反応が返ってこない. (`python.bat`は上で追記したパスの`$PYENV/shims`の中にある)
Anacondaのとき同様, winptyで実行コマンドをラップしてあげるとよい. 

https://github.com/rprichard/winpty からzipをダウンロード後, 展開して, ./configureしてmake.
build内のwinpty.exeを適当なところに移動. (コンパイルには[c++環境](https://qiita.com/birdwatcher/items/891ebe41a5e80d080171)が必要)

cygwinの`.bashrc`に以下を追記して, `pyenv`コマンドをwinptyでラップします. 
また, 各pythonコマンドはpyenv execで包んであげます. 
```bash
alias 'pyenv'="/cygdrive/c/winpty-master/build/winpty.exe $PYENV/bin/pyenv.bat"
alias 'python'='pyenv exec python'
alias 'ipython'='pyenv exec ipython'
alias 'pip'='pyenv exec pip'
alias 'jupyter'='pyenv exec jupyter'
```

`pyenv exec python`のような表記はもともと`$PYENV/shims/python(.bat)`に記載されていたものですが, わざわざshims内のスクリプトを経由する意味は無いため, aliasで直接包んでやります. 

## pyenvスクリプトの編集
`$PYENV/bin/pyenv`ファイルを以下のように書き換えます. 

```bash:pyenv
#!/bin/sh
# before:
# cmd //c call "$(dirname "$0")/pyenv.bat" "$@"
# after:
cmd /c call "`cygpath -d $(dirname "$0")`/pyenv.bat" $*
```

この変更をしないと, シェルスクリプト内でpythonを呼んだときに
>'ygdrive' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

となってしまいます. 
## pyenvを設定する
```bash
pyenv versions
```
を実行すると最初は何も入ってません. 
```bash
pyenv install --list
```
でインストールできるパッケージを確認し, 好きなバージョンをインストールします. 

```bash
pyenv install 3.9.6
pyenv rehash
```
この状態では, 
>$ pyenv versions
3.9.6

となります. 
この状態ではglobal設定がされていないため, 
```bash
pyenv global 3.9.6
```
を実行してglobalなバージョンを指定してからは, 
>$ pyenv versions
\* 3.9.6 (set by C:\\Users\\(ユーザ名)\\.pyenv\\pyenv-win\\version)

となり, 正しく設定されました. 

## python/pip/jupyterを使ってみる
winptyでラップしたことで, 正しくインタラクティブに動かせました. 
(`python hoge.py`ももちろん動きます. )
>$ python
Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
\>\>\> 1+1
2
\>\>\>

pipも使ってみます. 

>$ pip install tqdm
Collecting tqdm
  Downloading tqdm-4.64.0-py2.py3-none-any.whl (78 kB)
     |████████████████████████████████| 78 kB 581 kB/s
Requirement already satisfied: colorama in c:\\users\\(ユーザ名)\\.pyenv\\pyenv-win\\versions\\3.9.6\\lib\\site-packages (from tqdm) (0.4.4)
Installing collected packages: tqdm
Successfully installed tqdm-4.64.0
WARNING: You are using pip version 21.1.3; however, version 22.0.4 is available.
You should consider upgrading via the 'c:\\users\\(ユーザ名)\\.pyenv\\pyenv-win\\versions\\3.9.6\\python.exe -m pip install --upgrade pip' command.

無事動きました. 

jupyterも問題なく動かせました. 
>$ jupyter notebook
[I 14:26:20.464 NotebookApp] ローカルディレクトリからノートブックをサーブ: C:\Users\(ユーザ名)
[I 14:26:20.464 NotebookApp] Jupyter Notebook 6.4.10 is running at:
[I 14:26:20.464 NotebookApp] http://localhost:8888/?token=(トークン)
[I 14:26:20.464 NotebookApp]  or http://127.0.0.1:8888/?token=(トークン)
[I 14:26:20.464 NotebookApp] サーバを停止し全てのカーネルをシャットダウンするには Control-C を使って下さい(確認をスキップするには2回)。
[C 14:26:20.533 NotebookApp]

# まとめ
winptyを使うとcygwin上でpyenv使える.